diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index f455d528a98..9aa96b58350 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -12,7 +12,7 @@ blocks: - name: Mock UI Tests dependencies: [] execution_time_limit: - minutes: 30 + minutes: 45 task: secrets: - name: flowcrypt-browser-ci-secrets diff --git a/extension/chrome/dev/ci_pgp_host_page.htm b/extension/chrome/dev/ci_pgp_host_page.htm deleted file mode 100644 index d5cde5101a5..00000000000 --- a/extension/chrome/dev/ci_pgp_host_page.htm +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/extension/chrome/dev/ci_pgp_host_page.ts b/extension/chrome/dev/ci_pgp_host_page.ts deleted file mode 100644 index 3f4c2304062..00000000000 --- a/extension/chrome/dev/ci_pgp_host_page.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ - -'use strict'; - -import { BrowserMsg } from '../../js/common/browser/browser-msg.js'; -import { Catch } from '../../js/common/platform/catch.js'; -import { Xss } from '../../js/common/platform/xss.js'; -import { Env } from '../../js/common/browser/env.js'; - -Catch.try(async () => { - const tabId = await BrowserMsg.requiredTabId(); - - // BrowserMsg.addPgpListeners(); // todo - re-allow when https://github.com/FlowCrypt/flowcrypt-browser/issues/2560 fixed - BrowserMsg.listen(tabId); - - let src = Env.getBaseUrl(); - src += `/chrome/elements/pgp_block.htm${location.search}`; - src += `&parentTabId=${encodeURIComponent(tabId)}`; - $('body').append(``); // xss-escaped - $('body').attr('data-test-view-state', 'loaded'); -})(); diff --git a/extension/chrome/dev/export.ts b/extension/chrome/dev/export.ts index 5f25164f562..a8f2272c68c 100644 --- a/extension/chrome/dev/export.ts +++ b/extension/chrome/dev/export.ts @@ -87,7 +87,7 @@ Catch.try(async () => { const fetchableAttachments: Attachment[] = []; const skippedAttachments: Attachment[] = []; for (const msg of messages) { - for (const attachment of GmailParser.findAttachments(msg)) { + for (const attachment of GmailParser.findAttachments(msg, msg.id)) { if (attachment.length > 1024 * 1024 * 7) { // over 7 mb - attachment too big skippedAttachments.push( @@ -102,7 +102,7 @@ Catch.try(async () => { } } } - await gmail.fetchAttachments(fetchableAttachments, percent => print(`Percent attachments done: ${percent}`)); + await gmail.fetchAttachmentsMissingData(fetchableAttachments, percent => print(`Percent attachments done: ${percent}`)); const attachments: { [id: string]: { data: string; size: number } } = {}; for (const attachment of fetchableAttachments.concat(skippedAttachments)) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion diff --git a/extension/chrome/elements/attachment.ts b/extension/chrome/elements/attachment.ts index 33e2342a4da..b1891a43a82 100644 --- a/extension/chrome/elements/attachment.ts +++ b/extension/chrome/elements/attachment.ts @@ -8,7 +8,7 @@ import { PromiseCancellation, Str, Url } from '../../js/common/core/common.js'; import { Api } from '../../js/common/api/shared/api.js'; import { ApiErr } from '../../js/common/api/shared/api-error.js'; import { Assert } from '../../js/common/assert.js'; -import { Attachment } from '../../js/common/core/attachment.js'; +import { Attachment, AttachmentId } from '../../js/common/core/attachment.js'; import { Browser } from '../../js/common/browser/browser.js'; import { Catch } from '../../js/common/platform/catch.js'; import { Gmail } from '../../js/common/api/email-provider/gmail/gmail.js'; @@ -32,10 +32,8 @@ export class AttachmentDownloadView extends View { protected readonly isEncrypted: boolean; protected readonly errorDetailsOpened: boolean; protected readonly type: string | undefined; - protected readonly msgId: string | undefined; - protected readonly id: string | undefined; protected readonly name: string | undefined; - protected readonly url: string | undefined; + protected readonly attachmentId: AttachmentId; protected readonly gmail: Gmail; protected attachment!: Attachment; protected ppChangedPromiseCancellation: PromiseCancellation = { cancel: false }; @@ -73,11 +71,17 @@ export class AttachmentDownloadView extends View { this.errorDetailsOpened = uncheckedUrlParams.errorDetailsOpened === true; this.size = uncheckedUrlParams.size ? parseInt(String(uncheckedUrlParams.size)) : undefined; this.type = Assert.urlParamRequire.optionalString(uncheckedUrlParams, 'type'); - this.msgId = Assert.urlParamRequire.optionalString(uncheckedUrlParams, 'msgId'); - this.id = Assert.urlParamRequire.optionalString(uncheckedUrlParams, 'attachmentId'); this.name = Assert.urlParamRequire.optionalString(uncheckedUrlParams, 'name'); // url contains either actual url of remote content or objectUrl for direct content, either way needs to be downloaded - this.url = Assert.urlParamRequire.optionalString(uncheckedUrlParams, 'url'); + const url = Assert.urlParamRequire.optionalString(uncheckedUrlParams, 'url'); + if (url) { + this.attachmentId = { url }; + } else { + this.attachmentId = { + msgId: Assert.urlParamRequire.string(uncheckedUrlParams, 'msgId'), + id: Assert.urlParamRequire.string(uncheckedUrlParams, 'attachmentId'), + }; + } this.gmail = new Gmail(this.acctEmail); } @@ -91,11 +95,9 @@ export class AttachmentDownloadView extends View { this.fesUrl = storage.fesUrl; try { this.attachment = new Attachment({ + ...this.attachmentId, name: this.origNameBasedOnFilename, type: this.type, - msgId: this.msgId, - id: this.id, - url: this.url, }); } catch (e) { Catch.reportErr(e); @@ -107,9 +109,9 @@ export class AttachmentDownloadView extends View { this.renderHeader(); $('#name').attr('title', this.name || ''); $('img#file-format').attr('src', this.getFileIconSrc()); - if (!this.size && this.url) { + if (!this.size && 'url' in this.attachmentId) { // download url of a file that has an unknown size - this.getUrlFileSize(this.url) + this.getUrlFileSize(this.attachmentId.url) .then(fileSize => { if (typeof fileSize !== 'undefined') { this.size = fileSize; @@ -162,7 +164,7 @@ export class AttachmentDownloadView extends View { this.attachment.setData(await Api.download(this.attachment.url, this.renderProgress)); } else if (this.attachment.id && this.attachment.msgId) { // gmail attId - const { data } = await this.gmail.attachmentGet(this.attachment.msgId, this.attachment.id, this.renderProgress); + const { data } = await this.gmail.attachmentGet(this.attachment.msgId, this.attachment.id, { download: this.renderProgress }); this.attachment.setData(data); } else { throw new Error('File is missing both id and url - this should be fixed'); @@ -246,6 +248,7 @@ export class AttachmentDownloadView extends View { private processAsPublicKeyAndHideAttachmentIfAppropriate = async () => { // todo: we should call this detection in the main `core/Attachment.treatAs` (e.g. in the context of GmailElementReplacer and InboxActiveThreadModule) + // and we'll also be able to minimize the pgp_pubkey block if isOutgoing // should be possible after #4906 is done if (((this.attachment.msgId && this.attachment.id) || this.attachment.url) && this.attachment.isPublicKey()) { // this is encrypted public key - download && decrypt & parse & render diff --git a/extension/chrome/elements/attachment_preview.ts b/extension/chrome/elements/attachment_preview.ts index af687abbfff..446e61d7713 100644 --- a/extension/chrome/elements/attachment_preview.ts +++ b/extension/chrome/elements/attachment_preview.ts @@ -36,11 +36,9 @@ View.run( try { Xss.sanitizeRender(this.attachmentPreviewContainer, `${Ui.spinner('green', 'large_spinner')}`); this.attachment = new Attachment({ + ...this.attachmentId, name: this.origNameBasedOnFilename, type: this.type, - msgId: this.msgId, - id: this.id, - url: this.url, }); await this.downloadDataIfNeeded(); const result = this.isEncrypted ? await this.decrypt() : this.attachment.getData(); diff --git a/extension/chrome/elements/backup.htm b/extension/chrome/elements/backup.htm index 75335266130..3e3f1820c59 100644 --- a/extension/chrome/elements/backup.htm +++ b/extension/chrome/elements/backup.htm @@ -21,7 +21,7 @@
Key Fingerprint:
- +
diff --git a/extension/chrome/elements/compose-modules/compose-draft-module.ts b/extension/chrome/elements/compose-modules/compose-draft-module.ts index 3bf14f7cef8..e10cc81b481 100644 --- a/extension/chrome/elements/compose-modules/compose-draft-module.ts +++ b/extension/chrome/elements/compose-modules/compose-draft-module.ts @@ -12,7 +12,7 @@ import { Ui } from '../../../js/common/browser/ui.js'; import { Buf } from '../../../js/common/core/buf.js'; import { Str, Url } from '../../../js/common/core/common.js'; import { DecryptErrTypes, MsgUtil } from '../../../js/common/core/crypto/pgp/msg-util.js'; -import { Mime, MimeContent, MimeProccesedMsg } from '../../../js/common/core/mime.js'; +import { Mime, MimeContentWithHeaders, MimeProccesedMsg } from '../../../js/common/core/mime.js'; import { MsgBlockParser } from '../../../js/common/core/msg-block-parser.js'; import { Catch } from '../../../js/common/platform/catch.js'; import { GlobalStore } from '../../../js/common/platform/store/global-store.js'; @@ -298,7 +298,7 @@ export class ComposeDraftModule extends ViewModule { } }; - private fillAndRenderDraftHeaders = async (decoded: MimeContent) => { + private fillAndRenderDraftHeaders = async (decoded: MimeContentWithHeaders) => { this.view.recipientsModule.addRecipientsAndShowPreview({ to: decoded.to, cc: decoded.cc, bcc: decoded.bcc }); if (decoded.from) { this.view.S.now('input_from').val(decoded.from); diff --git a/extension/chrome/elements/compose-modules/compose-quote-module.ts b/extension/chrome/elements/compose-modules/compose-quote-module.ts index d4387bd776a..75bb07d9259 100644 --- a/extension/chrome/elements/compose-modules/compose-quote-module.ts +++ b/extension/chrome/elements/compose-modules/compose-quote-module.ts @@ -3,7 +3,7 @@ 'use strict'; import { Bm, BrowserMsg } from '../../../js/common/browser/browser-msg.js'; -import { FormatError, MsgUtil, DecryptErrTypes } from '../../../js/common/core/crypto/pgp/msg-util.js'; +import { MsgUtil, DecryptErrTypes } from '../../../js/common/core/crypto/pgp/msg-util.js'; import { ApiErr } from '../../../js/common/api/shared/api-error.js'; import { Buf } from '../../../js/common/core/buf.js'; import { Catch } from '../../../js/common/platform/catch.js'; @@ -123,29 +123,31 @@ export class ComposeQuoteModule extends ViewModule { decryptedAndFormatedContent.push(Xss.htmlUnescape(htmlParsed)); } else if (block.type === 'plainHtml') { decryptedAndFormatedContent.push(Xss.htmlUnescape(Xss.htmlSanitizeAndStripAllTags(stringContent, '\n', false))); - } else if (['encryptedAttachment', 'decryptedAttachment', 'plainAttachment'].includes(block.type)) { - if (block.attachmentMeta?.data) { - let attachmentMeta: { content: Buf; filename?: string } | undefined; - if (block.type === 'encryptedAttachment') { - this.setQuoteLoaderProgress('decrypting...'); - const result = await MsgUtil.decryptMessage({ - kisWithPp: await KeyStore.getAllWithOptionalPassPhrase(this.view.acctEmail), - encryptedData: block.attachmentMeta.data, - verificationPubs: [], // todo: #4158 signature verification of attachments - }); - if (result.success) { - attachmentMeta = { content: result.content, filename: result.filename }; - } - } else { - attachmentMeta = { - content: Buf.fromUint8(block.attachmentMeta.data), - filename: block.attachmentMeta.name, - }; - } - if (attachmentMeta) { - const file = new File([attachmentMeta.content], attachmentMeta.filename || ''); - decryptedFiles.push(file); + } else if ( + block.attachmentMeta && + 'data' in block.attachmentMeta && + ['encryptedAttachment', 'decryptedAttachment', 'plainAttachment'].includes(block.type) + ) { + let attachmentMeta: { content: Buf; filename?: string } | undefined; + if (block.type === 'encryptedAttachment') { + this.setQuoteLoaderProgress('decrypting...'); + const result = await MsgUtil.decryptMessage({ + kisWithPp: await KeyStore.getAllWithOptionalPassPhrase(this.view.acctEmail), + encryptedData: block.attachmentMeta.data, + verificationPubs: [], // todo: #4158 signature verification of attachments + }); + if (result.success) { + attachmentMeta = { content: result.content, filename: result.filename }; } + } else { + attachmentMeta = { + content: Buf.fromUint8(block.attachmentMeta.data), + filename: block.attachmentMeta.name, + }; + } + if (attachmentMeta) { + const file = new File([attachmentMeta.content], attachmentMeta.filename || ''); + decryptedFiles.push(file); } } else { decryptedAndFormatedContent.push(stringContent); @@ -158,9 +160,7 @@ export class ComposeQuoteModule extends ViewModule { decryptedFiles, }; } catch (e) { - if (e instanceof FormatError) { - Xss.sanitizeAppend(this.view.S.cached('input_text'), `
\n
\n
\n${Xss.escape(e.data)}`); - } else if (ApiErr.isNetErr(e)) { + if (ApiErr.isNetErr(e)) { // todo: retry } else if (ApiErr.isAuthErr(e)) { BrowserMsg.send.notificationShowAuthPopupNeeded(this.view.parentTabId, { acctEmail: this.view.acctEmail }); diff --git a/extension/chrome/elements/pgp_block.htm b/extension/chrome/elements/pgp_block.htm index 74e185d396a..0a2cd5671e5 100644 --- a/extension/chrome/elements/pgp_block.htm +++ b/extension/chrome/elements/pgp_block.htm @@ -40,14 +40,6 @@ - - - - - - - - diff --git a/extension/chrome/elements/pgp_block.ts b/extension/chrome/elements/pgp_block.ts index 38174e27a23..79ed3dc844a 100644 --- a/extension/chrome/elements/pgp_block.ts +++ b/extension/chrome/elements/pgp_block.ts @@ -2,115 +2,122 @@ 'use strict'; -import { Str, Url } from '../../js/common/core/common.js'; +import { Url } from '../../js/common/core/common.js'; import { Assert } from '../../js/common/assert.js'; -import { Buf } from '../../js/common/core/buf.js'; -import { Gmail } from '../../js/common/api/email-provider/gmail/gmail.js'; -import { Lang } from '../../js/common/lang.js'; +import { RenderMessage, RenderMessageWithFrameId } from '../../js/common/render-message.js'; +import { Attachment } from '../../js/common/core/attachment.js'; +import { Xss } from '../../js/common/platform/xss.js'; import { PgpBlockViewAttachmentsModule } from './pgp_block_modules/pgp-block-attachmens-module.js'; -import { PgpBlockViewDecryptModule } from './pgp_block_modules/pgp-block-decrypt-module.js'; import { PgpBlockViewErrorModule } from './pgp_block_modules/pgp-block-error-module.js'; +import { PgpBlockViewPrintModule } from './pgp_block_modules/pgp-block-print-module.js'; import { PgpBlockViewQuoteModule } from './pgp_block_modules/pgp-block-quote-module.js'; import { PgpBlockViewRenderModule } from './pgp_block_modules/pgp-block-render-module.js'; -import { PgpBlockViewSignatureModule } from './pgp_block_modules/pgp-block-signature-module.js'; import { Ui } from '../../js/common/browser/ui.js'; import { View } from '../../js/common/view.js'; -import { PubLookup } from '../../js/common/api/pub-lookup.js'; -import { ClientConfiguration } from '../../js/common/client-configuration.js'; -import { AcctStore } from '../../js/common/platform/store/acct-store.js'; -import { ContactStore } from '../../js/common/platform/store/contact-store.js'; -import { KeyUtil } from '../../js/common/core/crypto/key.js'; +import { Bm } from '../../js/common/browser/browser-msg.js'; export class PgpBlockView extends View { - public readonly acctEmail: string; + public readonly acctEmail: string; // needed for attachment decryption, probably should be refactored out public readonly parentTabId: string; public readonly frameId: string; - public readonly isOutgoing: boolean; - public readonly senderEmail: string; - public readonly msgId: string | undefined; - public readonly encryptedMsgUrlParam: Buf | undefined; - public readonly signature?: { - // when parsedSignature is undefined, decryptModule will try to fetch the message - parsedSignature?: string; - }; - - public gmail: Gmail; - public clientConfiguration!: ClientConfiguration; - public pubLookup!: PubLookup; public readonly debug: boolean; public readonly attachmentsModule: PgpBlockViewAttachmentsModule; - public readonly signatureModule: PgpBlockViewSignatureModule; public readonly quoteModule: PgpBlockViewQuoteModule; public readonly errorModule: PgpBlockViewErrorModule; public readonly renderModule: PgpBlockViewRenderModule; - public readonly decryptModule: PgpBlockViewDecryptModule; - - public fesUrl?: string; + public readonly printModule = new PgpBlockViewPrintModule(); public constructor() { super(); Ui.event.protect(); - const uncheckedUrlParams = Url.parse(['acctEmail', 'frameId', 'message', 'parentTabId', 'msgId', 'isOutgoing', 'senderEmail', 'signature', 'debug']); + const uncheckedUrlParams = Url.parse(['frameId', 'parentTabId', 'debug', 'acctEmail']); this.acctEmail = Assert.urlParamRequire.string(uncheckedUrlParams, 'acctEmail'); this.parentTabId = Assert.urlParamRequire.string(uncheckedUrlParams, 'parentTabId'); this.frameId = Assert.urlParamRequire.string(uncheckedUrlParams, 'frameId'); - this.isOutgoing = uncheckedUrlParams.isOutgoing === true; this.debug = uncheckedUrlParams.debug === true; - const senderEmail = Assert.urlParamRequire.string(uncheckedUrlParams, 'senderEmail'); - this.senderEmail = Str.parseEmail(senderEmail).email || ''; - this.msgId = Assert.urlParamRequire.optionalString(uncheckedUrlParams, 'msgId'); - if (/\.\.|\\|\//.test(decodeURI(this.msgId || ''))) { - throw new Error('API path traversal forbidden'); - } - this.encryptedMsgUrlParam = uncheckedUrlParams.message ? Buf.fromUtfStr(Assert.urlParamRequire.string(uncheckedUrlParams, 'message')) : undefined; - if (uncheckedUrlParams.signature === true) { - this.signature = { parsedSignature: undefined }; // decryptModule will try to fetch the message - } else if (uncheckedUrlParams.signature) { - this.signature = { parsedSignature: String(uncheckedUrlParams.signature) }; - } - this.gmail = new Gmail(this.acctEmail); // modules this.attachmentsModule = new PgpBlockViewAttachmentsModule(this); - this.signatureModule = new PgpBlockViewSignatureModule(this); this.quoteModule = new PgpBlockViewQuoteModule(this); this.errorModule = new PgpBlockViewErrorModule(this); this.renderModule = new PgpBlockViewRenderModule(this); - this.decryptModule = new PgpBlockViewDecryptModule(this); + chrome.runtime.onMessage.addListener((message: Bm.Raw) => { + if (message.name === 'pgp_block_render') { + const msg = message.data.bm as RenderMessageWithFrameId; + if (msg.frameId === this.frameId) { + this.processMessage(msg); + return true; + } + } + return false; + }); + window.addEventListener('load', () => window.parent.postMessage({ readyToReceive: this.frameId }, '*')); } - public getExpectedSignerEmail = () => { - // We always attempt to verify all signatures as "signed by sender", with public keys of the sender. - // That way, signature spoofing attacks are prevented: if Joe manages to spoof a sending address - // of Jane (send an email from Jane address), then we expect Jane to be this signer: we look up - // keys recorded for Jane and the signature either succeeds or fails to verify. - // If it fails (that pubkey which Joe used is not recorded for Jane), it will show an error. - return this.senderEmail; - }; - public render = async () => { - const storage = await AcctStore.get(this.acctEmail, ['setup_done', 'fesUrl']); - this.fesUrl = storage.fesUrl; - this.clientConfiguration = await ClientConfiguration.newInstance(this.acctEmail); - this.pubLookup = new PubLookup(this.clientConfiguration); - await this.renderModule.initPrintView(); - if (storage.setup_done) { - const parsedPubs = (await ContactStore.getOneWithAllPubkeys(undefined, this.getExpectedSignerEmail()))?.sortedPubkeys ?? []; - // todo: we don't actually need parsed pubs here because we're going to pass them to the backgorund page - // maybe we can have a method in ContactStore to extract armored keys - const verificationPubs = parsedPubs.map(key => KeyUtil.armor(key.pubkey)); - await this.decryptModule.initialize(verificationPubs, false); - } else { - await this.errorModule.renderErr(Lang.pgpBlock.refreshWindow, this.encryptedMsgUrlParam ? this.encryptedMsgUrlParam.toUtfStr() : undefined); - } + // }; public setHandlers = () => { $('.pgp_print_button').on( 'click', - this.setHandler(() => this.renderModule.printPGPBlock()) + this.setHandler(() => this.printModule.printPGPBlock()) ); }; + + private processMessage = (data: RenderMessage) => { + // messages aren't merged when queueing, so the order is arbitrary + if (data?.renderEncryptionStatus) { + this.renderModule.renderEncryptionStatus(data.renderEncryptionStatus); + } + if (data?.renderVerificationInProgress) { + $('#pgp_signature').removeClass('green_label red_label').addClass('gray_label').text('verifying signature...'); + } + if (data?.renderSignatureStatus) { + this.renderModule.renderSignatureStatus(data.renderSignatureStatus); + } + if (data?.renderText) { + this.renderModule.renderText(data.renderText); + } + if (data?.resizePgpBlockFrame) { + this.renderModule.resizePgpBlockFrame(); + } + if (data?.separateQuotedContentAndRenderText) { + this.quoteModule.separateQuotedContentAndRenderText( + data.separateQuotedContentAndRenderText.decryptedContent, + data.separateQuotedContentAndRenderText.isHtml + ); + } + if (data?.setFrameColor) { + this.renderModule.setFrameColor(data.setFrameColor); + } + if (data?.renderInnerAttachments) { + const attachments = data.renderInnerAttachments.attachments.map(Attachment.fromTransferableAttachment); + this.attachmentsModule.renderInnerAttachments(attachments, data.renderInnerAttachments.isEncrypted); + } + if (data?.renderErr) { + this.errorModule.renderErr(data.renderErr.errBoxContent, data.renderErr.renderRawMsg, data.renderErr.errMsg); + } + if (data?.renderPassphraseNeeded) { + this.renderModule.renderPassphraseNeeded(data.renderPassphraseNeeded); + } + if (data?.clearErrorStatus) { + this.renderModule.clearErrorStatus(); + } + if (data?.done) { + Ui.setTestState('ready'); + } + if (data?.printMailInfo) { + Xss.sanitizeRender('.print_user_email', data.printMailInfo.userNameAndEmail); + this.printModule.printMailInfoHtml = data.printMailInfo.html; + } + if (data?.renderAsRegularContent) { + this.renderModule.renderAsRegularContent(data.renderAsRegularContent); + } + if (data?.renderSignatureOffline) { + this.renderModule.renderSignatureOffline(); + } + }; } View.run(PgpBlockView); diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-attachmens-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-attachmens-module.ts index bc71a93fc78..20ddc65c542 100644 --- a/extension/chrome/elements/pgp_block_modules/pgp-block-attachmens-module.ts +++ b/extension/chrome/elements/pgp_block_modules/pgp-block-attachmens-module.ts @@ -6,7 +6,7 @@ import { Api } from '../../../js/common/api/shared/api.js'; import { Attachment } from '../../../js/common/core/attachment.js'; import { Browser } from '../../../js/common/browser/browser.js'; import { BrowserMsg } from '../../../js/common/browser/browser-msg.js'; -import { PgpBlockView } from '../pgp_block'; +import { PgpBlockView } from '../pgp_block.js'; import { CommonHandlers, Ui } from '../../../js/common/browser/ui.js'; import { Xss } from '../../../js/common/platform/xss.js'; import { KeyStore } from '../../../js/common/platform/store/key-store.js'; @@ -67,12 +67,11 @@ export class PgpBlockViewAttachmentsModule { await this.decryptAndSaveAttachmentToDownloads(attachment); } else { Xss.sanitizePrepend($(target).find('.progress'), Ui.spinner('green')); - attachment.setData( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - await Api.download(attachment.url!, (perc, load, total) => - this.renderProgress($(target).find('.progress .percent'), perc, load, total || attachment.length) - ) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const buf = await Api.download(attachment.url!, (perc, load, total) => + this.renderProgress($(target).find('.progress .percent'), perc, load, total || attachment.length) ); + if (!attachment.hasData()) attachment.setData(buf); // there may be some sort of a race await Ui.delay(100); // give browser time to render $(target).find('.progress').text(''); await this.decryptAndSaveAttachmentToDownloads(attachment); diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-decrypt-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-decrypt-module.ts deleted file mode 100644 index 4242d392121..00000000000 --- a/extension/chrome/elements/pgp_block_modules/pgp-block-decrypt-module.ts +++ /dev/null @@ -1,213 +0,0 @@ -/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ - -'use strict'; - -import { BrowserMsg } from '../../../js/common/browser/browser-msg.js'; -import { Buf } from '../../../js/common/core/buf.js'; -import { DecryptErrTypes } from '../../../js/common/core/crypto/pgp/msg-util.js'; -import { GmailResponseFormat } from '../../../js/common/api/email-provider/gmail/gmail.js'; -import { Lang } from '../../../js/common/lang.js'; -import { Mime } from '../../../js/common/core/mime.js'; -import { PgpBlockView } from '../pgp_block.js'; -import { Ui } from '../../../js/common/browser/ui.js'; -import { Xss } from '../../../js/common/platform/xss.js'; -import { KeyStore } from '../../../js/common/platform/store/key-store.js'; -import { PassphraseStore } from '../../../js/common/platform/store/passphrase-store.js'; -import { MsgBlockParser } from '../../../js/common/core/msg-block-parser.js'; -import { Str } from '../../../js/common/core/common.js'; - -export class PgpBlockViewDecryptModule { - private msgFetchedFromApi: false | GmailResponseFormat = false; - private isPwdMsgBasedOnMsgSnippet: boolean | undefined; - - public constructor(private view: PgpBlockView) {} - - public initialize = async (verificationPubs: string[], forcePullMsgFromApi: boolean) => { - try { - if (this.view.signature && !this.view.signature.parsedSignature && this.view.msgId) { - this.view.renderModule.renderText('Loading signed message...'); - const { raw } = await this.view.gmail.msgGet(this.view.msgId, 'raw'); - this.msgFetchedFromApi = 'raw'; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const mimeMsg = Buf.fromBase64UrlStr(raw!); // used 'raw' above - const parsed = await Mime.decode(mimeMsg); - if (parsed && typeof parsed.rawSignedContent === 'string') { - const signatureAttachment = parsed.attachments.find(a => a.treatAs(parsed.attachments) === 'signature'); // todo: more than one signature candidate? - if (signatureAttachment) { - this.view.signature.parsedSignature = signatureAttachment.getData().toUtfStr(); - return await this.decryptAndRender(parsed.rawSignedContent, verificationPubs); - } - } - await this.view.errorModule.renderErr( - 'Error: could not properly parse signed message', - parsed.rawSignedContent || parsed.text || parsed.html || mimeMsg.toUtfStr(), - 'parse error' - ); - } else if (this.view.encryptedMsgUrlParam && !forcePullMsgFromApi) { - // ascii armored message supplied - this.view.renderModule.renderText(this.view.signature ? 'Verifying...' : 'Decrypting...'); - await this.decryptAndRender(this.view.encryptedMsgUrlParam, verificationPubs); - } else { - // need to fetch the inline signed + armored or encrypted +armored message block from gmail api - if (!this.view.msgId) { - Xss.sanitizeRender('#pgp_block', 'Missing msgId to fetch message in pgp_block. ' + Lang.general.contactIfHappensAgain(!!this.view.fesUrl)); - this.view.renderModule.resizePgpBlockFrame(); - } else { - const { armored, plaintext, subject } = await this.retrieveMessage(this.view.msgId); - this.view.renderModule.renderText('Decrypting...'); - if (plaintext) { - await this.view.renderModule.renderAsRegularContent(plaintext); - } else { - await this.decryptAndRender(armored, verificationPubs, subject); - } - } - } - } catch (e) { - await this.view.errorModule.handleInitializeErr(e); - } - }; - - public canAndShouldFetchFromApi = () => this.msgFetchedFromApi !== 'raw'; - - private retrieveMessage = async (msgId: string) => { - // todo: msgId === this.view.msgId - this.view.renderModule.renderText('Retrieving message...'); - const format: GmailResponseFormat = !this.msgFetchedFromApi ? 'full' : 'raw'; - const extractionResult = await this.view.gmail.extractArmoredBlock(msgId, format, progress => { - this.view.renderModule.renderText(`Retrieving message... ${progress}%`); - }); - this.isPwdMsgBasedOnMsgSnippet = extractionResult.isPwdMsg; - this.msgFetchedFromApi = format; - return extractionResult; - }; - - // #4342 - we have some corrupted cleartext signed message, find the correct message by the base64 signature characters - private getNeededCleartextMessage = (armoredInput: string, referenceData: string): string | undefined => { - const { blocks } = MsgBlockParser.detectBlocks(armoredInput); - const candidateBlocks = blocks.filter(b => b.type === 'signedMsg'); - if (candidateBlocks.length === 0) { - return undefined; - } - const initialSignatureMatch = referenceData.match(/\r?\n-----BEGIN PGP SIGNATURE-----(?=[\r\n]).*?\r?\n\r?\n(.*)\r?\n-----END PGP SIGNATURE-----$/s); - const initialSignature = initialSignatureMatch ? initialSignatureMatch[1].replace(/\s/g, '') : ' '; - for (const candidateBlock of candidateBlocks.map(b => (typeof b.content === 'string' ? b.content : b.content.toUtfStr()))) { - const match = candidateBlock.match( - /^-----BEGIN PGP SIGNED MESSAGE-----\r?\n.*?\r?\n-----BEGIN PGP SIGNATURE-----(?=[\r\n]).*?\r?\n\r?\n(.*?)\r?\n-----END PGP SIGNATURE-----\r?\n?$/s - ); - if (match && match[1].replace(/\s/g, '') === initialSignature) { - return match[0]; - } - } - return undefined; - }; - - private decryptAndRender = async (encryptedData: Uint8Array | string, verificationPubs: string[], plainSubject?: string): Promise => { - if (!this.view.signature?.parsedSignature) { - const kisWithPp = await KeyStore.getAllWithOptionalPassPhrase(this.view.acctEmail); - const decrypt = async (verificationPubs: string[]) => await BrowserMsg.send.bg.await.pgpMsgDecrypt({ kisWithPp, encryptedData, verificationPubs }); - const result = await decrypt(verificationPubs); - - if (typeof result === 'undefined') { - await this.view.errorModule.renderErr(Lang.general.restartBrowserAndTryAgain(!!this.view.fesUrl), undefined); - } else if (result.success) { - if (result.isCleartext && result.signature?.error === 'Signed digest did not match' && this.view.msgId && !this.msgFetchedFromApi) { - // only try to re-fetch 'full' - console.info(`re-fetching message ${this.view.msgId} from api because looks like bad formatting: full`); - const { armored } = await this.retrieveMessage(this.view.msgId); // todo: subject? - const fetchedContent = this.getNeededCleartextMessage(armored, Str.with(encryptedData)); - if (typeof fetchedContent !== 'undefined') { - return await this.decryptAndRender(fetchedContent, verificationPubs); - } - } - - if (!result.signature?.match) { - // try to find signature attachment in decrypted data - const decoded = await Mime.decode(result.content); - const signature = decoded.attachments.find(a => a.treatAs(decoded.attachments) === 'signature'); - - if (signature && decoded.rawSignedContent) { - const sigText = signature.getData().toUtfStr(); - const plaintext = decoded.rawSignedContent; - const verify = async (verificationPubs: string[]) => await BrowserMsg.send.bg.await.pgpMsgVerifyDetached({ plaintext, sigText, verificationPubs }); - result.signature = await verify(verificationPubs); - result.content = Buf.with(plaintext); - } - } - - await this.view.renderModule.decideDecryptedContentFormattingAndRender( - result.content, - result.isEncrypted, - result.signature, - verificationPubs, - async (verificationPubs: string[]) => { - const decryptResult = await decrypt(verificationPubs); - if (!decryptResult.success) { - return undefined; // note: this internal error results in a wrong "Not Signed" badge - } else { - return decryptResult.signature; - } - }, - plainSubject - ); - } else if (result.error.type === DecryptErrTypes.format) { - if (this.canAndShouldFetchFromApi()) { - console.info(`re-fetching message ${this.view.msgId} from api because looks like bad formatting: ${!this.msgFetchedFromApi ? 'full' : 'raw'}`); - await this.initialize(verificationPubs, true); - } else { - await this.view.errorModule.renderErr(Lang.pgpBlock.badFormat + '\n\n' + result.error.message, Str.with(encryptedData)); - } - } else if (result.longids.needPassphrase.length) { - const enterPp = `${Lang.pgpBlock.enterPassphrase} ${Lang.pgpBlock.toOpenMsg}`; - await this.view.errorModule.renderErr(enterPp, undefined, 'pass phrase needed'); - $('.enter_passphrase').on( - 'click', - this.view.setHandler(() => { - Ui.setTestState('waiting'); - BrowserMsg.send.passphraseDialog(this.view.parentTabId, { - type: 'message', - longids: result.longids.needPassphrase, - }); - }) - ); - await PassphraseStore.waitUntilPassphraseChanged(this.view.acctEmail, result.longids.needPassphrase); - this.view.renderModule.clearErrorStatus(); - this.view.renderModule.renderText('Decrypting...'); - await this.decryptAndRender(encryptedData, verificationPubs); - } else { - if (!result.longids.chosen && !(await KeyStore.get(this.view.acctEmail)).length) { - await this.view.errorModule.renderErr( - Lang.pgpBlock.notProperlySetUp + this.view.errorModule.btnHtml('FlowCrypt settings', 'green settings'), - undefined - ); - } else if (result.error.type === DecryptErrTypes.keyMismatch) { - await this.view.errorModule.handlePrivateKeyMismatch( - kisWithPp.map(ki => ki.public), - encryptedData, - this.isPwdMsgBasedOnMsgSnippet === true - ); - } else if (result.error.type === DecryptErrTypes.wrongPwd || result.error.type === DecryptErrTypes.usePassword) { - await this.view.errorModule.renderErr(Lang.pgpBlock.pwdMsgAskSenderUsePubkey, undefined); - } else if (result.error.type === DecryptErrTypes.noMdc) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - await this.view.errorModule.renderErr(result.error.message, result.content!.toUtfStr()); // missing mdc - only render the result after user confirmation - } else if (result.error) { - await this.view.errorModule.renderErr(`${Lang.pgpBlock.cantOpen}\n\n${result.error.type}: ${result.error.message}`, Str.with(encryptedData)); - } else { - // should generally not happen - await this.view.errorModule.renderErr( - Lang.pgpBlock.cantOpen + Lang.general.writeMeToFixIt(!!this.view.fesUrl) + '\n\nDiagnostic info: "' + JSON.stringify(result) + '"', - Str.with(encryptedData) - ); - } - } - } else { - // this.view.signature.parsedSignature is defined - // sometimes signatures come wrongly percent-encoded. Here we check for typical "=3Dabcd" at the end - const sigText = this.view.signature.parsedSignature.replace('\n=3D', '\n='); - const verify = async (verificationPubs: string[]) => - await BrowserMsg.send.bg.await.pgpMsgVerifyDetached({ plaintext: encryptedData, sigText, verificationPubs }); - const signatureResult = await verify(verificationPubs); - await this.view.renderModule.decideDecryptedContentFormattingAndRender(encryptedData, false, signatureResult, verificationPubs, verify); - } - }; -} diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-error-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-error-module.ts index 1aca3207883..c0075b4c06c 100644 --- a/extension/chrome/elements/pgp_block_modules/pgp-block-error-module.ts +++ b/extension/chrome/elements/pgp_block_modules/pgp-block-error-module.ts @@ -2,12 +2,8 @@ 'use strict'; -import { ApiErr } from '../../../js/common/api/shared/api-error.js'; import { Browser } from '../../../js/common/browser/browser.js'; import { BrowserMsg } from '../../../js/common/browser/browser-msg.js'; -import { Catch } from '../../../js/common/platform/catch.js'; -import { FormatError } from '../../../js/common/core/crypto/pgp/msg-util.js'; -import { Lang } from '../../../js/common/lang.js'; import { PgpBlockView } from '../pgp_block.js'; import { Ui } from '../../../js/common/browser/ui.js'; import { Xss } from '../../../js/common/platform/xss.js'; @@ -18,11 +14,11 @@ export class PgpBlockViewErrorModule { public constructor(private view: PgpBlockView) {} - public renderErr = async (errBoxContent: string, renderRawMsg: string | undefined, errMsg?: string) => { + public renderErr = (errBoxContent: string, renderRawMsg: string | undefined, errMsg?: string) => { this.view.renderModule.setFrameColor('red'); this.view.renderModule.renderErrorStatus(errMsg || 'decrypt error'); const showRawMsgPrompt = renderRawMsg ? 'show original message' : ''; - await this.view.renderModule.renderContent(`
${errBoxContent.replace(/\n/g, '
')}
${showRawMsgPrompt}`, true); + this.view.renderModule.renderContent(`
${errBoxContent.replace(/\n/g, '
')}
${showRawMsgPrompt}`, true); $('.action_show_raw_pgp_block').on( 'click', this.view.setHandler(async () => { @@ -57,54 +53,4 @@ export class PgpBlockViewErrorModule { console.log(`[${this.debugId}] ${msg}`); } }; - - public handlePrivateKeyMismatch = async (armoredPubs: string[], message: Uint8Array | string, isPwdMsg: boolean) => { - // todo - make it work for multiple stored keys - const msgDiagnosis = await BrowserMsg.send.bg.await.pgpMsgDiagnosePubkeys({ armoredPubs, message }); - if (msgDiagnosis.found_match) { - await this.renderErr(Lang.pgpBlock.cantOpen + Lang.pgpBlock.encryptedCorrectlyFileBug, undefined); - } else if (isPwdMsg) { - await this.renderErr(Lang.pgpBlock.pwdMsgOnlyReadableOnWeb + this.btnHtml('ask sender to re-send', 'gray2 short reply_pubkey_mismatch'), undefined); - } else { - const startText = - msgDiagnosis.receivers === 1 - ? Lang.pgpBlock.cantOpen + Lang.pgpBlock.singleSender + Lang.pgpBlock.askResend - : Lang.pgpBlock.yourKeyCantOpenImportIfHave; - await this.renderErr( - startText + - this.btnHtml('import missing key', 'gray2 settings_add_key') + - '   ' + - this.btnHtml('ask sender to update', 'gray2 short reply_pubkey_mismatch') + - '   ' + - this.btnHtml('settings', 'gray2 settings_keyserver'), - undefined - ); - } - }; - - public handleInitializeErr = async (e: unknown) => { - if (ApiErr.isNetErr(e)) { - await this.renderErr(`Could not load message due to network error. ${Ui.retryLink()}`, undefined); - } else if (ApiErr.isAuthErr(e)) { - BrowserMsg.send.notificationShowAuthPopupNeeded(this.view.parentTabId, { acctEmail: this.view.acctEmail }); - await this.renderErr(`Could not load message due to missing auth. ${Ui.retryLink()}`, undefined); - } else if (e instanceof FormatError) { - await this.renderErr( - Lang.pgpBlock.cantOpen + Lang.pgpBlock.badFormat + Lang.pgpBlock.details + e.message + ' ' + Lang.pgpBlock.dontKnowHowOpen(!!this.view.fesUrl), - e.data - ); - } else if (ApiErr.isInPrivateMode(e)) { - await this.renderErr( - `FlowCrypt does not work in a Firefox Private Window (or when Firefox Containers are used). Please try in a standard window.`, - undefined - ); - } else { - Catch.reportErr(e); - await this.renderErr(Xss.escape(String(e)), this.view.encryptedMsgUrlParam ? this.view.encryptedMsgUrlParam.toUtfStr() : undefined); - } - }; - - public btnHtml = (text: string, addClasses: string) => { - return ``; - }; } diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-print-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-print-module.ts new file mode 100644 index 00000000000..231cdab8e18 --- /dev/null +++ b/extension/chrome/elements/pgp_block_modules/pgp-block-print-module.ts @@ -0,0 +1,91 @@ +/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ + +'use strict'; + +import { Time } from '../../../js/common/browser/time.js'; +import { Catch } from '../../../js/common/platform/catch.js'; +import { Xss } from '../../../js/common/platform/xss.js'; + +export class PgpBlockViewPrintModule { + public printMailInfoHtml: string | undefined; + + public printPGPBlock = async () => { + if (!this.printMailInfoHtml) { + Catch.reportErr('printMailInfoHtml not prepared!'); + return; + } + const w = window.open(); + const html = ` + + + + + + + ${$('#print-header').html()} +
+ ${Xss.htmlSanitize(this.printMailInfoHtml)} +
+
+ ${Xss.htmlSanitize($('#pgp_block').html())} +
+ + + `; + w?.document.write(html); + // Give some time for above dom to load in print dialog + // https://stackoverflow.com/questions/31725373/google-chrome-not-showing-image-in-print-preview + await Time.sleep(250); + w?.window.print(); + w?.document.close(); + }; +} diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-quote-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-quote-module.ts index 03298dc4049..531458902d7 100644 --- a/extension/chrome/elements/pgp_block_modules/pgp-block-quote-module.ts +++ b/extension/chrome/elements/pgp_block_modules/pgp-block-quote-module.ts @@ -9,7 +9,7 @@ import { Xss } from '../../../js/common/platform/xss.js'; export class PgpBlockViewQuoteModule { public constructor(private view: PgpBlockView) {} - public separateQuotedContentAndRenderText = async (decryptedContent: string, isHtml: boolean) => { + public separateQuotedContentAndRenderText = (decryptedContent: string, isHtml: boolean) => { if (isHtml) { const message = $('
').html(Xss.htmlSanitizeKeepBasicTags(decryptedContent)); // xss-sanitized let htmlBlockQuoteExists = false; @@ -32,10 +32,10 @@ export class PgpBlockViewQuoteModule { message[0].removeChild(shouldBeQuoted[i]); quotedHtml += shouldBeQuoted[i].outerHTML; } - await this.view.renderModule.renderContent(message.html(), false); + this.view.renderModule.renderContent(message.html(), false); this.appendCollapsedQuotedContentButton(quotedHtml, true); } else { - await this.view.renderModule.renderContent(decryptedContent, false); + this.view.renderModule.renderContent(decryptedContent, false); } } else { const lines = decryptedContent.split(/\r?\n/); @@ -62,7 +62,7 @@ export class PgpBlockViewQuoteModule { // only got quoted part, no real text -> show everything as real text, without quoting lines.push(...linesQuotedPart.splice(0, linesQuotedPart.length)); } - await this.view.renderModule.renderContent(Str.escapeTextAsRenderableHtml(lines.join('\n')), false); + this.view.renderModule.renderContent(Str.escapeTextAsRenderableHtml(lines.join('\n')), false); if (linesQuotedPart.join('').trim()) { this.appendCollapsedQuotedContentButton(linesQuotedPart.join('\n')); } diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-render-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-render-module.ts index 6b369549fdd..96fbe510264 100644 --- a/extension/chrome/elements/pgp_block_modules/pgp-block-render-module.ts +++ b/extension/chrome/elements/pgp_block_modules/pgp-block-render-module.ts @@ -2,145 +2,18 @@ 'use strict'; -import { VerifyRes } from '../../../js/common/core/crypto/pgp/msg-util.js'; -import { Attachment } from '../../../js/common/core/attachment.js'; import { BrowserMsg } from '../../../js/common/browser/browser-msg.js'; import { Catch } from '../../../js/common/platform/catch.js'; -import { Mime } from '../../../js/common/core/mime.js'; -import { MsgBlock } from '../../../js/common/core/msg-block.js'; import { PgpBlockView } from '../pgp_block.js'; import { Ui } from '../../../js/common/browser/ui.js'; +import { Lang } from '../../../js/common/lang.js'; import { Xss } from '../../../js/common/platform/xss.js'; -import { MsgBlockParser } from '../../../js/common/core/msg-block-parser.js'; -import { AcctStore } from '../../../js/common/platform/store/acct-store.js'; -import { GmailParser } from '../../../js/common/api/email-provider/gmail/gmail-parser.js'; -import { CID_PATTERN, Str } from '../../../js/common/core/common.js'; -import DOMPurify from 'dompurify'; -import { Time } from '../../../js/common/browser/time.js'; export class PgpBlockViewRenderModule { - public doNotSetStateAsReadyYet = false; - private heightHist: number[] = []; - private printMailInfoHtml!: string; public constructor(private view: PgpBlockView) {} - public initPrintView = async () => { - const fullName = await AcctStore.get(this.view.acctEmail, ['full_name']); - Xss.sanitizeRender('.print_user_email', `${fullName.full_name} <${this.view.acctEmail}>`); - try { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const gmailMsg = await this.view.gmail.msgGet(this.view.msgId!, 'metadata', undefined); - const sentDate = new Date(GmailParser.findHeader(gmailMsg, 'date') ?? ''); - const sentDateStr = Str.fromDate(sentDate).replace(' ', ' at '); - const from = Str.parseEmail(GmailParser.findHeader(gmailMsg, 'from') ?? ''); - const fromHtml = from.name ? `${Xss.htmlSanitize(from.name)} <${from.email}>` : from.email; - /* eslint-disable @typescript-eslint/no-non-null-assertion */ - const ccString = GmailParser.findHeader(gmailMsg, 'cc') - ? `Cc: ${Xss.escape(GmailParser.findHeader(gmailMsg, 'cc')!)}
` - : ''; - const bccString = GmailParser.findHeader(gmailMsg, 'bcc') ? `Bcc: ${Xss.escape(GmailParser.findHeader(gmailMsg, 'bcc')!)}
` : ''; - /* eslint-enable @typescript-eslint/no-non-null-assertion */ - this.printMailInfoHtml = ` -
-

${Xss.htmlSanitize(GmailParser.findHeader(gmailMsg, 'subject') ?? '')}

-
-
-
-
- From: ${fromHtml} -
-
- ${sentDateStr} -
-
- To: ${Xss.escape(GmailParser.findHeader(gmailMsg, 'to') ?? '')}
- ${ccString} - ${bccString} -

- `; - } catch (e) { - this.view.errorModule.debug(`Error while getting gmail message for ${this.view.msgId} message. ${e}`); - } - }; - - public printPGPBlock = async () => { - const w = window.open(); - const html = ` - - - - - - - ${$('#print-header').html()} -
- ${Xss.htmlSanitize(this.printMailInfoHtml)} -
-
- ${Xss.htmlSanitize($('#pgp_block').html())} -
- - - `; - w?.document.write(html); - // Give some time for above dom to load in print dialog - // https://stackoverflow.com/questions/31725373/google-chrome-not-showing-image-in-print-preview - await Time.sleep(250); - w?.window.print(); - w?.document.close(); - }; - public renderText = (text: string) => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion document.getElementById('pgp_block')!.innerText = text; @@ -172,13 +45,7 @@ export class PgpBlockViewRenderModule { }); }; - public renderContent = async (htmlContent: string, isErr: boolean) => { - if (!isErr && !this.view.isOutgoing) { - // successfully opened incoming message - // eslint-disable-next-line @typescript-eslint/naming-convention - await AcctStore.set(this.view.acctEmail, { successfully_received_at_leat_one_message: true }); - } - + public renderContent = (htmlContent: string, isErr: boolean) => { let contentWithLink = linkifyHtml(htmlContent); // Temporary workaround for an issue where 'cryptup_reply' divs are not being hidden when replying to all @@ -230,13 +97,28 @@ export class PgpBlockViewRenderModule { } }; - public renderAsRegularContent = async (content: string) => { + public renderAsRegularContent = (content: string) => { this.setFrameColor('gray'); this.renderSignatureStatus('not signed'); this.renderEncryptionStatus('not encrypted'); - await this.renderContent(content, false); + this.renderContent(content, false); + Ui.setTestState('ready'); }; + public renderPassphraseNeeded = (longids: string[]) => { + const enterPp = `${Lang.pgpBlock.enterPassphrase} ${Lang.pgpBlock.toOpenMsg}`; + this.view.errorModule.renderErr(enterPp, undefined, 'pass phrase needed'); + $('.enter_passphrase').on( + 'click', + this.view.setHandler(() => { + Ui.setTestState('waiting'); + BrowserMsg.send.passphraseDialog(this.view.parentTabId, { + type: 'message', + longids, + }); + }) + ); + }; public renderErrorStatus = (status: string): JQuery => { return $('#pgp_error').text(status).show(); }; @@ -257,131 +139,10 @@ export class PgpBlockViewRenderModule { .text(status); }; - public decideDecryptedContentFormattingAndRender = async ( - decryptedBytes: Uint8Array | string, - isEncrypted: boolean, - sigResult: VerifyRes | undefined, - verificationPubs: string[], - retryVerification: (verificationPubs: string[]) => Promise, - plainSubject?: string - ) => { - if (isEncrypted) { - this.renderEncryptionStatus('encrypted'); - this.setFrameColor('green'); - } else { - this.renderEncryptionStatus('not encrypted'); - this.setFrameColor('gray'); - } - const publicKeys: string[] = []; - let renderableAttachments: Attachment[] = []; - let decryptedContent: string | undefined; - let isHtml = false; - // todo - replace with MsgBlockParser.fmtDecryptedAsSanitizedHtmlBlocks, then the extract/strip methods could be private? - if (!Mime.resemblesMsg(decryptedBytes)) { - const fcAttachmentBlocks: MsgBlock[] = []; - decryptedContent = Str.with(decryptedBytes); - decryptedContent = MsgBlockParser.extractFcAttachments(decryptedContent, fcAttachmentBlocks); - decryptedContent = MsgBlockParser.stripFcReplyToken(decryptedContent); - decryptedContent = MsgBlockParser.stripPublicKeys(decryptedContent, publicKeys); - if (fcAttachmentBlocks.length) { - renderableAttachments = fcAttachmentBlocks.map( - attachmentBlock => new Attachment(attachmentBlock.attachmentMeta!) // eslint-disable-line @typescript-eslint/no-non-null-assertion - ); - } - } else { - this.renderText('Formatting...'); - const decoded = await Mime.decode(decryptedBytes); - let inlineCIDAttachments: Attachment[] = []; - if (typeof decoded.html !== 'undefined') { - ({ sanitizedHtml: decryptedContent, inlineCIDAttachments } = this.replaceInlineImageCIDs(decoded.html, decoded.attachments)); - isHtml = true; - } else if (typeof decoded.text !== 'undefined') { - decryptedContent = decoded.text; - } else { - decryptedContent = ''; - } - if ( - decoded.subject && - isEncrypted && - (!plainSubject || !Mime.subjectWithoutPrefixes(plainSubject).includes(Mime.subjectWithoutPrefixes(decoded.subject))) - ) { - // there is an encrypted subject + (either there is no plain subject or the plain subject does not contain what's in the encrypted subject) - decryptedContent = this.getEncryptedSubjectText(decoded.subject, isHtml) + decryptedContent; // render encrypted subject in message - } - for (const attachment of decoded.attachments) { - if (attachment.isPublicKey()) { - publicKeys.push(attachment.getData().toUtfStr()); - } else if (!inlineCIDAttachments.some(inlineAttachment => inlineAttachment.cid === attachment.cid)) { - renderableAttachments.push(attachment); - } - } - } - await this.view.quoteModule.separateQuotedContentAndRenderText(decryptedContent, isHtml); - await this.view.signatureModule.renderPgpSignatureCheckResult(sigResult, verificationPubs, retryVerification); - if (isEncrypted && publicKeys.length) { - BrowserMsg.send.renderPublicKeys(this.view.parentTabId, { afterFrameId: this.view.frameId, publicKeys }); - } - if (renderableAttachments.length) { - this.view.attachmentsModule.renderInnerAttachments(renderableAttachments, isEncrypted); - } - this.resizePgpBlockFrame(); - if (!this.doNotSetStateAsReadyYet) { - // in case async tasks are still being worked at - Ui.setTestState('ready'); - } - }; - - /** - * Replaces inline image CID references with base64 encoded data in sanitized HTML - * and returns the sanitized HTML along with the inline CID attachments. - * - * @param html - The original HTML content. - * @param attachments - An array of email attachments. - * @returns An object containing sanitized HTML and an array of inline CID attachments. - */ - private replaceInlineImageCIDs = (html: string, attachments: Attachment[]): { sanitizedHtml: string; inlineCIDAttachments: Attachment[] } => { - // Array to store inline CID attachments - const inlineCIDAttachments: Attachment[] = []; - - // Define the hook function for DOMPurify to process image elements after sanitizing attributes - const processImageElements = (node: Element | null) => { - // Ensure the node exists and has a 'src' attribute - if (!node || !('src' in node)) return; - const imageSrc = node.getAttribute('src') as string; - if (!imageSrc) return; - const matches = imageSrc.match(CID_PATTERN); - - // Check if the src attribute contains a CID - if (matches && matches[1]) { - const contentId = matches[1]; - const contentIdAttachment = attachments.find(attachment => attachment.cid === `<${contentId}>`); - - // Replace the src attribute with a base64 encoded string - if (contentIdAttachment) { - inlineCIDAttachments.push(contentIdAttachment); - node.setAttribute('src', `data:${contentIdAttachment.type};base64,${contentIdAttachment.getData().toBase64Str()}`); - } - } - }; - - // Add the DOMPurify hook - DOMPurify.addHook('afterSanitizeAttributes', processImageElements); - - // Sanitize the HTML and remove the DOMPurify hooks - const sanitizedHtml = Xss.htmlSanitize(html); - DOMPurify.removeAllHooks(); - - return { sanitizedHtml, inlineCIDAttachments }; - }; - - private getEncryptedSubjectText = (subject: string, isHtml: boolean) => { - if (isHtml) { - return `
Encrypted Subject: - ${Xss.escape(subject)} -
-
`; - } else { - return `Encrypted Subject: ${subject}\n----------------------------------------------------------------------------------------------------\n`; - } + public renderSignatureOffline = () => { + this.renderSignatureStatus('error verifying signature: offline, click to retry').on( + 'click', + this.view.setHandler(() => window.parent.postMessage({ retry: this.view.frameId }, '*')) + ); }; } diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-signature-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-signature-module.ts deleted file mode 100644 index 65b10bc4965..00000000000 --- a/extension/chrome/elements/pgp_block_modules/pgp-block-signature-module.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ - -'use strict'; - -import { ApiErr } from '../../../js/common/api/shared/api-error.js'; -import { Catch } from '../../../js/common/platform/catch.js'; -import { PgpBlockView } from '../pgp_block'; -import { Ui } from '../../../js/common/browser/ui.js'; -import { VerifyRes } from '../../../js/common/core/crypto/pgp/msg-util.js'; -import { Value } from '../../../js/common/core/common.js'; -import { BrowserMsg } from '../../../js/common/browser/browser-msg.js'; - -export class PgpBlockViewSignatureModule { - public constructor(private view: PgpBlockView) {} - - public renderPgpSignatureCheckResult = async ( - verifyRes: VerifyRes | undefined, - verificationPubs: string[], - retryVerification?: (verificationPubs: string[]) => Promise - ) => { - this.view.renderModule.doNotSetStateAsReadyYet = true; // so that body state is not marked as ready too soon - automated tests need to know when to check results - if (verifyRes?.error) { - if (this.view.signature && !verifyRes.isErrFatal && this.view.decryptModule.canAndShouldFetchFromApi()) { - // Sometimes the signed content is slightly modified when parsed from DOM, - // so the message should be re-fetched straight from API to make sure we get the original signed data and verify again - this.view.signature.parsedSignature = undefined; // force to re-parse - await this.view.decryptModule.initialize(verificationPubs, true); - return; - } - this.view.renderModule.renderSignatureStatus(`error verifying signature: ${verifyRes.error}`); - this.view.renderModule.setFrameColor('red'); - } else if (!verifyRes || !verifyRes.signerLongids.length) { - this.view.renderModule.renderSignatureStatus('not signed'); - } else if (verifyRes.match) { - this.view.renderModule.renderSignatureStatus('signed'); - } else { - if (retryVerification) { - const signerEmail = this.view.getExpectedSignerEmail(); - if (!signerEmail) { - // in some tests we load the block without sender information - this.view.renderModule.renderSignatureStatus('could not verify signature: missing pubkey, missing sender info'); - } else { - $('#pgp_signature').addClass('gray_label').text('verifying signature...'); - try { - const { pubkeys } = await this.view.pubLookup.lookupEmail(signerEmail); - if (pubkeys.length) { - await BrowserMsg.send.bg.await.saveFetchedPubkeys({ email: signerEmail, pubkeys }); - await this.renderPgpSignatureCheckResult(await retryVerification(pubkeys), pubkeys, undefined); - return; - } - this.renderMissingPubkeyOrBadSignature(verifyRes); - } catch (e) { - if (ApiErr.isSignificant(e)) { - Catch.reportErr(e); - this.view.renderModule.renderSignatureStatus(`error verifying signature: ${e}`); - } else { - this.view.renderModule.renderSignatureStatus('error verifying signature: offline, click to retry').on( - 'click', - this.view.setHandler(() => window.location.reload()) - ); - } - } - } - } else { - // !retryVerification - this.renderMissingPubkeyOrBadSignature(verifyRes); - } - } - this.view.renderModule.doNotSetStateAsReadyYet = false; - Ui.setTestState('ready'); - }; - - private renderMissingPubkey = (signerLongid: string) => { - this.view.renderModule.renderSignatureStatus(`could not verify signature: missing pubkey ${signerLongid}`); - }; - - private renderBadSignature = () => { - this.view.renderModule.renderSignatureStatus('bad signature'); - this.view.renderModule.setFrameColor('red'); // todo: in what other cases should we set the frame red? - }; - - private renderMissingPubkeyOrBadSignature = (verifyRes: VerifyRes): void => { - // eslint-disable-next-line no-null/no-null - if (verifyRes.match === null || !Value.arr.hasIntersection(verifyRes.signerLongids, verifyRes.suppliedLongids)) { - this.renderMissingPubkey(verifyRes.signerLongids[0]); - } else { - this.renderBadSignature(); - } - }; -} diff --git a/extension/chrome/settings/inbox/inbox-modules/inbox-active-thread-module.ts b/extension/chrome/settings/inbox/inbox-modules/inbox-active-thread-module.ts index 9c0e3d655ca..5c912de10bb 100644 --- a/extension/chrome/settings/inbox/inbox-modules/inbox-active-thread-module.ts +++ b/extension/chrome/settings/inbox/inbox-modules/inbox-active-thread-module.ts @@ -5,7 +5,7 @@ import { Bm, BrowserMsg } from '../../../../js/common/browser/browser-msg.js'; import { FactoryReplyParams, XssSafeFactory } from '../../../../js/common/xss-safe-factory.js'; import { GmailParser, GmailRes } from '../../../../js/common/api/email-provider/gmail/gmail-parser.js'; -import { Str, Url, UrlParams } from '../../../../js/common/core/common.js'; +import { Url, UrlParams } from '../../../../js/common/core/common.js'; import { ApiErr } from '../../../../js/common/api/shared/api-error.js'; import { BrowserMsgCommonHandlers } from '../../../../js/common/browser/browser-msg-common-handlers.js'; @@ -13,16 +13,74 @@ import { Buf } from '../../../../js/common/core/buf.js'; import { Catch } from '../../../../js/common/platform/catch.js'; import { InboxView } from '../inbox.js'; import { Lang } from '../../../../js/common/lang.js'; -import { Mime } from '../../../../js/common/core/mime.js'; import { Ui } from '../../../../js/common/browser/ui.js'; import { ViewModule } from '../../../../js/common/view-module.js'; import { Xss } from '../../../../js/common/platform/xss.js'; import { Browser } from '../../../../js/common/browser/browser.js'; import { Attachment } from '../../../../js/common/core/attachment.js'; +import { LoaderContextInterface } from '../../../../js/common/loader-context-interface.js'; + +class LoaderContext implements LoaderContextInterface { + private renderedMessageXssSafe: string | undefined; // xss-none + private renderedAttachmentsXssSafe: string[] = []; // xss-none + + public constructor(private readonly factory: XssSafeFactory) {} + + public renderPlainAttachment = (a: Attachment) => { + // todo: render error argument + this.renderedAttachmentsXssSafe.push(this.factory.embeddedAttachment(a, false)); // xss-safe-factory + }; + + public prependEncryptedAttachment = (a: Attachment) => { + this.renderedAttachmentsXssSafe.unshift(this.factory.embeddedAttachment(a, true)); // xss-safe-factory + }; + + /* eslint-disable @typescript-eslint/naming-convention */ + /** + * XSS WARNING + * + * newHtmlContent must be XSS safe + */ + // prettier-ignore + public setMsgBody_DANGEROUSLY = (newHtmlContent_MUST_BE_XSS_SAFE: string, method: 'set' | 'append' | 'after') => { // xss-dangerous-function + /* eslint-enable @typescript-eslint/naming-convention */ + if (method === 'set') { + this.renderedMessageXssSafe = newHtmlContent_MUST_BE_XSS_SAFE; // xss-safe-value + } else { + // todo: we may implement the difference between 'append' and 'after' + this.renderedAttachmentsXssSafe.unshift(newHtmlContent_MUST_BE_XSS_SAFE); // xss-safe-value + } + }; + + public getRenderedMessageXssSafe = (): string => { + return this.renderedMessageXssSafe || ''; + }; + + public getRenderedAttachmentsXssSafe = (): string => { + return this.renderedAttachmentsXssSafe.length + ? `
${this.renderedAttachmentsXssSafe.join('')}
` + : ''; + }; + + /* eslint-disable @typescript-eslint/naming-convention */ + /** + * XSS WARNING + * + * newHtmlContents must be XSS safe + */ + // prettier-ignore + public setRenderedAttachments_DANGEROUSLY = (newHtmlContents_MUST_BE_XSS_SAFE: string[]) => { // xss-dangerous-function + /* eslint-enable @typescript-eslint/naming-convention */ + this.renderedAttachmentsXssSafe = newHtmlContents_MUST_BE_XSS_SAFE; // xss-safe-value + }; + + public hideAttachment = () => { + // not applicable + }; +} export class InboxActiveThreadModule extends ViewModule { private threadId: string | undefined; - private threadHasPgpBlock = false; private debugEmails = ['flowcrypt.compatibility@gmail.com', 'ci.tests.gmail@flowcrypt.dev', 'e2e.enterprise.test@flowcrypt.com']; // adds debugging ui, useful for creating automated tests public render = async (threadId: string, thread?: GmailRes.GmailThread) => { @@ -37,14 +95,26 @@ export class InboxActiveThreadModule extends ViewModule { const subject = GmailParser.findHeader(thread.messages[0], 'subject') || '(no subject)'; this.updateUrlWithoutRedirecting(`${subject} - FlowCrypt Inbox`, { acctEmail: this.view.acctEmail, threadId }); this.view.displayBlock('thread', Xss.escape(subject)); + let threadHasPgpBlock = false; for (const m of thread.messages) { - await this.renderMsg(m); + const pgpFlag = await this.renderMsg(m); + threadHasPgpBlock ||= pgpFlag; } - if (this.threadHasPgpBlock) { + if (threadHasPgpBlock || this.view.showOriginal) { $('.action_see_original_message').css('display', 'inline-block'); if (this.view.showOriginal) { $('.action_see_original_message').text('See Decrypted'); } + $('.action_see_original_message').on( + 'click', + this.view.setHandler(() => + this.view.redirectToUrl({ + acctEmail: this.view.acctEmail, + threadId: this.threadId, + showOriginal: !this.view.showOriginal, + }) + ) + ); } const lastMsg = thread.messages[thread.messages.length - 1]; if (lastMsg) { @@ -65,21 +135,10 @@ export class InboxActiveThreadModule extends ViewModule { Xss.sanitizeRender('.thread', `
Failed to load thread due to the following error:
${printable}
`); } } + this.view.messageRenderer.deleteExpired(); }; public setHandlers = () => { - if (this.threadHasPgpBlock) { - $('.action_see_original_message').on( - 'click', - this.view.setHandler(() => - this.view.redirectToUrl({ - acctEmail: this.view.acctEmail, - threadId: this.threadId, - showOriginal: !this.view.showOriginal, - }) - ) - ); - } BrowserMsg.addListener('close_reply_message', async ({ frameId }: Bm.ComposeWindow) => { $(`iframe#${frameId}`).remove(); }); @@ -103,49 +162,39 @@ export class InboxActiveThreadModule extends ViewModule { BrowserMsg.addListener('reply_pubkey_mismatch', BrowserMsgCommonHandlers.replyPubkeyMismatch); }; - private renderMsg = async (message: GmailRes.GmailMsg) => { + private renderMsg = async (message: GmailRes.GmailMsg): Promise => { const htmlId = this.replyMsgId(message.id); - const from = GmailParser.findHeader(message, 'from') || 'unknown'; try { - const { raw } = await this.view.gmail.msgGet(message.id, 'raw'); - const mimeMsg = Buf.fromBase64UrlStr(raw!); // eslint-disable-line @typescript-eslint/no-non-null-assertion - const { blocks, headers } = await Mime.process(mimeMsg); - let r = ''; - let renderedAttachments = ''; - for (const block of blocks) { - if (block.type === 'encryptedMsg' || block.type === 'publicKey' || block.type === 'privateKey' || block.type === 'signedMsg') { - this.threadHasPgpBlock = true; - } - if (r) { - r += '

'; - } - if (['encryptedAttachment', 'plainAttachment'].includes(block.type)) { - renderedAttachments += XssSafeFactory.renderableMsgBlock( - this.view.factory, - block, - message.id, - from, - this.view.storage.sendAs && !!this.view.storage.sendAs[from] - ); - } else if (this.view.showOriginal) { - r += Xss.escape(Str.with(block.content)).replace(/\n/g, '
'); - } else { - r += XssSafeFactory.renderableMsgBlock(this.view.factory, block, message.id, from, this.view.storage.sendAs && !!this.view.storage.sendAs[from]); - } - } - if (renderedAttachments) { - r += `
${renderedAttachments}
`; + const msg = await this.view.messageRenderer.downloader.msgGetFull(message.id); + const { blocks, body, messageInfo, attachments } = await this.view.messageRenderer.msgGetProcessed(message.id); + const senderEmail = messageInfo.from?.email; + const { renderedXssSafe, blocksInFrames } = this.view.messageRenderer.renderMsg({ blocks, senderEmail }, this.view.showOriginal); // xss-safe-factory + const loaderContext = new LoaderContext(this.view.factory); + // not doing this in the constructor to track XSS safety + const renderedAttachmentsXssSafe = /* xss-safe-factory */ blocks + .filter(block => block.attachmentMeta && ['encryptedAttachment', 'plainAttachment'].includes(block.type)) + .map(block => XssSafeFactory.renderableMsgBlock(this.view.factory, block, this.view.messageRenderer.isOutgoing(senderEmail))); + loaderContext.setRenderedAttachments_DANGEROUSLY(renderedAttachmentsXssSafe); // xss-safe-factory + loaderContext.setMsgBody_DANGEROUSLY(renderedXssSafe, 'set'); // xss-safe-value + for (const a of attachments) { + await this.view.messageRenderer.processAttachment(a, body, attachments, loaderContext, undefined, message.id, messageInfo); } const exportBtn = this.debugEmails.includes(this.view.acctEmail) ? 'download api export' : ''; - r = - `

From: ${Xss.escape(from)} ${headers.date} ${exportBtn}

` + r; - $('.thread').append(this.wrapMsg(htmlId, r)); // xss-safe-factory + const r = + `

From: ${Xss.escape(messageInfo.from?.full || 'unknown')} ${ + GmailParser.findHeader(msg, 'Date') ?? '' + } ${exportBtn}

` + // xss-direct + loaderContext.getRenderedMessageXssSafe() + + loaderContext.getRenderedAttachmentsXssSafe(); + $('.thread').append(this.wrapMsg(htmlId, r)); // xss-safe-value + await this.view.messageRenderer.startProcessingInlineBlocks(this.view.relayManager, this.view.factory, messageInfo, blocksInFrames); if (exportBtn) { $('.action-export').on( 'click', this.view.setHandler(() => this.exportMsgForDebug(message.id)) ); } + return blocks.some(block => ['encryptedMsg', 'publicKey', 'privateKey', 'signedMsg'].includes(block.type)); } catch (e) { if (ApiErr.isNetErr(e)) { Xss.sanitizeAppend('.thread', this.wrapMsg(htmlId, `Failed to load a message (network error), skipping. ${Ui.retryLink()}`)); @@ -158,14 +207,15 @@ export class InboxActiveThreadModule extends ViewModule { const printable = Xss.escape(e instanceof Error ? e.stack || e.message : JSON.stringify(e, undefined, 2)); Xss.sanitizeAppend('.thread', this.wrapMsg(htmlId, `Failed to load a message due to the following error:
${printable}
`)); } + return false; } }; private exportMsgForDebug = async (msgId: string) => { const full = await this.view.gmail.msgGet(msgId, 'full'); const raw = await this.view.gmail.msgGet(msgId, 'raw'); - const existingAttachments = GmailParser.findAttachments(full); - await this.view.gmail.fetchAttachments(existingAttachments); + const existingAttachments = GmailParser.findAttachments(full, full.id); + await this.view.gmail.fetchAttachmentsMissingData(existingAttachments); this.redactExportMsgHeaders(full); this.redactExportMsgHeaders(raw); const attachments: { [id: string]: { data: string; size: number } } = {}; @@ -230,6 +280,6 @@ export class InboxActiveThreadModule extends ViewModule { }; private wrapMsg = (id: string, html: string) => { - return Ui.e('div', { id, class: 'message line', html }); + return Ui.e('div', { id, class: 'message line', html, 'data-test': 'message-line' }); }; } diff --git a/extension/chrome/settings/inbox/inbox-modules/inbox-menu-module.ts b/extension/chrome/settings/inbox/inbox-modules/inbox-menu-module.ts index ba3021fef67..be231a89d4f 100644 --- a/extension/chrome/settings/inbox/inbox-modules/inbox-menu-module.ts +++ b/extension/chrome/settings/inbox/inbox-modules/inbox-menu-module.ts @@ -119,9 +119,9 @@ export class InboxMenuModule extends ViewModule { private renderNavbartTop = async () => { $('.action_open_webmail').attr('href', Google.webmailUrl(this.view.acctEmail)); $('.action_choose_account').get(0).title = this.view.acctEmail; - if (this.view.storage.picture) { + if (this.view.picture) { $('img.main-profile-img') - .attr('src', this.view.storage.picture) + .attr('src', this.view.picture) .on( 'error', this.view.setHandler(self => { diff --git a/extension/chrome/settings/inbox/inbox.htm b/extension/chrome/settings/inbox/inbox.htm index 7c7a42ce4ce..d94e9758708 100644 --- a/extension/chrome/settings/inbox/inbox.htm +++ b/extension/chrome/settings/inbox/inbox.htm @@ -37,7 +37,7 @@

- See Original + See Original
diff --git a/extension/chrome/settings/inbox/inbox.ts b/extension/chrome/settings/inbox/inbox.ts index 5245f96602e..32beb7fe5ac 100644 --- a/extension/chrome/settings/inbox/inbox.ts +++ b/extension/chrome/settings/inbox/inbox.ts @@ -21,7 +21,10 @@ import { View } from '../../../js/common/view.js'; import { WebmailCommon } from '../../../js/common/webmail.js'; import { Xss } from '../../../js/common/platform/xss.js'; import { XssSafeFactory } from '../../../js/common/xss-safe-factory.js'; -import { AcctStore, AcctStoreDict } from '../../../js/common/platform/store/acct-store.js'; +import { AcctStore } from '../../../js/common/platform/store/acct-store.js'; +import { RelayManager } from '../../../js/common/relay-manager.js'; +import { MessageRenderer } from '../../../js/common/message-renderer.js'; +import { Env } from '../../../js/common/browser/env.js'; export class InboxView extends View { public readonly inboxMenuModule: InboxMenuModule; @@ -39,9 +42,11 @@ export class InboxView extends View { public injector!: Injector; public webmailCommon!: WebmailCommon; + public messageRenderer!: MessageRenderer; public factory!: XssSafeFactory; - public storage!: AcctStoreDict; + public picture?: string; public tabId!: string; + public relayManager!: RelayManager; public constructor() { super(); @@ -51,12 +56,18 @@ export class InboxView extends View { this.threadId = Assert.urlParamRequire.optionalString(uncheckedUrlParams, 'threadId'); this.showOriginal = uncheckedUrlParams.showOriginal === true; this.debug = uncheckedUrlParams.debug === true; + this.relayManager = new RelayManager(this.debug); this.S = Ui.buildJquerySels({ threads: '.threads', thread: '.thread', body: 'body' }); this.gmail = new Gmail(this.acctEmail); this.inboxMenuModule = new InboxMenuModule(this); this.inboxNotificationModule = new InboxNotificationModule(this); this.inboxActiveThreadModule = new InboxActiveThreadModule(this); this.inboxListThreadsModule = new InboxListThreadsModule(this); + window.addEventListener('message', e => { + if (e.origin === Env.getExtensionOrigin()) { + this.relayManager.handleMessageFromFrame(e.data); + } + }); } public render = async () => { @@ -64,12 +75,13 @@ export class InboxView extends View { this.factory = new XssSafeFactory(this.acctEmail, this.tabId); this.injector = new Injector('settings', undefined, this.factory); this.webmailCommon = new WebmailCommon(this.acctEmail, this.injector); - this.storage = await AcctStore.get(this.acctEmail, ['email_provider', 'picture', 'sendAs']); + let emailProvider: 'gmail' | undefined; + ({ email_provider: emailProvider, picture: this.picture } = await AcctStore.get(this.acctEmail, ['email_provider', 'picture'])); + this.messageRenderer = await MessageRenderer.newInstance(this.acctEmail, this.gmail, this.relayManager, this.factory, this.debug); this.inboxNotificationModule.render(); - const emailProvider = this.storage.email_provider || 'gmail'; try { await Settings.populateAccountsMenu('inbox.htm'); - if (emailProvider !== 'gmail') { + if (emailProvider && emailProvider !== 'gmail') { $('body').text('Not supported for ' + emailProvider); } else { await this.inboxMenuModule.render(); diff --git a/extension/chrome/settings/modules/contacts.ts b/extension/chrome/settings/modules/contacts.ts index b20ebb55e2d..fe4fad513ab 100644 --- a/extension/chrome/settings/modules/contacts.ts +++ b/extension/chrome/settings/modules/contacts.ts @@ -282,12 +282,8 @@ View.run( const container = $('#bulk_import #processed'); for (const block of blocks) { if (block.type === 'publicKey' || block.type === 'certificate') { - const replacedHtmlSafe = XssSafeFactory.renderableMsgBlock( - this.factory!, // eslint-disable-line @typescript-eslint/no-non-null-assertion - block, - '', - '' - ); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const replacedHtmlSafe = XssSafeFactory.renderableMsgBlock(this.factory!, block); if (replacedHtmlSafe && replacedHtmlSafe !== value) { container.append(replacedHtmlSafe); // xss-safe-factory } diff --git a/extension/chrome/settings/modules/debug_api.ts b/extension/chrome/settings/modules/debug_api.ts index dd0d312b6ee..d5d132d3c57 100644 --- a/extension/chrome/settings/modules/debug_api.ts +++ b/extension/chrome/settings/modules/debug_api.ts @@ -43,7 +43,6 @@ View.run( 'full_name', 'cryptup_enabled', 'setup_done', - 'successfully_received_at_leat_one_message', 'notification_setup_done_seen', 'rules', 'use_rich_text', diff --git a/extension/js/background_page/background_page.ts b/extension/js/background_page/background_page.ts index 338b3cc1549..34570938951 100644 --- a/extension/js/background_page/background_page.ts +++ b/extension/js/background_page/background_page.ts @@ -21,7 +21,7 @@ console.info('background_process.js starting'); (async () => { let db: IDBDatabase; let storage: GlobalStoreDict; - const inMemoryStore = new ExpirationCache(4 * 60 * 60 * 1000); // 4 hours + const inMemoryStore = new ExpirationCache(4 * 60 * 60 * 1000); // 4 hours Catch.setHandledInterval(() => inMemoryStore.deleteExpired(), 60000); // each minute try { diff --git a/extension/js/background_page/bg-handlers.ts b/extension/js/background_page/bg-handlers.ts index 4674a8cdcbb..59dc42fb99c 100644 --- a/extension/js/background_page/bg-handlers.ts +++ b/extension/js/background_page/bg-handlers.ts @@ -4,7 +4,7 @@ import { Api } from '../common/api/shared/api.js'; import { BgUtils } from './bgutils.js'; -import { Bm } from '../common/browser/browser-msg.js'; +import { Bm, BrowserMsg } from '../common/browser/browser-msg.js'; import { Gmail } from '../common/api/email-provider/gmail/gmail.js'; import { GlobalStore } from '../common/platform/store/global-store.js'; import { ContactStore } from '../common/platform/store/contact-store.js'; @@ -29,7 +29,27 @@ export class BgHandlers { return await dbFunc(db, ...request.args); }; - public static ajaxHandler = async (r: Bm.Ajax): Promise => { + public static ajaxHandler = async (r: Bm.Ajax, sender: Bm.Sender): Promise => { + if (r.req.context?.frameId) { + // progress updates were requested via messages + let dest = r.req.context.tabId; + if (typeof dest === 'undefined') { + // detect tabId from sender + if (sender !== 'background') { + if (typeof sender?.tab?.id !== 'undefined') { + dest = `${sender.tab.id}:0`; + } + } + } + if (typeof dest !== 'undefined') { + const destination = dest; + const frameId = r.req.context.frameId; + const expectedTransferSize = r.req.context.expectedTransferSize; + r.req.xhr = Api.getAjaxProgressXhrFactory({ + download: (percent, loaded, total) => BrowserMsg.send.ajaxProgress(destination, { percent, loaded, total, expectedTransferSize, frameId }), + }); + } + } return await Api.ajax(r.req, r.stack); }; diff --git a/extension/js/common/api/email-provider/gmail/gmail-parser.ts b/extension/js/common/api/email-provider/gmail/gmail-parser.ts index 8185b95631d..e89adc9be79 100644 --- a/extension/js/common/api/email-provider/gmail/gmail-parser.ts +++ b/extension/js/common/api/email-provider/gmail/gmail-parser.ts @@ -141,14 +141,14 @@ export class GmailParser { public static findAttachments = ( msgOrPayloadOrPart: GmailRes.GmailMsg | GmailRes.GmailMsg$payload | GmailRes.GmailMsg$payload$part, + internalMsgId: string, internalResults: Attachment[] = [], - internalMsgId?: string, { pgpEncryptedIndex }: { pgpEncryptedIndex?: number } = {} ) => { if (msgOrPayloadOrPart.hasOwnProperty('payload')) { internalMsgId = (msgOrPayloadOrPart as GmailRes.GmailMsg).id; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - GmailParser.findAttachments((msgOrPayloadOrPart as GmailRes.GmailMsg).payload!, internalResults, internalMsgId); + GmailParser.findAttachments((msgOrPayloadOrPart as GmailRes.GmailMsg).payload!, internalMsgId, internalResults); } if (msgOrPayloadOrPart.hasOwnProperty('parts')) { const payload = msgOrPayloadOrPart as GmailRes.GmailMsg$payload; @@ -159,7 +159,7 @@ export class GmailParser { parts.length === 2 && contentType?.value?.startsWith('multipart/encrypted;') && contentType.value.includes('protocol="application/pgp-encrypted"') ); for (const [i, part] of parts.entries()) { - GmailParser.findAttachments(part, internalResults, internalMsgId, { + GmailParser.findAttachments(part, internalMsgId, internalResults, { pgpEncryptedIndex: pgpEncrypted ? i : undefined, }); } diff --git a/extension/js/common/api/email-provider/gmail/gmail.ts b/extension/js/common/api/email-provider/gmail/gmail.ts index 986b93d6b1b..e12016d2280 100644 --- a/extension/js/common/api/email-provider/gmail/gmail.ts +++ b/extension/js/common/api/email-provider/gmail/gmail.ts @@ -3,7 +3,7 @@ 'use strict'; import { AddrParserResult, BrowserWindow } from '../../../browser/browser-window.js'; -import { ChunkedCb, ProgressCb, EmailProviderContact } from '../../shared/api.js'; +import { ChunkedCb, ProgressCb, EmailProviderContact, ProgressDestFrame } from '../../shared/api.js'; import { Dict, Str, Value } from '../../../core/common.js'; import { EmailProviderApi, EmailProviderInterface, Backups } from '../email-provider-api.js'; import { GMAIL_GOOGLE_API_HOST, gmailBackupSearchQuery } from '../../../core/const.js'; @@ -15,13 +15,9 @@ import { Buf } from '../../../core/buf.js'; import { Catch } from '../../../platform/catch.js'; import { KeyUtil } from '../../../core/crypto/key.js'; import { Env } from '../../../browser/env.js'; -import { FormatError } from '../../../core/crypto/pgp/msg-util.js'; import { Google } from './google.js'; import { GoogleAuth } from './google-auth.js'; -import { Mime } from '../../../core/mime.js'; -import { PgpArmor } from '../../../core/crypto/pgp/pgp-armor.js'; import { SendableMsg } from '../sendable-msg.js'; -import { Xss } from '../../../platform/xss.js'; import { KeyStore } from '../../../platform/store/key-store.js'; export type GmailResponseFormat = 'raw' | 'full' | 'metadata'; @@ -123,15 +119,9 @@ export class Gmail extends EmailProviderApi implements EmailProviderInterface { return await Google.gmailCall(this.acctEmail, 'GET', `labels`, {}); }; - public attachmentGet = async (msgId: string, attId: string, progressCb?: ProgressCb): Promise => { + public attachmentGet = async (msgId: string, attId: string, progress: { download: ProgressCb } | ProgressDestFrame): Promise => { type RawGmailAttRes = { attachmentId: string; size: number; data: string }; - const { attachmentId, size, data } = await Google.gmailCall( - this.acctEmail, - 'GET', - `messages/${msgId}/attachments/${attId}`, - {}, - { download: progressCb } - ); + const { attachmentId, size, data } = await Google.gmailCall(this.acctEmail, 'GET', `messages/${msgId}/attachments/${attId}`, {}, progress); return { attachmentId, size, data: Buf.fromBase64UrlStr(data) }; // data should be a Buf for ease of passing to/from bg page }; @@ -232,35 +222,45 @@ export class Gmail extends EmailProviderApi implements EmailProviderInterface { }); }; - public fetchAttachments = async (attachments: Attachment[], progressCb?: ProgressCb) => { - if (!attachments.length) { + public fetchAttachmentsMissingData = async (attachments: Attachment[], progressCb?: ProgressCb) => { + const attachmentsMissingData = attachments.filter(a => !a.hasData()); + if (!attachmentsMissingData.length) { return; } let lastProgressPercent = -1; const loadedAr: Array = []; // 1.33 is approximate ratio of downloaded data to what we expected, likely due to encoding - const total = attachments.map(x => x.length).reduce((a, b) => a + b) * 1.33; + const total = attachmentsMissingData.map(x => x.length).reduce((a, b) => a + b) * 1.33; const responses = await Promise.all( - attachments.map((a, index) => + attachmentsMissingData.map((a, index) => // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.attachmentGet(a.msgId!, a.id!, (_, loaded) => { - if (progressCb) { - loadedAr[index] = loaded || 0; - const totalLoaded = loadedAr.reduce((a, b) => a + b); - const progressPercent = Math.round((totalLoaded * 100) / total); - if (progressPercent !== lastProgressPercent) { - lastProgressPercent = progressPercent; - progressCb(progressPercent, totalLoaded, total); + this.attachmentGet(a.msgId!, a.id!, { + download: (_, loaded) => { + if (progressCb) { + loadedAr[index] = loaded || 0; + const totalLoaded = loadedAr.reduce((a, b) => a + b); + const progressPercent = Math.round((totalLoaded * 100) / total); + if (progressPercent !== lastProgressPercent) { + lastProgressPercent = progressPercent; + progressCb(progressPercent, totalLoaded, total); + } } - } + }, }) ) ); for (const i of responses.keys()) { - attachments[i].setData(responses[i].data); + attachmentsMissingData[i].setData(responses[i].data); } }; + public fetchAttachment = async (a: Attachment, progressFunction: (expectedTransferSize: number) => { download: ProgressCb } | ProgressDestFrame) => { + const expectedTransferSize = a.length * 1.33; // todo: remove code duplication + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const response = await this.attachmentGet(a.msgId!, a.id!, progressFunction(expectedTransferSize)); + a.setData(response.data); + }; + /** * This will keep triggering callback with new emails as they are being discovered */ @@ -307,72 +307,6 @@ export class Gmail extends EmailProviderApi implements EmailProviderInterface { await this.apiGmailLoopThroughEmailsToCompileContacts(needles, gmailQuery, chunkedCb); }; - /** - * Extracts the encrypted message from gmail api. Sometimes it's sent as a text, sometimes html, sometimes attachments in various forms. - * As MsgBlockParser detects incomplete encryptedMsg etc. and they get through, we're handling them too - */ - public extractArmoredBlock = async ( - msgId: string, - format: GmailResponseFormat, - progressCb?: ProgressCb - ): Promise<{ armored: string; plaintext?: string; subject?: string; isPwdMsg: boolean }> => { - // only track progress in this call if we are getting RAW mime, - // because these tend to be big, while 'full' and 'metadata' are tiny - // since we often do full + get attachments below, the user would see 100% after the first short request, - // and then again 0% when attachments start downloading, which would be confusing - const gmailMsg = await this.msgGet(msgId, format, format === 'raw' ? progressCb : undefined); - const isPwdMsg = /https:\/\/flowcrypt\.com\/[a-zA-Z0-9]{10}$/.test(gmailMsg.snippet || ''); - const subject = gmailMsg.payload ? GmailParser.findHeader(gmailMsg.payload, 'subject') : undefined; - if (format === 'full') { - const bodies = GmailParser.findBodies(gmailMsg); - const attachments = GmailParser.findAttachments(gmailMsg); - const textBody = Buf.fromBase64UrlStr(bodies['text/plain'] || '').toUtfStr(); - const fromTextBody = PgpArmor.clip(textBody); - if (fromTextBody) { - return { armored: fromTextBody, subject, isPwdMsg }; - } - const htmlBody = Xss.htmlSanitizeAndStripAllTags(Buf.fromBase64UrlStr(bodies['text/html'] || '').toUtfStr(), '\n'); - const fromHtmlBody = PgpArmor.clip(htmlBody); - if (fromHtmlBody) { - return { armored: fromHtmlBody, subject, isPwdMsg }; - } - for (const attachment of attachments) { - if (attachment.treatAs(attachments, !!textBody) === 'encryptedMsg') { - await this.fetchAttachments([attachment], progressCb); - const armoredMsg = PgpArmor.clip(attachment.getData().toUtfStr()); - if (!armoredMsg) { - throw new FormatError('Problem extracting armored message', attachment.getData().toUtfStr()); - } - return { armored: armoredMsg, subject, isPwdMsg }; - } - } - const plaintext = PgpArmor.clipIncomplete(textBody) || PgpArmor.clipIncomplete(htmlBody); - if (plaintext) { - return { armored: '', plaintext, subject, isPwdMsg }; - } - throw new FormatError('Armored message not found', textBody || htmlBody); - } else { - // format === raw - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const mimeMsg = Buf.fromBase64UrlStr(gmailMsg.raw!); - const decoded = await Mime.decode(mimeMsg); - if (decoded.text !== undefined) { - const armoredMsg = PgpArmor.clip(decoded.text); - if (armoredMsg) { - return { armored: armoredMsg, subject, isPwdMsg }; - } - // todo - the message might be in attachments - const plaintext = PgpArmor.clipIncomplete(decoded.text); - if (plaintext) { - return { armored: '', plaintext, subject, isPwdMsg }; - } - throw new FormatError('Could not find armored message in parsed raw mime', mimeMsg.toUtfStr()); - } else { - throw new FormatError('No text in parsed raw mime', mimeMsg.toUtfStr()); - } - } - }; - public fetchAcctAliases = async (): Promise => { const res = (await Google.gmailCall(this.acctEmail, 'GET', 'settings/sendAs', {})) as GmailRes.GmailAliases; for (const sendAs of res.sendAs) { @@ -392,9 +326,9 @@ export class Gmail extends EmailProviderApi implements EmailProviderInterface { const msgs = await this.msgsGet(msgIds, 'full'); const attachments: Attachment[] = []; for (const msg of msgs) { - attachments.push(...GmailParser.findAttachments(msg)); + attachments.push(...GmailParser.findAttachments(msg, msg.id)); } - await this.fetchAttachments(attachments); + await this.fetchAttachmentsMissingData(attachments); const { keys: foundBackupKeys } = await KeyUtil.readMany(Buf.fromUtfStr(attachments.map(a => a.getData().toUtfStr()).join('\n'))); const backups = await Promise.all(foundBackupKeys.map(k => KeyUtil.keyInfoObj(k))); const imported = await KeyStore.get(this.acctEmail); diff --git a/extension/js/common/api/email-provider/gmail/google-auth.ts b/extension/js/common/api/email-provider/gmail/google-auth.ts index d6154dbf168..c4cf721fa5f 100644 --- a/extension/js/common/api/email-provider/gmail/google-auth.ts +++ b/extension/js/common/api/email-provider/gmail/google-auth.ts @@ -5,7 +5,7 @@ import { Str, Url } from '../../../core/common.js'; import { FLAVOR, GOOGLE_OAUTH_SCREEN_HOST, OAUTH_GOOGLE_API_HOST } from '../../../core/const.js'; import { ApiErr } from '../../shared/api-error.js'; -import { Api } from './../../shared/api.js'; +import { Api, ApiCallContext } from './../../shared/api.js'; import { Bm, GoogleAuthWindowResult$result } from '../../../browser/browser-msg.js'; import { Buf } from '../../../core/buf.js'; @@ -122,7 +122,7 @@ export class GoogleAuth { ); }; - public static apiGoogleCallRetryAuthErrorOneTime = async (acctEmail: string, request: JQuery.AjaxSettings): Promise => { + public static apiGoogleCallRetryAuthErrorOneTime = async (acctEmail: string, request: JQuery.AjaxSettings): Promise => { try { return await Api.ajax(request, Catch.stackTrace()); } catch (firstAttemptErr) { diff --git a/extension/js/common/api/email-provider/gmail/google.ts b/extension/js/common/api/email-provider/gmail/google.ts index d28ad3eb925..6b7bac05796 100644 --- a/extension/js/common/api/email-provider/gmail/google.ts +++ b/extension/js/common/api/email-provider/gmail/google.ts @@ -2,7 +2,7 @@ 'use strict'; -import { Api, ProgressCbs, ReqMethod } from '../../shared/api.js'; +import { Api, ProgressCbs, ProgressDestFrame, ReqMethod } from '../../shared/api.js'; import { Dict, Str } from '../../../core/common.js'; import { GMAIL_GOOGLE_API_HOST, PEOPLE_GOOGLE_API_HOST } from '../../../core/const.js'; @@ -20,12 +20,12 @@ export class Google { method: ReqMethod, path: string, params: Dict | string | undefined, - progress?: ProgressCbs, + progress?: ProgressCbs | ProgressDestFrame, contentType?: string ): Promise => { progress = progress || {}; let data, url; - if (typeof progress.upload === 'function') { + if ('upload' in progress) { url = `${GMAIL_GOOGLE_API_HOST}/upload/gmail/v1/users/me/${path}?uploadType=multipart`; data = params; } else { @@ -39,8 +39,10 @@ export class Google { contentType = contentType || 'application/json; charset=UTF-8'; // eslint-disable-next-line @typescript-eslint/naming-convention const headers = { Authorization: await GoogleAuth.googleApiAuthHeader(acctEmail) }; - const xhr = Api.getAjaxProgressXhrFactory(progress); - const request = { xhr, url, method, data, headers, crossDomain: true, contentType, async: true }; + const context = + 'frameId' in progress ? { frameId: progress.frameId, expectedTransferSize: progress.expectedTransferSize, tabId: progress.tabId } : undefined; + const xhr = Api.getAjaxProgressXhrFactory('download' in progress || 'upload' in progress ? progress : {}); + const request = { xhr, context, url, method, data, headers, crossDomain: true, contentType, async: true }; return (await GoogleAuth.apiGoogleCallRetryAuthErrorOneTime(acctEmail, request)) as RT; }; @@ -93,11 +95,11 @@ export class Google { // todo - this could probably be achieved with emailjs-mime-builder const boundary = 'the_boundary_is_' + Str.sloppyRandom(10); let body = ''; - for (const type of Object.keys(parts)) { + for (const [type, content] of Object.entries(parts)) { body += '--' + boundary + '\n'; body += 'Content-Type: ' + type + '\n'; if (type.includes('json')) { - body += '\n' + parts[type] + '\n\n'; + body += '\n' + content + '\n\n'; } else { body += 'Content-Transfer-Encoding: base64\n'; body += '\n' + btoa(parts[type]) + '\n\n'; diff --git a/extension/js/common/api/key-server/key-manager.ts b/extension/js/common/api/key-server/key-manager.ts index c4d6430b7f2..27943fcf1d7 100644 --- a/extension/js/common/api/key-server/key-manager.ts +++ b/extension/js/common/api/key-server/key-manager.ts @@ -3,7 +3,7 @@ 'use strict'; import { Api, ReqMethod } from './../shared/api.js'; -import { Dict } from '../../core/common.js'; +import { Dict, Url } from '../../core/common.js'; type LoadPrvRes = { privateKeys: { decryptedPrivateKey: string }[] }; @@ -12,7 +12,7 @@ export class KeyManager extends Api { public constructor(url: string) { super(); - this.url = url.replace(/\/$/, ''); // remove trailing space + this.url = Url.removeTrailingSlash(url); } public getPrivateKeys = async (idToken: string): Promise => { diff --git a/extension/js/common/api/key-server/sks.ts b/extension/js/common/api/key-server/sks.ts index 3bed26eee37..4cdd2bbcf81 100644 --- a/extension/js/common/api/key-server/sks.ts +++ b/extension/js/common/api/key-server/sks.ts @@ -6,6 +6,7 @@ import { Api } from './../shared/api.js'; import { ApiErr } from '../shared/api-error.js'; import { PgpArmor } from '../../core/crypto/pgp/pgp-armor.js'; import { PubkeySearchResult } from './../pub-lookup.js'; +import { Url } from '../../core/common.js'; export class Sks extends Api { private static MR_VERSION_1 = 'info:1:'; @@ -13,7 +14,7 @@ export class Sks extends Api { public constructor(url: string) { super(); - this.url = url.replace(/\/$/, ''); // remove trailing space + this.url = Url.removeTrailingSlash(url); } /** diff --git a/extension/js/common/api/shared/api.ts b/extension/js/common/api/shared/api.ts index 450b69a5759..cd7a5ecd954 100644 --- a/extension/js/common/api/shared/api.ts +++ b/extension/js/common/api/shared/api.ts @@ -25,6 +25,8 @@ type RawAjaxErr = { status?: number; statusText?: string; }; +export type ProgressDestFrame = { frameId: string; expectedTransferSize: number; tabId?: string }; +export type ApiCallContext = ProgressDestFrame | undefined; export type ChunkedCb = (r: ProviderContactsResults) => Promise; export type ProgressCb = (percent: number | undefined, loaded: number, total: number) => void; @@ -58,7 +60,7 @@ export class Api { }); }; - public static ajax = async (req: JQueryAjaxSettings, stack: string): Promise> => { + public static ajax = async (req: JQuery.AjaxSettings, stack: string): Promise> => { if (Env.isContentScript()) { // content script CORS not allowed anymore, have to drag it through background page // https://www.chromestatus.com/feature/5629709824032768 @@ -104,8 +106,8 @@ export class Api { } }; - public static getAjaxProgressXhrFactory = (progressCbs?: ProgressCbs): (() => XMLHttpRequest) | undefined => { - if (Env.isContentScript() || Env.isBackgroundPage() || !progressCbs || !Object.keys(progressCbs).length) { + public static getAjaxProgressXhrFactory = (progressCbs: ProgressCbs | undefined): (() => XMLHttpRequest) | undefined => { + if (Env.isContentScript() || !progressCbs || !(progressCbs.upload || progressCbs.download)) { // xhr object would cause 'The object could not be cloned.' lastError during BrowserMsg passing // thus no progress callbacks in bg or content scripts // additionally no need to create this if there are no progressCbs defined @@ -191,7 +193,7 @@ export class Api { } else { throw new Error('unknown format:' + String(fmt)); } - const req: JQueryAjaxSettings = { + const req: JQuery.AjaxSettings = { xhr: Api.getAjaxProgressXhrFactory(progress), url: url + path, method, diff --git a/extension/js/common/browser/browser-msg.ts b/extension/js/common/browser/browser-msg.ts index 42e0e3959a6..cf9b99bc78f 100644 --- a/extension/js/common/browser/browser-msg.ts +++ b/extension/js/common/browser/browser-msg.ts @@ -3,21 +3,22 @@ 'use strict'; import { AuthRes } from '../api/email-provider/gmail/google-auth.js'; +import { ApiCallContext } from '../api/shared/api.js'; import { AjaxErr } from '../api/shared/api-error.js'; import { Buf } from '../core/buf.js'; import { Dict, Str, UrlParams } from '../core/common.js'; import { ArmoredKeyIdentityWithEmails, KeyUtil } from '../core/crypto/key.js'; -import { DecryptResult, DiagnoseMsgPubkeysResult, MsgUtil, PgpMsgMethod, PgpMsgTypeResult, VerifyRes } from '../core/crypto/pgp/msg-util.js'; +import { DecryptResult, MsgUtil, PgpMsgMethod } from '../core/crypto/pgp/msg-util.js'; import { NotificationGroupType } from '../notifications.js'; import { Catch } from '../platform/catch.js'; import { AccountIndex, AcctStoreDict } from '../platform/store/acct-store.js'; import { GlobalIndex, GlobalStoreDict } from '../platform/store/global-store.js'; -import { saveFetchedPubkeysIfNewerThanInStorage } from '../shared.js'; import { PassphraseDialogType } from '../xss-safe-factory.js'; import { BrowserMsgCommonHandlers } from './browser-msg-common-handlers.js'; import { Browser } from './browser.js'; import { Env } from './env.js'; import { Time } from './time.js'; +import { RenderMessageWithFrameId } from '../render-message.js'; export type GoogleAuthWindowResult$result = 'Success' | 'Denied' | 'Error' | 'Closed'; @@ -75,16 +76,13 @@ export namespace Bm { export type StoreAcctSet = { acctEmail: string; values: AcctStoreDict }; export type ReconnectAcctAuthPopup = { acctEmail: string; scopes?: string[] }; export type PgpMsgDecrypt = PgpMsgMethod.Arg.Decrypt; - export type PgpMsgDiagnoseMsgPubkeys = PgpMsgMethod.Arg.DiagnosePubkeys; - export type PgpMsgVerifyDetached = PgpMsgMethod.Arg.VerifyDetached; - export type PgpMsgType = PgpMsgMethod.Arg.Type; export type PgpKeyBinaryToArmored = { binaryKeysData: Uint8Array }; - export type Ajax = { req: JQueryAjaxSettings; stack: string }; + export type Ajax = { req: JQuery.AjaxSettings; stack: string }; + export type AjaxProgress = { frameId: string; percent?: number; loaded: number; total: number; expectedTransferSize: number }; export type AjaxGmailAttachmentGetChunk = { acctEmail: string; msgId: string; attachmentId: string }; export type ShowAttachmentPreview = { iframeUrl: string }; export type ShowConfirmation = { text: string; isHTML: boolean; footer?: string }; export type ReRenderRecipient = { email: string }; - export type SaveFetchedPubkeys = { email: string; pubkeys: string[] }; export type ShowConfirmationResult = { isConfirmed: boolean }; export namespace Res { @@ -101,13 +99,9 @@ export namespace Bm { export type StoreAcctSet = void; export type ReconnectAcctAuthPopup = AuthRes; export type PgpMsgDecrypt = DecryptResult; - export type PgpMsgDiagnoseMsgPubkeys = DiagnoseMsgPubkeysResult; - export type PgpMsgVerify = VerifyRes; - export type PgpMsgType = PgpMsgTypeResult; export type PgpKeyBinaryToArmored = { keys: ArmoredKeyIdentityWithEmails[] }; export type AjaxGmailAttachmentGetChunk = { chunk: Buf }; export type _tab_ = { tabId: string | null | undefined }; // eslint-disable-line @typescript-eslint/naming-convention - export type SaveFetchedPubkeys = boolean; export type ShowConfirmationResult = boolean; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type Db = any; // not included in Any below @@ -119,9 +113,6 @@ export namespace Bm { | _tab_ | ReconnectAcctAuthPopup | PgpMsgDecrypt - | PgpMsgDiagnoseMsgPubkeys - | PgpMsgVerify - | PgpMsgType | InMemoryStoreGet | InMemoryStoreSet | StoreAcctGet @@ -129,7 +120,6 @@ export namespace Bm { | StoreGlobalGet | StoreGlobalSet | AjaxGmailAttachmentGetChunk - | SaveFetchedPubkeys | PgpKeyBinaryToArmored; } @@ -163,14 +153,10 @@ export namespace Bm { | StoreAcctGet | StoreAcctSet | PgpMsgDecrypt - | PgpMsgDiagnoseMsgPubkeys - | PgpMsgVerifyDetached - | PgpMsgType | Ajax | ShowAttachmentPreview | ShowConfirmation | ReRenderRecipient - | SaveFetchedPubkeys | PgpKeyBinaryToArmored | AuthWindowResult | ConfirmationResult; @@ -228,16 +214,9 @@ export class BrowserMsg { ajax: (bm: Bm.Ajax): Promise => BrowserMsg.sendAwait(undefined, 'ajax', bm, true) as Promise, ajaxGmailAttachmentGetChunk: (bm: Bm.AjaxGmailAttachmentGetChunk) => BrowserMsg.sendAwait(undefined, 'ajaxGmailAttachmentGetChunk', bm, true) as Promise, - pgpMsgDiagnosePubkeys: (bm: Bm.PgpMsgDiagnoseMsgPubkeys) => - BrowserMsg.sendAwait(undefined, 'pgpMsgDiagnosePubkeys', bm, true) as Promise, pgpMsgDecrypt: (bm: Bm.PgpMsgDecrypt) => BrowserMsg.sendAwait(undefined, 'pgpMsgDecrypt', bm, true) as Promise, - pgpMsgVerifyDetached: (bm: Bm.PgpMsgVerifyDetached) => - BrowserMsg.sendAwait(undefined, 'pgpMsgVerifyDetached', bm, true) as Promise, - pgpMsgType: (bm: Bm.PgpMsgType) => BrowserMsg.sendAwait(undefined, 'pgpMsgType', bm, true) as Promise, pgpKeyBinaryToArmored: (bm: Bm.PgpKeyBinaryToArmored) => BrowserMsg.sendAwait(undefined, 'pgpKeyBinaryToArmored', bm, true) as Promise, - saveFetchedPubkeys: (bm: Bm.SaveFetchedPubkeys) => - BrowserMsg.sendAwait(undefined, 'saveFetchedPubkeys', bm, true) as Promise, }, }, confirmationResult: (dest: Bm.Dest, bm: Bm.ConfirmationResult) => BrowserMsg.sendCatch(dest, 'confirmation_result', bm), @@ -272,6 +251,8 @@ export class BrowserMsg { addToContacts: (dest: Bm.Dest) => BrowserMsg.sendCatch(dest, 'addToContacts', {}), reRenderRecipient: (dest: Bm.Dest, bm: Bm.ReRenderRecipient) => BrowserMsg.sendCatch(dest, 'reRenderRecipient', bm), showAttachmentPreview: (dest: Bm.Dest, bm: Bm.ShowAttachmentPreview) => BrowserMsg.sendCatch(dest, 'show_attachment_preview', bm), + ajaxProgress: (dest: Bm.Dest, bm: Bm.AjaxProgress) => BrowserMsg.sendCatch(dest, 'ajax_progress', bm), + pgpBlockRender: (dest: Bm.Dest, bm: RenderMessageWithFrameId) => BrowserMsg.sendCatch(dest, 'pgp_block_render', bm), }; /* eslint-disable @typescript-eslint/naming-convention */ private static HANDLERS_REGISTERED_BACKGROUND: Handlers = {}; @@ -334,11 +315,7 @@ export class BrowserMsg { }; public static addPgpListeners = () => { - BrowserMsg.bgAddListener('pgpMsgDiagnosePubkeys', MsgUtil.diagnosePubkeys); BrowserMsg.bgAddListener('pgpMsgDecrypt', MsgUtil.decryptMessage); - BrowserMsg.bgAddListener('pgpMsgVerifyDetached', MsgUtil.verifyDetached); - BrowserMsg.bgAddListener('pgpMsgType', async (r: Bm.PgpMsgType) => MsgUtil.type(r)); - BrowserMsg.bgAddListener('saveFetchedPubkeys', saveFetchedPubkeysIfNewerThanInStorage); BrowserMsg.bgAddListener('pgpKeyBinaryToArmored', async (r: Bm.PgpKeyBinaryToArmored) => ({ keys: await KeyUtil.parseAndArmorKeys(r.binaryKeysData), })); diff --git a/extension/js/common/browser/env.ts b/extension/js/common/browser/env.ts index 8646daffd40..730c8590902 100644 --- a/extension/js/common/browser/env.ts +++ b/extension/js/common/browser/env.ts @@ -5,6 +5,8 @@ 'use strict'; +import { Url } from '../core/common.js'; + export type WebMailName = 'gmail' | 'outlook' | 'settings'; export type WebMailVersion = 'generic' | 'gmail2020' | 'gmail2022'; @@ -20,6 +22,11 @@ export class Env { return undefined; }; + public static getExtensionOrigin = () => { + const url = chrome.runtime.getURL(''); + return Url.removeTrailingSlash(url); + }; + public static isContentScript = () => { return Env.isExtension() && window.location.href.indexOf(chrome.runtime.getURL('')) === -1; // extension but not on its own url }; diff --git a/extension/js/common/core/attachment.ts b/extension/js/common/core/attachment.ts index 3f07c47d281..bd62891acc7 100644 --- a/extension/js/common/core/attachment.ts +++ b/extension/js/common/core/attachment.ts @@ -5,28 +5,41 @@ import { Buf } from './buf.js'; import { Str } from './common.js'; -type Attachment$treatAs = 'publicKey' | 'privateKey' | 'encryptedMsg' | 'hidden' | 'signature' | 'encryptedFile' | 'plainFile' | 'inlineImage'; +export type Attachment$treatAs = + | 'publicKey' + | 'privateKey' + | 'encryptedMsg' /* may be signed-only (known as 'signedMsg' in MsgBlockType) as well, + should probably be renamed to 'cryptoMsg' to not be confused with 'encryptedMsg' in MsgBlockType */ + | 'hidden' + | 'signature' + | 'encryptedFile' + | 'plainFile' + | 'inlineImage' + | 'needChunk' + | 'maybePgp'; type ContentTransferEncoding = '7bit' | 'quoted-printable' | 'base64'; -export type AttachmentMeta = { - data?: Uint8Array; +export type AttachmentId = { id: string; msgId: string } | { url: string }; // a way to extract data +export type AttachmentProperties = { type?: string; name?: string; length?: number; - url?: string; inline?: boolean; - id?: string; - msgId?: string; treatAs?: Attachment$treatAs; cid?: string; contentDescription?: string; contentTransferEncoding?: ContentTransferEncoding; }; +export type AttachmentMeta = (AttachmentId | { data: Uint8Array }) & AttachmentProperties; export type FcAttachmentLinkData = { name: string; type: string; size: number }; +export type TransferableAttachment = (AttachmentId | { data: /* base64 see #2587 */ string }) & AttachmentProperties; + export class Attachment { + // Regex to trigger message download and processing based on attachment file names + // todo: it'd be better to compile this regex based on the data we have in `treatAs` method public static readonly webmailNamePattern = - /^(((cryptup|flowcrypt)-backup-[a-z0-9]+\.(key|asc))|(.+\.pgp)|(.+\.gpg)|(.+\.asc)|(noname)|(message)|(PGPMIME version identification)|(ATT[0-9]{5})|())$/m; + /^(((cryptup|flowcrypt)-backup-[a-z0-9]+\.(key|asc))|(.+\.pgp)|(.+\.gpg)|(.+\.asc)|(OpenPGP_signature(.asc)?)|(noname)|(message)|(PGPMIME version identification)|(ATT[0-9]{5})|())$/m; public static readonly encryptedMsgNames = ['msg.asc', 'message.asc', 'encrypted.asc', 'encrypted.eml.pgp', 'Message.pgp', 'openpgp-encrypted-message.asc']; public length = NaN; @@ -43,29 +56,23 @@ export class Attachment { private bytes: Uint8Array | undefined; private treatAsValue: Attachment$treatAs | undefined; // this field is to disable on-the-fly detection by this.treatAs() - public constructor({ data, type, name, length, url, inline, id, msgId, treatAs, cid, contentDescription, contentTransferEncoding }: AttachmentMeta) { - if (typeof data === 'undefined' && typeof url === 'undefined' && typeof id === 'undefined') { - throw new Error('Attachment: one of data|url|id has to be set'); - } - if (id && !msgId) { - throw new Error('Attachment: if id is set, msgId must be set too'); - } - if (data) { - this.bytes = data; - this.length = data.length; + public constructor(attachmentMeta: AttachmentMeta) { + if ('data' in attachmentMeta) { + this.bytes = attachmentMeta.data; + this.length = attachmentMeta.data.length; } else { - this.length = Number(length); + this.length = Number(attachmentMeta.length); } - this.name = name || ''; - this.type = type || 'application/octet-stream'; - this.url = url || undefined; - this.inline = !!inline; - this.id = id || undefined; - this.msgId = msgId || undefined; - this.treatAsValue = treatAs || undefined; - this.cid = cid || undefined; - this.contentDescription = contentDescription || undefined; - this.contentTransferEncoding = contentTransferEncoding || undefined; + this.name = attachmentMeta.name || ''; + this.type = attachmentMeta.type || 'application/octet-stream'; + this.url = 'url' in attachmentMeta ? attachmentMeta.url : undefined; + this.inline = !!attachmentMeta.inline; + this.id = 'id' in attachmentMeta ? attachmentMeta.id : undefined; + this.msgId = 'msgId' in attachmentMeta ? attachmentMeta.msgId : undefined; + this.treatAsValue = attachmentMeta.treatAs; + this.cid = attachmentMeta.cid; + this.contentDescription = attachmentMeta.contentDescription; + this.contentTransferEncoding = attachmentMeta.contentTransferEncoding; } public static treatAsForPgpEncryptedAttachments = (mimeType: string | undefined, pgpEncryptedIndex: number | undefined) => { @@ -101,6 +108,29 @@ export class Attachment { return `f_${Str.sloppyRandom(30)}@flowcrypt`; }; + public static toTransferableAttachment = (attachmentMeta: AttachmentMeta): TransferableAttachment => { + return 'data' in attachmentMeta + ? { + ...attachmentMeta, + data: Buf.fromUint8(attachmentMeta.data).toBase64Str(), // should we better convert to url? + } + : attachmentMeta; + }; + + public static fromTransferableAttachment = (t: TransferableAttachment): Attachment => { + return new Attachment( + 'data' in t + ? { + ...t, + data: Buf.fromBase64Str(t.data), + } + : t + ); + }; + + /** @deprecated should be made private + * + */ public isPublicKey = (): boolean => { if (this.treatAsValue) { return this.treatAsValue === 'publicKey'; @@ -173,9 +203,13 @@ export class Attachment { return 'publicKey'; } else if (this.name.match(/(cryptup|flowcrypt)-backup-[a-z0-9]+\.(key|asc)$/g)) { return 'privateKey'; - } else if (this.name.match(/\.asc$/) && this.length < 100000 && !this.inline) { - return 'encryptedMsg'; } else { + // && !Attachment.encryptedMsgNames.includes(this.name) -- already checked above + const isAmbiguousAscFile = /\.asc$/.test(this.name); // ambiguous .asc name + const isAmbiguousNonameFile = !this.name || this.name === 'noname'; // may not even be OpenPGP related + if (!this.inline && this.length < 100000 && (isAmbiguousAscFile || isAmbiguousNonameFile)) { + return this.hasData() ? 'maybePgp' : 'needChunk'; + } return 'plainFile'; } }; diff --git a/extension/js/common/core/common.ts b/extension/js/common/core/common.ts index 73fe5206f83..7183a0fe503 100644 --- a/extension/js/common/core/common.ts +++ b/extension/js/common/core/common.ts @@ -366,6 +366,10 @@ export class Url { return `${urlParts[0]}?${params.toString()}`; }; + public static removeTrailingSlash = (url: string) => { + return url.replace(/\/$/, ''); + }; + public static replaceUrlParam = (url: string, key: string, value: string) => { const regex = new RegExp(`([?|&]${key}=).*?(&|$)`, 'i'); return url.replace(regex, '$1' + value + '$2'); diff --git a/extension/js/common/core/crypto/pgp/msg-util.ts b/extension/js/common/core/crypto/pgp/msg-util.ts index 64bd17385fe..d5c4503af1e 100644 --- a/extension/js/common/core/crypto/pgp/msg-util.ts +++ b/extension/js/common/core/crypto/pgp/msg-util.ts @@ -2,7 +2,7 @@ 'use strict'; import { Key, KeyInfoWithIdentity, KeyInfoWithIdentityAndOptionalPp, KeyUtil } from '../key.js'; -import { MsgBlockType, ReplaceableMsgBlockType } from '../../msg-block.js'; +import { ReplaceableMsgBlockType } from '../../msg-block.js'; import { Buf } from '../../buf.js'; import { PgpArmor, PreparedForDecrypt } from './pgp-armor.js'; import { opgp } from './openpgpjs-custom.js'; @@ -34,7 +34,7 @@ export namespace PgpMsgMethod { armor: boolean; date?: Date; }; - export type Type = { data: Uint8Array | string }; + export type Type = { data: Uint8Array }; export type Decrypt = { kisWithPp: KeyInfoWithIdentityAndOptionalPp[]; encryptedData: Uint8Array | string; @@ -46,7 +46,7 @@ export namespace PgpMsgMethod { } export type DiagnosePubkeys = (arg: Arg.DiagnosePubkeys) => Promise; export type VerifyDetached = (arg: Arg.VerifyDetached) => Promise; - export type Decrypt = (arg: Arg.Decrypt) => Promise; + export type Decrypt = (arg: Arg.Decrypt) => Promise; export type Type = (arg: Arg.Type) => PgpMsgTypeResult; export type Encrypt = (arg: Arg.Encrypt) => Promise; export type EncryptResult = EncryptPgpResult | EncryptX509Result; @@ -95,7 +95,7 @@ export type VerifyRes = { isErrFatal?: boolean; content?: Buf; }; -export type PgpMsgTypeResult = { armored: boolean; type: MsgBlockType } | undefined; +export type PgpMsgTypeResult = { armored: boolean; type: ReplaceableMsgBlockType } | undefined; export type DecryptResult = DecryptSuccess | DecryptError; export type DiagnoseMsgPubkeysResult = { found_match: boolean; receivers: number }; // eslint-disable-line @typescript-eslint/naming-convention export enum DecryptErrTypes { @@ -106,28 +106,15 @@ export enum DecryptErrTypes { badMdc = 'bad_mdc', needPassphrase = 'need_passphrase', format = 'format', + armorChecksumFailed = 'armor_checksum_failed', other = 'other', } -export class FormatError extends Error { - public data: string; - public constructor(message: string, data: string) { - super(message); - this.data = data; - } -} - export class MsgUtil { public static type: PgpMsgMethod.Type = ({ data }) => { if (!data || !data.length) { return undefined; } - if (typeof data === 'string') { - // Uint8Array sent over BrowserMsg gets converted to blobs on the sending side, and read on the receiving side - // Firefox blocks such blobs from content scripts to background, see: https://github.com/FlowCrypt/flowcrypt-browser/issues/2587 - // that's why we add an option to send data as a base64 formatted string - data = Buf.fromBase64Str(data); - } const firstByte = data[0]; // attempt to understand this as a binary PGP packet: https://tools.ietf.org/html/rfc4880#section-4.2 if ((firstByte & 0b10000000) === 0b10000000) { @@ -177,7 +164,17 @@ export class MsgUtil { public static verifyDetached: PgpMsgMethod.VerifyDetached = async ({ plaintext, sigText, verificationPubs }) => { const message = await opgp.createMessage({ text: Str.with(plaintext) }); - await message.appendSignature(sigText); + try { + await message.appendSignature(sigText); + } catch (formatErr) { + return { + match: null, // eslint-disable-line no-null/no-null + signerLongids: [], + suppliedLongids: [], + error: String(formatErr).replace('Error: ', ''), + isErrFatal: true, + }; + } return await OpenPGPKey.verify(message, await ContactStore.getPubkeyInfos(undefined, verificationPubs)); }; @@ -187,7 +184,7 @@ export class MsgUtil { try { prepared = await PgpArmor.cryptoMsgPrepareForDecrypt(encryptedData); } catch (formatErr) { - return { success: false, error: { type: DecryptErrTypes.format, message: String(formatErr) }, longids }; + return { success: false, error: MsgUtil.cryptoMsgDecryptCategorizeErr(formatErr), longids }; } // there are 3 types of messages possible at this point // 1. PKCS#7 if isPkcs7 is true @@ -435,6 +432,11 @@ export class MsgUtil { type: DecryptErrTypes.badMdc, message: `Security threat - opening this message is dangerous because it was modified in transit.`, }; + } else if (e === 'Ascii armor integrity check failed') { + return { + type: DecryptErrTypes.armorChecksumFailed, + message: e, + }; } else { return { type: DecryptErrTypes.other, message: e }; } diff --git a/extension/js/common/core/expiration-cache.ts b/extension/js/common/core/expiration-cache.ts index 0bf762d859c..7408adecac1 100644 --- a/extension/js/common/core/expiration-cache.ts +++ b/extension/js/common/core/expiration-cache.ts @@ -3,36 +3,53 @@ /** * Cache, keeping entries for limited duration */ -export class ExpirationCache { - private cache: { [key: string]: { value: string; expiration: number } } = {}; +export class ExpirationCache { + private cache = new Map(); // eslint-disable-next-line @typescript-eslint/naming-convention public constructor(public EXPIRATION_TICKS: number) {} - public set = (key: string, value?: string, expiration?: number) => { + public set = (key: K, value?: V, expiration?: number) => { if (value) { - this.cache[key] = { value, expiration: expiration || Date.now() + this.EXPIRATION_TICKS }; + this.cache.set(key, { value, expiration: expiration || Date.now() + this.EXPIRATION_TICKS }); } else { - delete this.cache[key]; + this.cache.delete(key); } }; - public get = (key: string): string | undefined => { - const found = this.cache[key]; + public get = (key: K): V | undefined => { + const found = this.cache.get(key); if (found) { if (found.expiration > Date.now()) { return found.value; } else { // expired, so delete it and return as if not found - delete this.cache[key]; + this.cache.delete(key); } } return undefined; }; - public deleteExpired = (): void => { - for (const keyToDelete of Object.keys(this.cache).filter(key => this.cache[key].expiration <= Date.now())) { - delete this.cache[keyToDelete]; + public deleteExpired = (additionalPredicate: (key: K, value: V) => boolean = () => false): void => { + const keysToDelete: K[] = []; + for (const [key, value] of this.cache.entries()) { + if (value.expiration <= Date.now() || additionalPredicate(key, value.value)) { + keysToDelete.push(key); + } + } + for (const key of keysToDelete) { + this.cache.delete(key); + } + }; + + // await the value if it's a promise and remove from cache in case of exception + // the value is provided along with the key as parameter to eliminate possibility of a missing (expired) record + public await = async (key: K, value: V): Promise => { + try { + return await value; + } catch (e) { + if (this.get(key) === value) this.set(key); // remove faulty record + return Promise.reject(e); } }; } diff --git a/extension/js/common/core/mime.ts b/extension/js/common/core/mime.ts index 5d32488d262..efc57749f58 100644 --- a/extension/js/common/core/mime.ts +++ b/extension/js/common/core/mime.ts @@ -22,17 +22,24 @@ const Iso88592 = requireIso88592(); type AddressHeader = { address: string; name: string }; type MimeContentHeader = string | AddressHeader[]; -export type MimeContent = { - headers: Dict; - attachments: Attachment[]; - rawSignedContent?: string; - subject?: string; + +export type MessageBody = { html?: string; text?: string; - from?: string; +}; + +export type MimeContent = MessageBody & { + attachments: Attachment[]; // attachments in MimeContent are parsed from a raw MIME message and always have data + rawSignedContent?: string; + subject?: string; +}; + +export type MimeContentWithHeaders = MimeContent & { + headers: Dict; to: string[]; cc: string[]; bcc: string[]; + from?: string; }; export type MimeEncodeType = 'pgpMimeEncrypted' | 'pgpMimeSigned' | 'smimeEncrypted' | 'smimeSigned' | undefined; @@ -44,21 +51,19 @@ export type SendableMsgBody = { 'text/html'?: string; 'pkcs7/buf'?: Buf; // DER-encoded PKCS#7 message }; -/* eslint-enable @typescript-eslint/naming-convention */ + export type MimeProccesedMsg = { - rawSignedContent: string | undefined; - headers: Dict; - blocks: MsgBlock[]; - from: string | undefined; - to: string[]; + rawSignedContent: string | undefined; // undefined if format was 'full' + blocks: MsgBlock[]; // may be many blocks per file }; + type SendingType = 'to' | 'cc' | 'bcc'; export class Mime { - public static processDecoded = (decoded: MimeContent): MimeProccesedMsg => { + public static processBody = (decoded: MessageBody): MsgBlock[] => { const blocks: MsgBlock[] = []; if (decoded.text) { - const blocksFromTextPart = MsgBlockParser.detectBlocks(Str.normalize(decoded.text)).blocks; + const blocksFromTextPart = MsgBlockParser.detectBlocks(Str.normalize(decoded.text), true).blocks; // if there are some encryption-related blocks found in the text section, which we can use, and not look at the html section if (blocksFromTextPart.find(b => ['pkcs7', 'encryptedMsg', 'signedMsg', 'publicKey', 'privateKey'].includes(b.type))) { blocks.push(...blocksFromTextPart); // because the html most likely containt the same thing, just harder to parse pgp sections cause it's html @@ -72,23 +77,42 @@ export class Mime { } else if (decoded.html) { blocks.push(MsgBlock.fromContent('plainHtml', decoded.html)); } + return blocks; + }; + + public static isBodyEmpty = ({ text, html }: MessageBody) => { + return Mime.isBodyTextEmpty(text) && Mime.isBodyTextEmpty(html); + }; + + public static isBodyTextEmpty = (text: string | undefined) => { + return !(text && !/^(\r)?(\n)?$/.test(text)); + }; + + public static processAttachments = (bodyBlocks: MsgBlock[], decoded: MimeContent): MimeProccesedMsg => { + const attachmentBlocks: MsgBlock[] = []; const signatureAttachments: Attachment[] = []; for (const file of decoded.attachments) { - const isBodyEmpty = decoded.text === '' || decoded.text === '\n'; - const treatAs = file.treatAs(decoded.attachments, isBodyEmpty); + let treatAs = file.treatAs(decoded.attachments, Mime.isBodyEmpty(decoded)); + if (['needChunk', 'maybePgp'].includes(treatAs)) { + // todo: attachments from MimeContent always have data set (so 'needChunk' should never happen), + // and we can perform whatever analysis is needed based on the actual data, + // but we don't want to reference MsgUtil and OpenPGP.js from this class, + // so I suggest to move this method to MessageRenderer for further refactoring + treatAs = 'encryptedMsg'; // publicKey? + } if (treatAs === 'encryptedMsg') { const armored = PgpArmor.clip(file.getData().toUtfStr()); if (armored) { - blocks.push(MsgBlock.fromContent('encryptedMsg', armored)); + attachmentBlocks.push(MsgBlock.fromContent('encryptedMsg', armored)); } } else if (treatAs === 'signature') { signatureAttachments.push(file); } else if (treatAs === 'publicKey') { - blocks.push(...MsgBlockParser.detectBlocks(file.getData().toUtfStr()).blocks); + attachmentBlocks.push(...MsgBlockParser.detectBlocks(file.getData().toUtfStr(), true).blocks); // todo: test when more than one } else if (treatAs === 'privateKey') { - blocks.push(...MsgBlockParser.detectBlocks(file.getData().toUtfStr()).blocks); + attachmentBlocks.push(...MsgBlockParser.detectBlocks(file.getData().toUtfStr(), true).blocks); // todo: test when more than one } else if (treatAs === 'encryptedFile') { - blocks.push( + attachmentBlocks.push( MsgBlock.fromAttachment('encryptedAttachment', '', { name: file.name, type: file.type, @@ -97,7 +121,7 @@ export class Mime { }) ); } else if (treatAs === 'plainFile') { - blocks.push( + attachmentBlocks.push( MsgBlock.fromAttachment('plainAttachment', '', { name: file.name, type: file.type, @@ -111,39 +135,27 @@ export class Mime { } if (signatureAttachments.length) { // todo: if multiple signatures, figure out which fits what + // attachments from MimeContent always have data set const signature = signatureAttachments[0].getData().toUtfStr(); - for (const block of blocks) { - if (block.type === 'plainText') { - block.type = 'signedText'; - block.signature = signature; - } else if (block.type === 'plainHtml') { - block.type = 'signedHtml'; - block.signature = signature; - } - } - if (!blocks.find(block => ['plainText', 'plainHtml', 'signedMsg', 'signedHtml', 'signedText'].includes(block.type))) { + if (![...bodyBlocks, ...attachmentBlocks].some(block => ['plainText', 'plainHtml', 'signedMsg'].includes(block.type))) { // signed an empty message - blocks.push(new MsgBlock('signedMsg', '', true, signature)); + attachmentBlocks.push(new MsgBlock('signedMsg', '', true, signature)); } } return { - headers: decoded.headers, - blocks, - from: decoded.from, - to: decoded.to, + blocks: [...bodyBlocks, ...attachmentBlocks], rawSignedContent: decoded.rawSignedContent, }; }; - public static process = async (mimeMsg: Uint8Array): Promise => { - const decoded = await Mime.decode(mimeMsg); - return Mime.processDecoded(decoded); + public static processDecoded = (decoded: MimeContent): MimeProccesedMsg => { + const bodyBlocks = Mime.processBody(decoded); + return Mime.processAttachments(bodyBlocks, decoded); }; - public static replyHeaders = (parsedMimeMsg: MimeContent) => { - const msgId = String(parsedMimeMsg.headers['message-id'] || ''); - const refs = String(parsedMimeMsg.headers['in-reply-to'] || ''); - return { 'in-reply-to': msgId, references: refs + ' ' + msgId }; + public static process = async (mimeMsg: Uint8Array) => { + const decoded = await Mime.decode(mimeMsg); + return Mime.processDecoded(decoded); }; public static resemblesMsg = (msg: Uint8Array | string) => { @@ -168,8 +180,8 @@ export class Mime { return contentType.index === 0; }; - public static decode = async (mimeMsg: Uint8Array | string): Promise => { - let mimeContent: MimeContent = { + public static decode = async (mimeMsg: Uint8Array | string): Promise => { + let mimeContent: MimeContentWithHeaders = { attachments: [], headers: {}, subject: undefined, @@ -329,7 +341,7 @@ export class Mime { return pgpMimeSigned; }; - private static headerGetAddress = (parsedMimeMsg: MimeContent, headersNames: Array) => { + private static headerGetAddress = (parsedMimeMsg: MimeContentWithHeaders, headersNames: Array) => { const result: { to: string[]; cc: string[]; bcc: string[] } = { to: [], cc: [], bcc: [] }; let from: string | undefined; const getHdrValAsArr = (hdr: MimeContentHeader) => diff --git a/extension/js/common/core/msg-block-parser.ts b/extension/js/common/core/msg-block-parser.ts index f8200371c60..aa1a294237d 100644 --- a/extension/js/common/core/msg-block-parser.ts +++ b/extension/js/common/core/msg-block-parser.ts @@ -23,12 +23,12 @@ type SanitizedBlocks = { export class MsgBlockParser { private static ARMOR_HEADER_MAX_LENGTH = 50; - public static detectBlocks = (origText: string) => { + public static detectBlocks = (origText: string, completeOnly?: boolean) => { const blocks: MsgBlock[] = []; const normalized = Str.normalize(origText); let startAt = 0; while (true) { - const { found, continueAt } = MsgBlockParser.detectBlockNext(normalized, startAt); + const { found, continueAt } = MsgBlockParser.detectBlockNext(normalized, startAt, completeOnly); if (found) { blocks.push(...found); } @@ -165,7 +165,7 @@ export class MsgBlockParser { ); }; - private static detectBlockNext = (origText: string, startAt: number) => { + private static detectBlockNext = (origText: string, startAt: number, completeOnly?: boolean) => { const armorHdrTypes = Object.keys(PgpArmor.ARMOR_HEADER_DICT) as ReplaceableMsgBlockType[]; const result: { found: MsgBlock[]; continueAt?: number } = { found: [] as MsgBlock[] }; const begin = origText.indexOf(PgpArmor.headers('null').begin, startAt); @@ -177,8 +177,9 @@ export class MsgBlockParser { if (blockHeaderDef.replace) { const indexOfConfirmedBegin = potentialBeginHeader.indexOf(blockHeaderDef.begin); if (indexOfConfirmedBegin === 0) { + let potentialTextBeforeBlockBegun = ''; if (begin > startAt) { - let potentialTextBeforeBlockBegun = origText.substring(startAt, begin); + potentialTextBeforeBlockBegun = origText.substring(startAt, begin); if (!potentialTextBeforeBlockBegun.endsWith('\n')) { // only replace blocks if they begin on their own line // contains deliberate block: `-----BEGIN PGP PUBLIC KEY BLOCK-----\n...` @@ -188,10 +189,6 @@ export class MsgBlockParser { // this will actually cause potential deliberate blocks that follow accidental block to be ignored // but if the message already contains accidental (not on dedicated line) blocks, it's probably a good thing to ignore the rest } - potentialTextBeforeBlockBegun = potentialTextBeforeBlockBegun.trim(); - if (potentialTextBeforeBlockBegun) { - result.found.push(MsgBlock.fromContent('plainText', potentialTextBeforeBlockBegun)); - } } let endIndex = -1; let foundBlockEndHeaderLength = 0; @@ -207,15 +204,21 @@ export class MsgBlockParser { foundBlockEndHeaderLength = matchEnd[0].length; } } - if (endIndex !== -1) { - // identified end of the same block - result.found.push(MsgBlock.fromContent(armorHdrType, origText.substring(begin, endIndex + foundBlockEndHeaderLength).trim())); - result.continueAt = endIndex + foundBlockEndHeaderLength; - } else { - // corresponding end not found - result.found.push(MsgBlock.fromContent(armorHdrType, origText.substr(begin), true)); + if (endIndex !== -1 || !completeOnly) { + // flush the preceding plainText + potentialTextBeforeBlockBegun = potentialTextBeforeBlockBegun.trim(); + if (potentialTextBeforeBlockBegun) { + result.found.push(MsgBlock.fromContent('plainText', potentialTextBeforeBlockBegun)); + } + if (endIndex !== -1) { + // identified end of the same block + result.found.push(MsgBlock.fromContent(armorHdrType, origText.substring(begin, endIndex + foundBlockEndHeaderLength).trim())); + result.continueAt = endIndex + foundBlockEndHeaderLength; + } else { + result.found.push(MsgBlock.fromContent(armorHdrType, origText.substr(begin), true)); + } + break; } - break; } } } diff --git a/extension/js/common/core/msg-block.ts b/extension/js/common/core/msg-block.ts index 7a5a2057475..52c2251d4dd 100644 --- a/extension/js/common/core/msg-block.ts +++ b/extension/js/common/core/msg-block.ts @@ -12,7 +12,6 @@ export type ReplaceableMsgBlockType = KeyBlockType | 'signedMsg' | 'encryptedMsg export type MsgBlockType = | ReplaceableMsgBlockType | 'plainText' - | 'signedText' | 'plainHtml' | 'decryptedHtml' | 'plainAttachment' @@ -20,8 +19,7 @@ export type MsgBlockType = | 'decryptedAttachment' | 'encryptedAttachmentLink' | 'decryptErr' - | 'verifiedMsg' - | 'signedHtml'; + | 'verifiedMsg'; export class MsgBlock { public constructor( diff --git a/extension/js/common/downloader.ts b/extension/js/common/downloader.ts new file mode 100644 index 00000000000..9cbfee6f74b --- /dev/null +++ b/extension/js/common/downloader.ts @@ -0,0 +1,61 @@ +/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ + +'use strict'; + +import { GmailRes } from './api/email-provider/gmail/gmail-parser.js'; +import { Gmail } from './api/email-provider/gmail/gmail.js'; +import { Attachment } from './core/attachment.js'; +import { Buf } from './core/buf.js'; +import { ExpirationCache } from './core/expiration-cache.js'; + +export class Downloader { + private readonly chunkDownloads = new ExpirationCache>(2 * 60 * 60 * 1000); // 2 hours + private readonly fullMessages = new ExpirationCache>(24 * 60 * 60 * 1000); // 24 hours + private readonly rawMessages = new ExpirationCache>(24 * 60 * 60 * 1000); // 24 hours + + public constructor(private readonly gmail: Gmail) {} + + public deleteExpired = (): void => { + this.fullMessages.deleteExpired(); + this.rawMessages.deleteExpired(); + this.chunkDownloads.deleteExpired(attachment => { + return attachment.hasData(); + }); + }; + + public queueAttachmentChunkDownload = (a: Attachment): { result: Promise } => { + if (a.hasData()) { + return { result: Promise.resolve(a.getData()) }; + } + let download = this.chunkDownloads.get(a); + if (!download) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + download = this.gmail.attachmentGetChunk(a.msgId!, a.id!); + this.chunkDownloads.set(a, download); + } + return { result: download }; + }; + + public waitForAttachmentChunkDownload = async (a: Attachment) => { + if (a.hasData()) return a.getData(); + return this.chunkDownloads.await(a, this.queueAttachmentChunkDownload(a).result); + }; + + public msgGetRaw = async (msgId: string): Promise => { + let msgDownload = this.rawMessages.get(msgId); + if (!msgDownload) { + msgDownload = this.gmail.msgGet(msgId, 'raw'); + this.rawMessages.set(msgId, msgDownload); + } + return (await this.rawMessages.await(msgId, msgDownload)).raw || ''; + }; + + public msgGetFull = async (msgId: string): Promise => { + let msgDownload = this.fullMessages.get(msgId); + if (!msgDownload) { + msgDownload = this.gmail.msgGet(msgId, 'full'); + this.fullMessages.set(msgId, msgDownload); + } + return await this.fullMessages.await(msgId, msgDownload); + }; +} diff --git a/extension/js/common/lang.ts b/extension/js/common/lang.ts index f110682a896..10a8b5b2e05 100644 --- a/extension/js/common/lang.ts +++ b/extension/js/common/lang.ts @@ -130,10 +130,6 @@ export const Lang = { contactForSupportSubsentence, contactForSupportSentence: (isCustomerUrlFesUsed = false) => contactForSupportSubsentence(isCustomerUrlFesUsed, 'for support.'), writeMeToFixIt: (isCustomerUrlFesUsed: boolean) => contactForSupportSubsentence(isCustomerUrlFesUsed, 'to fix it.'), - restartBrowserAndTryAgain: (isCustomerUrlFesUsed: boolean) => - `Unexpected error occured. Please restart your browser and try again. If this persists after a restart, ${contactForSupportSubsentence( - isCustomerUrlFesUsed - )}.`, emailAliasChangedAskForReload: 'Your email aliases on Gmail have refreshed since the last time you used FlowCrypt.\nReload the compose window now?', }, passphraseRequired: { diff --git a/extension/js/common/loader-context-interface.ts b/extension/js/common/loader-context-interface.ts new file mode 100644 index 00000000000..6486ced90d3 --- /dev/null +++ b/extension/js/common/loader-context-interface.ts @@ -0,0 +1,24 @@ +/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ + +'use strict'; + +import { Attachment } from './core/attachment.js'; + +export type JQueryEl = JQuery; + +export interface LoaderContextInterface { + renderPlainAttachment(a: Attachment, attachmentEl?: JQueryEl, error?: string): void; + + // prependAttachments is used to render encrypted attachment prepending AttachmentContainerInner + prependEncryptedAttachment(a: Attachment): void; + + hideAttachment(attachmentSel?: JQueryEl): void; + + /** + * XSS WARNING + * + * newHtmlContent must be XSS safe + */ + // eslint-disable-next-line @typescript-eslint/naming-convention + setMsgBody_DANGEROUSLY(newHtmlContent_MUST_BE_XSS_SAFE: string, method: 'set' | 'append' | 'after'): void; // xss-dangerous-function +} diff --git a/extension/js/common/message-renderer.ts b/extension/js/common/message-renderer.ts new file mode 100644 index 00000000000..692d3efbd43 --- /dev/null +++ b/extension/js/common/message-renderer.ts @@ -0,0 +1,823 @@ +/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ + +'use strict'; + +import { GmailParser, GmailRes } from './api/email-provider/gmail/gmail-parser.js'; +import { PubLookup } from './api/pub-lookup.js'; +import { ClientConfiguration } from './client-configuration.js'; +import { Attachment, TransferableAttachment } from './core/attachment.js'; +import { Buf } from './core/buf.js'; +import { CID_PATTERN, Dict, Str, Value } from './core/common.js'; +import { KeyUtil } from './core/crypto/key.js'; +import { DecryptErrTypes, DecryptResult, MsgUtil, PgpMsgTypeResult, VerifyRes } from './core/crypto/pgp/msg-util.js'; +import { PgpArmor } from './core/crypto/pgp/pgp-armor.js'; +import { Mime, MessageBody } from './core/mime.js'; +import { MsgBlockParser } from './core/msg-block-parser.js'; +import { MsgBlock } from './core/msg-block.js'; +import { Lang } from './lang.js'; +import { Catch } from './platform/catch.js'; +import { AcctStore } from './platform/store/acct-store.js'; +import { ContactStore } from './platform/store/contact-store.js'; +import { KeyStore } from './platform/store/key-store.js'; +import { PassphraseStore } from './platform/store/passphrase-store.js'; +import { Xss } from './platform/xss.js'; +import { RelayManager } from './relay-manager.js'; +import { RenderInterface, RenderInterfaceBase } from './render-interface.js'; +import { MessageInfo, PrintMailInfo } from './render-message.js'; +import { saveFetchedPubkeysIfNewerThanInStorage } from './shared.js'; +import { XssSafeFactory } from './xss-safe-factory.js'; +import * as DOMPurify from 'dompurify'; +import { Downloader } from './downloader.js'; +import { JQueryEl, LoaderContextInterface } from './loader-context-interface.js'; +import { Gmail } from './api/email-provider/gmail/gmail.js'; +import { ApiErr } from './api/shared/api-error.js'; +import { isCustomerUrlFesUsed } from './helpers.js'; +import { ExpirationCache } from './core/expiration-cache.js'; + +type ProcessedMessage = { + body: MessageBody; + blocks: MsgBlock[]; + attachments: Attachment[]; + messageInfo: MessageInfo; +}; + +export class MessageRenderer { + public readonly downloader: Downloader; + private readonly processedMessages = new ExpirationCache>(24 * 60 * 60 * 1000); // 24 hours + + private constructor( + private readonly acctEmail: string, + private readonly gmail: Gmail, + private readonly relayManager: RelayManager, + private readonly factory: XssSafeFactory, + private readonly sendAsAliases: Set, + private readonly fullName?: string, + private debug: boolean = false + ) { + this.downloader = new Downloader(gmail); + } + + public static newInstance = async (acctEmail: string, gmail: Gmail, relayManager: RelayManager, factory: XssSafeFactory, debug = false) => { + const { sendAs, full_name: fullName } = await AcctStore.get(acctEmail, ['sendAs', 'full_name']); + return new MessageRenderer(acctEmail, gmail, relayManager, factory, new Set(sendAs ? Object.keys(sendAs) : [acctEmail]), fullName, debug); + }; + + public static isPwdMsg = (text: string) => { + return /https:\/\/flowcrypt\.com\/[a-zA-Z0-9]{10}$/.test(text); + }; + + /** + * Replaces inline image CID references with base64 encoded data in sanitized HTML + * and returns the sanitized HTML along with the inline CID attachments. + * + * @param html - The original HTML content. + * @param attachments - An array of email attachments. + * @returns An object containing sanitized HTML and an array of inline CID attachments. + */ + private static replaceInlineImageCIDs = (html: string, attachments: Attachment[]): { sanitizedHtml: string; inlineCIDAttachments: Set } => { + // Set to store inline CID attachments + const inlineCIDAttachments = new Set(); + + // Define the hook function for DOMPurify to process image elements after sanitizing attributes + const processImageElements = (node: Element | null) => { + // Ensure the node exists and has a 'src' attribute + if (!node || !('src' in node)) return; + const imageSrc = node.getAttribute('src') as string; + if (!imageSrc) return; + const matches = imageSrc.match(CID_PATTERN); + + // Check if the src attribute contains a CID + if (matches && matches[1]) { + const contentId = matches[1]; + const contentIdAttachment = attachments.find(attachment => attachment.cid === `<${contentId}>`); + + // Replace the src attribute with a base64 encoded string + if (contentIdAttachment) { + inlineCIDAttachments.add(contentIdAttachment); + node.setAttribute('src', `data:${contentIdAttachment.type};base64,${contentIdAttachment.getData().toBase64Str()}`); + } + } + }; + + // Add the DOMPurify hook + DOMPurify.addHook('afterSanitizeAttributes', processImageElements); + + // Sanitize the HTML and remove the DOMPurify hooks + const sanitizedHtml = Xss.htmlSanitize(html); + DOMPurify.removeAllHooks(); + + return { sanitizedHtml, inlineCIDAttachments }; + }; + + private static getEncryptedSubjectText = (subject: string, isHtml: boolean) => { + if (isHtml) { + return `
Encrypted Subject: + ${Xss.escape(subject)} +
+
`; + } else { + return `Encrypted Subject: ${subject}\n----------------------------------------------------------------------------------------------------\n`; + } + }; + + private static decryptFunctionToVerifyRes = async (decrypt: () => Promise): Promise => { + const decryptResult = await decrypt(); + if (!decryptResult.success) { + return undefined; // note: this internal error results in a wrong "Not Signed" badge + } else { + return decryptResult.signature; + } + }; + + // attachments returned by this method are missing data, so they need to be fetched + private static getMessageBodyAndAttachments = (gmailMsg: GmailRes.GmailMsg): { body: MessageBody; attachments: Attachment[] } => { + const bodies = GmailParser.findBodies(gmailMsg); + const attachments = GmailParser.findAttachments(gmailMsg, gmailMsg.id); + const text = bodies['text/plain'] ? Buf.fromBase64UrlStr(bodies['text/plain']).toUtfStr() : undefined; + // stripping HTML tags here for safety in the way extractArmoredBlock used to do, should we? + // note: MimeContent.html returned from Mime.decode (when processing a raw MIME-message) isn't stripped + // so there is another stripping that takes place later when rendering in XssSafeFactory.renderableMsgBlock + const html = bodies['text/html'] ? Xss.htmlSanitizeAndStripAllTags(Buf.fromBase64UrlStr(bodies['text/html']).toUtfStr(), '\n') : undefined; + return { + body: { + text, + html, + }, + attachments, + }; + }; + + private static renderPgpSignatureCheckResult = async ( + renderModule: RenderInterface, + verifyRes: VerifyRes | undefined, + wasSignerEmailSupplied: boolean, + retryVerification?: () => Promise + ) => { + if (verifyRes?.error) { + renderModule.renderSignatureStatus(`error verifying signature: ${verifyRes.error}`); + renderModule.setFrameColor('red'); + } else if (!verifyRes || !verifyRes.signerLongids.length) { + renderModule.renderSignatureStatus('not signed'); + } else if (verifyRes.match) { + renderModule.renderSignatureStatus('signed'); + } else if (retryVerification) { + renderModule.renderVerificationInProgress(); + let retryVerificationAgain: (() => Promise) | undefined; + try { + verifyRes = (await retryVerification()) ?? verifyRes; // [fetch pubkeys] and verify again + } catch (e) { + if (ApiErr.isSignificant(e)) { + Catch.reportErr(e); + renderModule.renderSignatureStatus(`error verifying signature: ${e}`); + return; + } else { + const continuationPromise = new Promise(resolve => renderModule.renderSignatureOffline(resolve)); + // todo: we can make a helper method to await a Promise or a cancellation flag, + // but we'd better make `cancel` a Promise as well + const createTimeoutPromise = () => + new Promise<'timeout'>(resolve => { + Catch.setHandledTimeout(() => resolve('timeout'), 1000); + }); + while ((await Promise.race([continuationPromise, createTimeoutPromise()])) === 'timeout') { + if (renderModule.cancellation.cancel) return; + } + retryVerificationAgain = retryVerification; + } + } + await MessageRenderer.renderPgpSignatureCheckResult(renderModule, verifyRes, wasSignerEmailSupplied, retryVerificationAgain); + return; + } else if (!wasSignerEmailSupplied) { + // todo: unit-test this case? + renderModule.renderSignatureStatus('could not verify signature: missing pubkey, missing sender info'); + } else { + MessageRenderer.renderMissingPubkeyOrBadSignature(renderModule, verifyRes); + } + }; + + private static renderMissingPubkeyOrBadSignature = (renderModule: RenderInterfaceBase, verifyRes: VerifyRes): void => { + // eslint-disable-next-line no-null/no-null + if (verifyRes.match === null || !Value.arr.hasIntersection(verifyRes.signerLongids, verifyRes.suppliedLongids)) { + MessageRenderer.renderMissingPubkey(renderModule, verifyRes.signerLongids[0]); + } else { + MessageRenderer.renderBadSignature(renderModule); + } + }; + + private static renderMissingPubkey = (renderModule: RenderInterfaceBase, signerLongid: string) => { + renderModule.renderSignatureStatus(`could not verify signature: missing pubkey ${signerLongid}`); + }; + + private static renderBadSignature = (renderModule: RenderInterfaceBase) => { + renderModule.renderSignatureStatus('bad signature'); + renderModule.setFrameColor('red'); + }; + + private static getVerificationPubs = async (signerEmail: string) => { + const email = Str.parseEmail(signerEmail).email; + if (!email) return []; + const parsedPubs = (await ContactStore.getOneWithAllPubkeys(undefined, email))?.sortedPubkeys ?? []; + // todo: we're armoring pubkeys here to pass them to MsgUtil. Perhaps, we can optimize this + return parsedPubs.map(key => KeyUtil.armor(key.pubkey)); + }; + + private static handlePrivateKeyMismatch = async (renderModule: RenderInterface, armoredPubs: string[], message: Uint8Array | string, isPwdMsg: boolean) => { + // todo - make it work for multiple stored keys + const msgDiagnosis = await MsgUtil.diagnosePubkeys({ armoredPubs, message }); + if (msgDiagnosis.found_match) { + renderModule.renderErr(Lang.pgpBlock.cantOpen + Lang.pgpBlock.encryptedCorrectlyFileBug, undefined); + } else if (isPwdMsg) { + renderModule.renderErr( + Lang.pgpBlock.pwdMsgOnlyReadableOnWeb + MessageRenderer.btnHtml('ask sender to re-send', 'gray2 short reply_pubkey_mismatch'), + undefined + ); + } else { + const startText = + msgDiagnosis.receivers === 1 + ? Lang.pgpBlock.cantOpen + Lang.pgpBlock.singleSender + Lang.pgpBlock.askResend + : Lang.pgpBlock.yourKeyCantOpenImportIfHave; + renderModule.renderErr( + startText + + MessageRenderer.btnHtml('import missing key', 'gray2 settings_add_key') + + '   ' + + MessageRenderer.btnHtml('ask sender to update', 'gray2 short reply_pubkey_mismatch') + + '   ' + + MessageRenderer.btnHtml('settings', 'gray2 settings_keyserver'), + undefined + ); + } + }; + + private static btnHtml = (text: string, addClasses: string) => { + return ``; + }; + + public renderMsg = ({ senderEmail, blocks }: { blocks: MsgBlock[]; senderEmail?: string }, showOriginal: boolean) => { + const isOutgoing = this.isOutgoing(senderEmail); + const blocksInFrames: Dict = {}; + let renderedXssSafe = ''; // xss-direct + for (const block of blocks) { + if (renderedXssSafe) renderedXssSafe += '

'; // xss-direct + if (showOriginal) { + renderedXssSafe += Xss.escape(Str.with(block.content)).replace(/\n/g, '
'); // xss-escaped + } else if (['signedMsg', 'encryptedMsg'].includes(block.type)) { + const { frameId, frameXssSafe } = this.factory.embeddedMsg(block.type); // xss-safe-factory + renderedXssSafe += frameXssSafe; // xss-safe-value + blocksInFrames[frameId] = block; + } else { + renderedXssSafe += XssSafeFactory.renderableMsgBlock(this.factory, block, isOutgoing); // xss-safe-factory + } + } + return { renderedXssSafe, isOutgoing, blocksInFrames }; // xss-safe-value + }; + + public isOutgoing = (senderEmail: string | undefined) => { + return Boolean(senderEmail && this.sendAsAliases.has(senderEmail)); + }; + + public processAttachment = async ( + a: Attachment, + body: MessageBody, + attachments: Attachment[], + loaderContext: LoaderContextInterface, + attachmentSel: JQueryEl | undefined, + msgId: string, // for PGP/MIME signed messages + messageInfo: MessageInfo, + skipSignatureAttachment?: boolean + ): Promise<'shown' | 'hidden' | 'replaced'> => { + // todo - [same name + not processed].first() ... What if attachment metas are out of order compared to how gmail shows it? And have the same name? + try { + let treatAs = a.treatAs(attachments, !skipSignatureAttachment && Mime.isBodyEmpty(body)); + if (['needChunk', 'maybePgp', 'publicKey'].includes(treatAs)) { + // Inspect a chunk + if (this.debug) { + console.debug('processAttachment() try -> awaiting chunk + awaiting type'); + } + const data = await this.downloader.waitForAttachmentChunkDownload(a); + const openpgpType = MsgUtil.type({ data }); + if (openpgpType && openpgpType.type === 'publicKey' && openpgpType.armored) { + // todo: publicKey attachment can't be too big, so we could do preparePubkey() call (checking file length) right here + treatAs = 'publicKey'; + } else if (treatAs === 'publicKey' && openpgpType?.type === 'encryptedMsg') { + treatAs = 'encryptedFile'; + } else if (treatAs !== 'publicKey' && openpgpType && ['encryptedMsg', 'signedMsg'].includes(openpgpType.type)) { + treatAs = 'encryptedMsg'; + } else { + if (this.debug) { + console.debug("processAttachment() try -> awaiting done and processed -- doesn't look like OpenPGP"); + } + // plain attachment with a warning + loaderContext.renderPlainAttachment(a, attachmentSel, 'Unknown OpenPGP format'); + return 'shown'; + } + if (this.debug) { + console.debug('processAttachment() try -> awaiting done and processed'); + } + } + if (treatAs === 'signature') { + if (skipSignatureAttachment) { + treatAs = 'plainFile'; + } else { + // we could change 'Getting file info..' to 'Loading signed message..' in attachment_loader element + const raw = await this.downloader.msgGetRaw(msgId); + loaderContext.hideAttachment(attachmentSel); + await this.setMsgBodyAndStartProcessing(loaderContext, 'signedDetached', messageInfo.printMailInfo, messageInfo.from?.email, renderModule => + this.processMessageWithDetachedSignatureFromRaw(raw, renderModule, messageInfo.from?.email, body) + ); + return 'hidden'; // native attachment should be hidden, the "attachment" goes to the message container + } + } + if (treatAs !== 'plainFile') { + loaderContext.hideAttachment(attachmentSel); + } + if (treatAs === 'hidden') { + return 'hidden'; + } + if (treatAs === 'publicKey') { + const { armoredPubkey, openpgpType } = await this.preparePubkey(a); + if (armoredPubkey) { + loaderContext.setMsgBody_DANGEROUSLY(this.factory.embeddedPubkey(armoredPubkey, this.isOutgoing(messageInfo.from?.email)), 'after'); // xss-safe-factory + return 'hidden'; + } else if (openpgpType?.type === 'encryptedMsg') { + treatAs = 'encryptedFile'; // fall back to ordinary encrypted attachment + } else { + loaderContext.renderPlainAttachment(a, attachmentSel, 'Unknown Public Key Format'); + return 'shown'; + } + } + if (treatAs === 'encryptedFile') { + // actual encrypted attachment - show it + loaderContext.prependEncryptedAttachment(a); + return 'replaced'; // native should be hidden, custom should appear instead + } else if (treatAs === 'encryptedMsg') { + await this.setMsgBodyAndStartProcessing(loaderContext, treatAs, messageInfo.printMailInfo, messageInfo.from?.email, (renderModule, frameId) => + this.processCryptoMessage(a, renderModule, frameId, messageInfo.from?.email, messageInfo.isPwdMsgBasedOnMsgSnippet, messageInfo.plainSubject) + ); + return 'hidden'; // native attachment should be hidden, the "attachment" goes to the message container + } else if (treatAs === 'privateKey') { + return await this.renderBackupFromFile(a, loaderContext, attachmentSel); + } else { + // standard file + loaderContext.renderPlainAttachment(a, attachmentSel); + return 'shown'; + } + } catch (e) { + if (ApiErr.isNetErr(e)) { + loaderContext.renderPlainAttachment(a, attachmentSel, 'Categorize: net err'); + return 'shown'; + } else { + Catch.reportErr(e); + loaderContext.renderPlainAttachment(a, attachmentSel, 'Categorize: unknown err'); + return 'shown'; + } + } + }; + + public startProcessingInlineBlocks = async (relayManager: RelayManager, factory: XssSafeFactory, messageInfo: MessageInfo, blocks: Dict) => { + await Promise.all( + Object.entries(blocks).map(([frameId, block]) => + this.relayAndStartProcessing(relayManager, factory, frameId, messageInfo.printMailInfo, messageInfo.from?.email, renderModule => + this.renderMsgBlock(block, renderModule, messageInfo.from?.email, messageInfo.isPwdMsgBasedOnMsgSnippet, messageInfo.plainSubject) + ) + ) + ); + }; + + public deleteExpired = (): void => { + this.processedMessages.deleteExpired(); + this.downloader.deleteExpired(); + }; + + public msgGetProcessed = async (msgId: string): Promise => { + let processed = this.processedMessages.get(msgId); + if (!processed) { + processed = (async () => { + return this.processFull(await this.downloader.msgGetFull(msgId)); + })(); + this.processedMessages.set(msgId, processed); + } + return this.processedMessages.await(msgId, processed); + }; + + private processFull = async (fullMsg: GmailRes.GmailMsg): Promise => { + const { body, attachments } = MessageRenderer.getMessageBodyAndAttachments(fullMsg); + const blocks = Mime.processBody(body); + const isBodyEmpty = Mime.isBodyEmpty(body); + // todo: start download of all attachments that are not plainFile, when the cache is implemented? + // start chunk downloads for 'needChunk' attachments + for (const a of attachments.filter(a => !a.hasData())) { + const treatAs = a.treatAs(attachments, isBodyEmpty); + if (treatAs === 'plainFile') continue; + if (treatAs === 'needChunk') { + this.downloader.queueAttachmentChunkDownload(a); + } else if (treatAs === 'publicKey') { + // we also want a chunk before we replace the publicKey-looking attachment in the UI + // todo: or simply queue full attachment download? + this.downloader.queueAttachmentChunkDownload(a); + } else { + // todo: queue full attachment download, when the cache is implemented? + // note: this cache should return void or throw an exception because the data bytes are set to the Attachment object + } + } + return { + body, + blocks, + messageInfo: await this.getMessageInfo(fullMsg), + attachments, + }; + }; + + private getMessageInfo = async (fullMsg: GmailRes.GmailMsg): Promise => { + const sentDate = GmailParser.findHeader(fullMsg, 'date'); + const sentDateStr = sentDate ? Str.fromDate(new Date(sentDate)).replace(' ', ' at ') : ''; + const fromString = GmailParser.findHeader(fullMsg, 'from'); + const from = fromString ? Str.parseEmail(fromString) : undefined; + const fromEmail = from?.email ?? ''; + const fromHtml = from?.name ? `${Xss.htmlSanitize(from.name)} <${fromEmail}>` : fromEmail; + /* eslint-disable @typescript-eslint/no-non-null-assertion */ + const ccString = GmailParser.findHeader(fullMsg, 'cc') + ? `Cc: ${Xss.escape(GmailParser.findHeader(fullMsg, 'cc')!)}
` + : ''; + const bccString = GmailParser.findHeader(fullMsg, 'bcc') ? `Bcc: ${Xss.escape(GmailParser.findHeader(fullMsg, 'bcc')!)}
` : ''; + /* eslint-enable @typescript-eslint/no-non-null-assertion */ + const plainSubject = GmailParser.findHeader(fullMsg, 'subject'); + return { + plainSubject, + printMailInfo: { + userNameAndEmail: `${Xss.escape(this.fullName ?? '')} <${Xss.escape(this.acctEmail)}>`, + html: ` +
+

${Xss.htmlSanitize(plainSubject ?? '')}

+
+
+
+
+ From: ${fromHtml} +
+
+ ${sentDateStr} +
+
+ To: ${Xss.escape(GmailParser.findHeader(fullMsg, 'to') ?? '')}
+ ${ccString} + ${bccString} +

+ `, + }, + from, + isPwdMsgBasedOnMsgSnippet: MessageRenderer.isPwdMsg(fullMsg.snippet || ''), + }; + }; + + private decideDecryptedContentFormattingAndRender = async ( + signerEmail: string | undefined, + verificationPubs: string[], + decryptedBytes: Uint8Array | string, + isEncrypted: boolean, + sigResult: VerifyRes | undefined, + renderModule: RenderInterface, + retryVerification: (() => Promise) | undefined, + plainSubject: string | undefined + ): Promise<{ publicKeys?: string[] }> => { + if (isEncrypted) { + renderModule.renderEncryptionStatus('encrypted'); + renderModule.setFrameColor('green'); + } else { + renderModule.renderEncryptionStatus('not encrypted'); + renderModule.setFrameColor('gray'); + } + const publicKeys: string[] = []; + let renderableAttachments: TransferableAttachment[] = []; + let signedContentInDecryptedData: { rawSignedContent: string; signature: Attachment } | undefined; + let decryptedContent: string | undefined; + let isHtml = false; + // todo - replace with MsgBlockParser.fmtDecryptedAsSanitizedHtmlBlocks, then the extract/strip methods could be private? + if (!Mime.resemblesMsg(decryptedBytes)) { + const fcAttachmentBlocks: MsgBlock[] = []; + decryptedContent = Str.with(decryptedBytes); + decryptedContent = MsgBlockParser.extractFcAttachments(decryptedContent, fcAttachmentBlocks); + decryptedContent = MsgBlockParser.stripFcReplyToken(decryptedContent); + decryptedContent = MsgBlockParser.stripPublicKeys(decryptedContent, publicKeys); + if (fcAttachmentBlocks.length) { + renderableAttachments = fcAttachmentBlocks.map( + attachmentBlock => Attachment.toTransferableAttachment(attachmentBlock.attachmentMeta!) // eslint-disable-line @typescript-eslint/no-non-null-assertion + ); + } + } else { + renderModule.renderText('Formatting...'); + const decoded = await Mime.decode(decryptedBytes); + let inlineCIDAttachments = new Set(); + if (typeof decoded.html !== 'undefined') { + ({ sanitizedHtml: decryptedContent, inlineCIDAttachments } = MessageRenderer.replaceInlineImageCIDs(decoded.html, decoded.attachments)); + isHtml = true; + } else if (typeof decoded.text !== 'undefined') { + decryptedContent = decoded.text; + } else { + decryptedContent = ''; + } + if ( + decoded.subject && + isEncrypted && + (!plainSubject || !Mime.subjectWithoutPrefixes(plainSubject).includes(Mime.subjectWithoutPrefixes(decoded.subject))) + ) { + // there is an encrypted subject + (either there is no plain subject or the plain subject does not contain what's in the encrypted subject) + decryptedContent = MessageRenderer.getEncryptedSubjectText(decoded.subject, isHtml) + decryptedContent; // render encrypted subject in message + } + for (const attachment of decoded.attachments) { + if (attachment.isPublicKey()) { + publicKeys.push(attachment.getData().toUtfStr()); + } else if (decoded.rawSignedContent && attachment.treatAs(decoded.attachments) === 'signature') { + signedContentInDecryptedData = { rawSignedContent: decoded.rawSignedContent, signature: attachment }; + } else if (inlineCIDAttachments.has(attachment)) { + // this attachment has been processed into an inline image + } else { + renderableAttachments.push( + Attachment.toTransferableAttachment({ + name: attachment.name, + type: attachment.type, + length: attachment.getData().length, + data: attachment.getData(), + }) + ); + } + } + } + if (!sigResult?.match && signedContentInDecryptedData) { + const plaintext = signedContentInDecryptedData.rawSignedContent; + const sigText = signedContentInDecryptedData.signature.getData().toUtfStr(); + const verify = (verificationPubs: string[]) => MsgUtil.verifyDetached({ plaintext, sigText, verificationPubs }); + const newSigResult = await verify(verificationPubs); + return await this.decideDecryptedContentFormattingAndRender( + signerEmail, + verificationPubs, + plaintext, + isEncrypted, + newSigResult, + renderModule, + this.getRetryVerification(signerEmail, verify), + plainSubject + ); + } + renderModule.separateQuotedContentAndRenderText(decryptedContent, isHtml); + await MessageRenderer.renderPgpSignatureCheckResult(renderModule, sigResult, Boolean(signerEmail), retryVerification); + if (renderableAttachments.length) { + renderModule.renderInnerAttachments(renderableAttachments, isEncrypted); + } + renderModule.resizePgpBlockFrame(); + return isEncrypted ? { publicKeys } : {}; + }; + + private relayAndStartProcessing = async ( + relayManager: RelayManager, + factory: XssSafeFactory, + frameId: string, + printMailInfo: PrintMailInfo | undefined, + senderEmail: string | undefined, + cb: (renderModule: RenderInterface, frameId: string) => Promise<{ publicKeys?: string[]; needPassphrase?: string[] }> + ): Promise<{ processor: Promise }> => { + const renderModule = relayManager.createRelay(frameId); + if (printMailInfo) { + renderModule.setPrintMailInfo(printMailInfo); + } + const processor = cb(renderModule, frameId) + .then(async result => { + const appendAfter = $(`iframe#${frameId}`); // todo: review inbox-active-thread -- may fail + // todo: how publicKeys and needPassphrase interact? + for (const armoredPubkey of result.publicKeys ?? []) { + appendAfter.after(factory.embeddedPubkey(armoredPubkey, this.isOutgoing(senderEmail))); + } + while (result.needPassphrase && !renderModule.cancellation.cancel) { + // if we need passphrase, we have to be able to re-try decryption indefinitely on button presses, + // so we can only release resources when the frame is detached + await PassphraseStore.waitUntilPassphraseChanged(this.acctEmail, result.needPassphrase, 1000, renderModule.cancellation); + if (renderModule.cancellation.cancel) { + if (this.debug) { + console.debug('Destination frame was detached -- stopping processing'); + } + return; + } + renderModule.clearErrorStatus(); + renderModule.renderText('Decrypting...'); + result = await cb(renderModule, frameId); + // I guess, no additional publicKeys will appear here for display... + } + }) + .catch(e => { + // normally no exceptions come to this point so let's report it + Catch.reportErr(e); + renderModule.renderErr(Xss.escape(String(e)), undefined); + }) + .finally(() => relayManager.done(frameId)); + return { processor }; + }; + + private renderMsgBlock = async ( + block: MsgBlock, + renderModule: RenderInterface, + signerEmail: string | undefined, + isPwdMsgBasedOnMsgSnippet: boolean | undefined, + plainSubject: string | undefined + ) => { + return await this.renderCryptoMessage(block.content, renderModule, true, signerEmail, isPwdMsgBasedOnMsgSnippet, plainSubject); + }; + + // todo: this should be moved to some other class? + private getRetryVerification = (email: string | undefined, verify: (verificationPubs: string[]) => Promise) => { + if (!email) return undefined; + return async () => { + const clientConfiguration = await ClientConfiguration.newInstance(this.acctEmail); + const { pubkeys } = await new PubLookup(clientConfiguration).lookupEmail(email); + if (pubkeys.length) { + await saveFetchedPubkeysIfNewerThanInStorage({ email, pubkeys }); // synchronously because we don't want erratic behaviour + return await verify(pubkeys); + } + return undefined; + }; + }; + + private processMessageWithDetachedSignatureFromRaw = async ( + raw: string, + renderModule: RenderInterface, + signerEmail: string | undefined, + body: MessageBody + ) => { + // ... from PgpBlockViewDecryptModule.initialize + const mimeMsg = Buf.fromBase64UrlStr(raw); + const parsed = await Mime.decode(mimeMsg); + if (!parsed || typeof parsed.rawSignedContent !== 'string') { + renderModule.renderErr( + 'Error: could not properly parse signed message', + parsed.rawSignedContent || parsed.text || parsed.html || mimeMsg.toUtfStr(), + 'parse error' + ); + } else { + const signatureAttachment = parsed.attachments.find(a => a.treatAs(parsed.attachments) === 'signature'); // todo: more than one signature candidate? + if (signatureAttachment) { + const parsedSignature = signatureAttachment.getData().toUtfStr(); + // ... from PgpBlockViewDecryptModule.decryptAndRender + const sigText = parsedSignature.replace('\n=3D', '\n='); + const plaintext = parsed.rawSignedContent; + try { + const verificationPubs = signerEmail ? await MessageRenderer.getVerificationPubs(signerEmail) : []; + const verify = async (verificationPubs: string[]) => await MsgUtil.verifyDetached({ plaintext, sigText, verificationPubs }); + const signatureResult = await verify(verificationPubs); + return await this.decideDecryptedContentFormattingAndRender( + signerEmail, + verificationPubs, + plaintext, + false, + signatureResult, + renderModule, + this.getRetryVerification(signerEmail, verify), + undefined + ); + } catch (e) { + // network errors shouldn't pass to this point + // so an exception here would be an unexpected failure + if (ApiErr.isSignificant(e)) { + Catch.reportErr(e); + } + renderModule.renderErr(Xss.escape(String(e)), body.html || body.text); // instead of raw MIME, show some readable text + } + } + } + return {}; + }; + + private renderCryptoMessage = async ( + encryptedData: string | Uint8Array, + renderModule: RenderInterface, + fallbackToPlainText: boolean, + signerEmail: string | undefined, + isPwdMsgBasedOnMsgSnippet: boolean | undefined, + plainSubject: string | undefined + ): Promise<{ publicKeys?: string[]; needPassphrase?: string[] }> => { + const kisWithPp = await KeyStore.getAllWithOptionalPassPhrase(this.acctEmail); // todo: cache + const verificationPubs = signerEmail ? await MessageRenderer.getVerificationPubs(signerEmail) : []; + const decrypt = (verificationPubs: string[]) => MsgUtil.decryptMessage({ kisWithPp, encryptedData, verificationPubs }); + const result = await decrypt(verificationPubs); + if (result.success) { + return await this.decideDecryptedContentFormattingAndRender( + signerEmail, + verificationPubs, + result.content, + !!result.isEncrypted, + result.signature, + renderModule, + this.getRetryVerification(signerEmail, verificationPubs => MessageRenderer.decryptFunctionToVerifyRes(() => decrypt(verificationPubs))), + plainSubject + ); + } else if (result.error.type === DecryptErrTypes.format) { + if (fallbackToPlainText) { + renderModule.renderAsRegularContent(Str.with(encryptedData)); + } else { + renderModule.renderErr(Lang.pgpBlock.badFormat + '\n\n' + result.error.message, Str.with(encryptedData)); + } + } else if (result.longids.needPassphrase.length) { + renderModule.renderPassphraseNeeded(result.longids.needPassphrase); + return { needPassphrase: result.longids.needPassphrase }; + } else { + if (!result.longids.chosen && !(await KeyStore.get(this.acctEmail)).length) { + renderModule.renderErr(Lang.pgpBlock.notProperlySetUp + MessageRenderer.btnHtml('FlowCrypt settings', 'green settings'), undefined); + } else if (result.error.type === DecryptErrTypes.keyMismatch) { + await MessageRenderer.handlePrivateKeyMismatch( + renderModule, + kisWithPp.map(ki => ki.public), + encryptedData, + isPwdMsgBasedOnMsgSnippet === true + ); + } else if (result.error.type === DecryptErrTypes.wrongPwd || result.error.type === DecryptErrTypes.usePassword) { + renderModule.renderErr(Lang.pgpBlock.pwdMsgAskSenderUsePubkey, undefined); + } else if (result.error.type === DecryptErrTypes.noMdc) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + renderModule.renderErr(result.error.message, result.content!.toUtfStr()); // missing mdc - only render the result after user confirmation + } else if (result.error) { + renderModule.renderErr(`${Lang.pgpBlock.cantOpen}\n\n${result.error.type}: ${result.error.message}`, Str.with(encryptedData)); + } else { + // should generally not happen + renderModule.renderErr( + Lang.pgpBlock.cantOpen + + Lang.general.writeMeToFixIt(await isCustomerUrlFesUsed(this.acctEmail)) + + '\n\nDiagnostic info: "' + + JSON.stringify(result) + + '"', + Str.with(encryptedData) + ); + } + } + return {}; + }; + + private setMsgBodyAndStartProcessing = async ( + loaderContext: LoaderContextInterface, + type: string, // for diagnostics + printMailInfo: PrintMailInfo | undefined, + senderEmail: string | undefined, + cb: (renderModule: RenderInterface, frameId: string) => Promise<{ publicKeys?: string[] }> + ): Promise<{ processor: Promise }> => { + const { frameId, frameXssSafe } = this.factory.embeddedMsg(type); // xss-safe-factory + loaderContext.setMsgBody_DANGEROUSLY(frameXssSafe, 'set'); // xss-safe-value + return await this.relayAndStartProcessing(this.relayManager, this.factory, frameId, printMailInfo, senderEmail, cb); + }; + + private processCryptoMessage = async ( + attachment: Attachment, + renderModule: RenderInterface, + frameId: string, + senderEmail: string | undefined, + isPwdMsgBasedOnMsgSnippet: boolean | undefined, + plainSubject: string | undefined + ) => { + try { + if (!attachment.hasData()) { + // todo: implement cache similar to chunk downloads + // note: this cache should return void or throw an exception because the data bytes are set to the Attachment object + this.relayManager.renderProgressText(frameId, 'Retrieving message...'); + await this.gmail.fetchAttachment(attachment, expectedTransferSize => { + return { + frameId, + expectedTransferSize, + download: (percent, loaded, total) => this.relayManager.renderProgress({ frameId, percent, loaded, total, expectedTransferSize }), // shortcut + }; + }); + } + const armoredMsg = PgpArmor.clip(attachment.getData().toUtfStr()); + if (!armoredMsg) { + renderModule.renderErr('Problem extracting armored message', attachment.getData().toUtfStr()); + } else { + renderModule.renderText('Decrypting...'); + return await this.renderCryptoMessage(armoredMsg, renderModule, false, senderEmail, isPwdMsgBasedOnMsgSnippet, plainSubject); + } + } catch (e) { + // todo: provide 'retry' button on isNetErr to re-fetch the attachment and continue processing? + if (ApiErr.isSignificant(e)) Catch.reportErr(e); + renderModule.renderErr(Xss.escape(String(e)), attachment.hasData() ? attachment.getData().toUtfStr() : undefined); + } + return {}; + }; + + private preparePubkey = async (attachment: Attachment): Promise<{ armoredPubkey?: string; openpgpType: PgpMsgTypeResult }> => { + await this.gmail.fetchAttachmentsMissingData([attachment]); + const data = attachment.getData(); + const openpgpType = MsgUtil.type({ data }); + if (openpgpType?.type === 'publicKey' && openpgpType.armored) { + // todo: do we need to armor if not openpgpType.armored? + return { armoredPubkey: data.toUtfStr(), openpgpType }; + } + return { openpgpType }; + }; + + private renderBackupFromFile = async ( + attachment: Attachment, + loaderContext: LoaderContextInterface, + attachmentSel: JQueryEl | undefined + ): Promise<'shown' | 'hidden'> => { + try { + await this.gmail.fetchAttachmentsMissingData([attachment]); + loaderContext.setMsgBody_DANGEROUSLY(this.factory.embeddedBackup(attachment.getData().toUtfStr()), 'append'); // xss-safe-factory + return 'hidden'; + } catch (e) { + loaderContext.renderPlainAttachment(attachment, attachmentSel, 'Please reload page'); // todo: unit-test + return 'shown'; + } + }; +} diff --git a/extension/js/common/platform/require.ts b/extension/js/common/platform/require.ts index 0dade1becc6..933eff80282 100644 --- a/extension/js/common/platform/require.ts +++ b/extension/js/common/platform/require.ts @@ -46,16 +46,14 @@ export const requireOpenpgp = (): typeof OpenPGP => { }; export const requireMimeParser = (): typeof MimeParser => { - return (window as any)['emailjs-mime-parser']; // eslint-disable-line + return (globalThis as any)['emailjs-mime-parser']; // eslint-disable-line }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export const requireMimeBuilder = (): any => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return (window as any)['emailjs-mime-builder']; +export const requireMimeBuilder = () => { + return (globalThis as any)['emailjs-mime-builder']; // eslint-disable-line }; export const requireIso88592 = (): Codec => { // eslint-disable-next-line @typescript-eslint/no-explicit-any - return (window as any).iso88592 as Codec; + return (globalThis as any).iso88592 as Codec; }; diff --git a/extension/js/common/platform/store/acct-store.ts b/extension/js/common/platform/store/acct-store.ts index 00ba0eb015b..1cae6b81f23 100644 --- a/extension/js/common/platform/store/acct-store.ts +++ b/extension/js/common/platform/store/acct-store.ts @@ -38,7 +38,6 @@ export type AccountIndex = | 'full_name' | 'cryptup_enabled' | 'setup_done' - | 'successfully_received_at_leat_one_message' | 'notification_setup_done_seen' | 'picture' | 'outgoing_language' @@ -67,7 +66,6 @@ export type AcctStoreDict = { full_name?: string; cryptup_enabled?: boolean; setup_done?: boolean; - successfully_received_at_leat_one_message?: boolean; notification_setup_done_seen?: boolean; picture?: string; // google image outgoing_language?: 'EN' | 'DE'; diff --git a/extension/js/common/relay-manager-interface.ts b/extension/js/common/relay-manager-interface.ts new file mode 100644 index 00000000000..9e3d0bf3267 --- /dev/null +++ b/extension/js/common/relay-manager-interface.ts @@ -0,0 +1,9 @@ +/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ + +'use strict'; + +import { RenderMessage } from './render-message.js'; + +export interface RelayManagerInterface { + relay(frameId: string, message: RenderMessage, dontEnqueue?: boolean): void; +} diff --git a/extension/js/common/relay-manager.ts b/extension/js/common/relay-manager.ts new file mode 100644 index 00000000000..a92dfbcff9a --- /dev/null +++ b/extension/js/common/relay-manager.ts @@ -0,0 +1,150 @@ +/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ + +'use strict'; + +import { Bm, BrowserMsg } from './browser/browser-msg.js'; +import { RelayManagerInterface } from './relay-manager-interface.js'; +import { RenderInterface } from './render-interface.js'; +import { RenderMessage } from './render-message.js'; +import { RenderRelay } from './render-relay.js'; + +type FrameEntry = { + readyToReceive?: true; + queue: RenderMessage[]; + progressText?: string; + relay?: RenderRelay; +}; + +export class RelayManager implements RelayManagerInterface { + private static readonly completionMessage: RenderMessage = { done: true }; + private readonly frames = new Map(); + + public constructor(private debug: boolean = false) { + const framesObserver = new MutationObserver(async mutationsList => { + for (const mutation of mutationsList) { + if (mutation.type === 'childList') { + for (const removedNode of mutation.removedNodes) { + this.dropRemovedNodes(removedNode); + } + } + } + }); + framesObserver.observe(window.document, { subtree: true, childList: true }); + } + + public static getPercentage = (percent: number | undefined, loaded: number, total: number, expectedTransferSize: number) => { + if (typeof percent === 'undefined') { + if (total || expectedTransferSize) { + percent = Math.round((loaded / (total || expectedTransferSize)) * 100); + } + } + return percent; + }; + + public relay = (frameId: string, message: RenderMessage) => { + const frameData = this.frames.get(frameId); + if (frameData) { + frameData.queue.push(message); + if (frameData.readyToReceive) { + this.flush({ frameId, queue: frameData.queue }); + } + } + }; + + public createRelay = (frameId: string): RenderInterface => { + const frameData = this.getOrCreate(frameId); + const relay = new RenderRelay(this, frameId); + frameData.relay = relay; + return relay; + }; + + public done = (frameId: string) => { + this.relay(frameId, RelayManager.completionMessage); + }; + + public handleMessageFromFrame = (data: unknown) => { + const typedData = data as { readyToReceive?: string; retry?: string } | undefined; + if (typeof typedData?.readyToReceive === 'string') { + this.readyToReceive(typedData.readyToReceive); + } + if (typeof typedData?.retry === 'string') { + this.retry(typedData.retry); + } + }; + + public renderProgressText = (frameId: string, text: string) => { + const frameData = this.frames.get(frameId); + if (frameData) { + frameData.progressText = text; + this.relay(frameId, { renderText: text }); + } + }; + + public renderProgress = ({ frameId, percent, loaded, total, expectedTransferSize }: Bm.AjaxProgress) => { + const perc = RelayManager.getPercentage(percent, loaded, total, expectedTransferSize); + if (typeof perc !== 'undefined') { + const frameData = this.frames.get(frameId); + if (frameData?.readyToReceive && typeof frameData.progressText !== 'undefined') { + this.relay(frameId, { renderText: `${frameData.progressText} ${perc}%` }); + } + } + }; + + private dropRemovedNodes = (removedNode: Node) => { + let frameId: string | undefined; + if (removedNode.nodeType === Node.ELEMENT_NODE) { + const element = removedNode as HTMLElement; + if (element.tagName === 'IFRAME') { + frameId = element.id; + } + } + if (frameId) { + if (this.debug) { + console.debug('releasing resources connected to frameId=', frameId); + } + const frameData = this.frames.get(frameId); + if (frameData) { + if (frameData.relay?.cancellation) frameData.relay.cancellation.cancel = true; + this.frames.delete(frameId); + } + } else { + for (const childNode of removedNode.childNodes) { + this.dropRemovedNodes(childNode); + } + } + }; + + private getOrCreate = (frameId: string): FrameEntry => { + const frameEntry = this.frames.get(frameId); + if (frameEntry) return frameEntry; + const newFrameEntry = { queue: [], cancellation: { cancel: false } }; + this.frames.set(frameId, newFrameEntry); + return newFrameEntry; + }; + + private flush = ({ frameId, queue }: { frameId: string; queue: RenderMessage[] }) => { + while (true) { + const message = queue.shift(); + if (message) { + BrowserMsg.send.pgpBlockRender( + 'broadcast', // todo: own tabId? + { ...message, frameId } + ); + if (message === RelayManager.completionMessage) { + this.frames.delete(frameId); + } + } else break; + } + }; + + private readyToReceive = (frameId: string) => { + const frameData = this.getOrCreate(frameId); + frameData.readyToReceive = true; + this.flush({ frameId, queue: frameData.queue }); + }; + + private retry = (frameId: string) => { + const frameData = this.frames.get(frameId); + frameData?.relay?.executeRetry(); + }; +} diff --git a/extension/js/common/render-interface.ts b/extension/js/common/render-interface.ts new file mode 100644 index 00000000000..01d6373b628 --- /dev/null +++ b/extension/js/common/render-interface.ts @@ -0,0 +1,28 @@ +/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ + +'use strict'; + +import { TransferableAttachment } from './core/attachment.js'; +import { PromiseCancellation } from './core/common.js'; +import { PrintMailInfo } from './render-message.js'; + +export interface RenderInterfaceBase { + resizePgpBlockFrame(): void; + renderText(text: string): void; + setFrameColor(color: 'red' | 'green' | 'gray'): void; + renderEncryptionStatus(status: string): void; + renderSignatureStatus(status: string): void; +} + +export interface RenderInterface extends RenderInterfaceBase { + cancellation: PromiseCancellation; + renderAsRegularContent(content: string): void; + setPrintMailInfo(info: PrintMailInfo): void; + clearErrorStatus(): void; + renderPassphraseNeeded(longids: string[]): void; + renderErr(errBoxContent: string, renderRawMsg: string | undefined, errMsg?: string): void; + renderInnerAttachments(attachments: TransferableAttachment[], isEncrypted: boolean): void; + separateQuotedContentAndRenderText(decryptedContent: string, isHtml: boolean): void; + renderVerificationInProgress(): void; + renderSignatureOffline(retry: () => void): void; +} diff --git a/extension/js/common/render-message.ts b/extension/js/common/render-message.ts new file mode 100644 index 00000000000..8fee3bd6673 --- /dev/null +++ b/extension/js/common/render-message.ts @@ -0,0 +1,46 @@ +/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ + +'use strict'; + +import { TransferableAttachment } from './core/attachment.js'; + +export type PrintMailInfo = { + userNameAndEmail: string; + html: string; +}; + +export type MessageInfo = { + printMailInfo?: PrintMailInfo; + isPwdMsgBasedOnMsgSnippet: boolean; + from?: { + email: string | undefined; + name: string | undefined; + full: string; + }; + plainSubject: string | undefined; // todo: cover by unit tests +}; + +export type RenderMessage = { + done?: true; + resizePgpBlockFrame?: true; + separateQuotedContentAndRenderText?: { decryptedContent: string; isHtml: boolean }; + renderText?: string; + setFrameColor?: 'green' | 'gray' | 'red'; + renderEncryptionStatus?: string; + renderSignatureStatus?: string; + renderVerificationInProgress?: true; + renderInnerAttachments?: { + attachments: TransferableAttachment[]; + isEncrypted: boolean; + }; + renderPassphraseNeeded?: string[]; // longids + renderErr?: { errBoxContent: string; renderRawMsg: string | undefined; errMsg?: string }; + clearErrorStatus?: true; + renderSignatureOffline?: true; + printMailInfo?: PrintMailInfo; + renderAsRegularContent?: string; +}; + +export type RenderMessageWithFrameId = { + frameId: string; +} & RenderMessage; diff --git a/extension/js/common/render-relay.ts b/extension/js/common/render-relay.ts new file mode 100644 index 00000000000..a03481ae02b --- /dev/null +++ b/extension/js/common/render-relay.ts @@ -0,0 +1,84 @@ +/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ + +'use strict'; + +import { RelayManagerInterface } from './relay-manager-interface.js'; +import { RenderInterface } from './render-interface.js'; +import { PrintMailInfo, RenderMessage } from './render-message.js'; +import { TransferableAttachment } from './core/attachment.js'; +import { PromiseCancellation } from './core/common.js'; + +export class RenderRelay implements RenderInterface { + public readonly cancellation: PromiseCancellation = { cancel: false }; + private retry?: () => void; + public constructor(private relayManager: RelayManagerInterface, private frameId: string) {} + + public renderErr = (errBoxContent: string, renderRawMsg: string | undefined, errMsg?: string | undefined) => { + this.relay({ renderErr: { errBoxContent, renderRawMsg, errMsg } }); + }; + + public renderInnerAttachments = (attachments: TransferableAttachment[], isEncrypted: boolean) => { + this.relay({ renderInnerAttachments: { attachments, isEncrypted } }); + }; + + public resizePgpBlockFrame = () => { + this.relay({ resizePgpBlockFrame: true }); + }; + + public separateQuotedContentAndRenderText = (decryptedContent: string, isHtml: boolean) => { + this.relay({ separateQuotedContentAndRenderText: { decryptedContent, isHtml } }); + }; + + public renderText = (text: string) => { + this.relay({ renderText: text }); + }; + + public setFrameColor = (color: 'green' | 'gray' | 'red') => { + this.relay({ setFrameColor: color }); + }; + + public renderEncryptionStatus = (status: string) => { + this.relay({ renderEncryptionStatus: status }); + }; + + public renderSignatureStatus = (status: string) => { + this.relay({ renderSignatureStatus: status }); + }; + + public renderVerificationInProgress = () => { + this.relay({ renderVerificationInProgress: true }); + }; + + public renderPassphraseNeeded = (longids: string[]) => { + this.relay({ renderPassphraseNeeded: longids }); + }; + + public clearErrorStatus = () => { + this.relay({ clearErrorStatus: true }); + }; + + public setPrintMailInfo = (printMailInfo: PrintMailInfo) => { + this.relay({ printMailInfo }); + }; + + public renderAsRegularContent = (content: string) => { + this.relay({ renderAsRegularContent: content }); + }; + + public renderSignatureOffline = (retry: () => void) => { + this.retry = retry; + this.relay({ renderSignatureOffline: true }); + }; + + public executeRetry = () => { + const retry = this.retry; + if (retry) { + this.retry = undefined; + retry(); + } + }; + + private relay = (message: RenderMessage) => { + this.relayManager.relay(this.frameId, message); + }; +} diff --git a/extension/js/common/xss-safe-factory.ts b/extension/js/common/xss-safe-factory.ts index d36fcad36c2..575873460ea 100644 --- a/extension/js/common/xss-safe-factory.ts +++ b/extension/js/common/xss-safe-factory.ts @@ -10,12 +10,12 @@ import { Attachment } from './core/attachment.js'; import { Browser } from './browser/browser.js'; import { BrowserMsg } from './browser/browser-msg.js'; import { Catch } from './platform/catch.js'; -import { MsgBlock, MsgBlockType } from './core/msg-block.js'; +import { MsgBlock } from './core/msg-block.js'; import { PgpArmor } from './core/crypto/pgp/pgp-armor.js'; import { Ui } from './browser/ui.js'; import { WebMailName, WebMailVersion } from './browser/env.js'; import { Xss } from './platform/xss.js'; -import { SendAsAlias } from './platform/store/acct-store.js'; +import { Buf } from './core/buf.js'; type Placement = 'settings' | 'settings_compose' | 'default' | 'dialog' | 'gmail' | 'embedded' | 'compose'; export type WebmailVariantString = undefined | 'html' | 'standard' | 'new'; @@ -23,7 +23,6 @@ export type PassphraseDialogType = 'embedded' | 'message' | 'attachment' | 'draf export type FactoryReplyParams = { replyMsgId?: string; draftId?: string; - sendAs?: Dict; subject?: string; removeAfterClose?: boolean; }; @@ -59,41 +58,30 @@ export class XssSafeFactory { * * When edited, REQUEST A SECOND SET OF EYES TO REVIEW CHANGES */ - public static renderableMsgBlock = (factory: XssSafeFactory, block: MsgBlock, msgId: string, senderEmail: string, isOutgoing?: boolean) => { + public static renderableMsgBlock = (factory: XssSafeFactory, block: MsgBlock, isOutgoing?: boolean) => { if (block.type === 'plainText') { - return Xss.escape(Str.with(block.content)).replace(/\n/g, '
') + '

'; + return XssSafeFactory.renderPlainContent(block.content); } else if (block.type === 'plainHtml') { return Xss.htmlSanitizeAndStripAllTags(Str.with(block.content), '
') + '

'; - } else if (block.type === 'encryptedMsg') { - return factory.embeddedMsg( - 'encryptedMsg', - block.complete ? PgpArmor.normalize(Str.with(block.content), 'encryptedMsg') : '', - msgId, - isOutgoing, - senderEmail - ); - } else if (block.type === 'signedMsg') { - return factory.embeddedMsg('signedMsg', Str.with(block.content), msgId, isOutgoing, senderEmail); } else if (block.type === 'publicKey') { return factory.embeddedPubkey(PgpArmor.normalize(Str.with(block.content), 'publicKey'), isOutgoing); } else if (block.type === 'privateKey') { return factory.embeddedBackup(PgpArmor.normalize(Str.with(block.content), 'privateKey')); } else if (block.type === 'certificate') { - return factory.embeddedPubkey(Str.with(block.content)); + return factory.embeddedPubkey(Str.with(block.content), isOutgoing); } else if (['encryptedAttachment', 'plainAttachment'].includes(block.type)) { return block.attachmentMeta ? factory.embeddedAttachment(new Attachment(block.attachmentMeta), block.type === 'encryptedAttachment') : '[missing encrypted attachment details]'; - } else if (block.type === 'signedHtml') { - return factory.embeddedMsg('signedHtml', '', msgId, isOutgoing, senderEmail, true); // empty msg so it re-fetches from api. True at the and for "signature" - } else if (block.type === 'signedText') { - return factory.embeddedMsg('signedText', '', msgId, isOutgoing, senderEmail, true); // empty msg so it re-fetches from api. True at the and for "signature" } else { Catch.report(`don't know how to process block type: ${block.type} (not a hard fail)`); return ''; } }; + public static renderPlainContent = (content: string | Buf) => { + return Xss.escape(Str.with(content)).replace(/\n/g, '
') + '

'; + }; /** * XSS WARNING * @@ -101,9 +89,6 @@ export class XssSafeFactory { * * When edited, REQUEST A SECOND SET OF EYES TO REVIEW CHANGES */ - public static renderableMsgBlocks = (factory: XssSafeFactory, blocks: MsgBlock[], msgId: string, senderEmail: string, isOutgoing?: boolean) => { - return blocks.map(block => XssSafeFactory.renderableMsgBlock(factory, block, msgId, senderEmail, isOutgoing)).join('\n\n'); - }; public srcImg = (relPath: string) => { return this.extUrl(`img/${relPath}`); @@ -151,15 +136,14 @@ export class XssSafeFactory { ); }; - public srcPgpBlockIframe = (message: string, msgId?: string, isOutgoing?: boolean, senderEmail?: string, signature?: string | boolean) => { - return this.frameSrc(this.extUrl('chrome/elements/pgp_block.htm'), { - frameId: this.newId(), - message, - msgId, - senderEmail, - isOutgoing, - signature, - }); + public srcPgpBlockIframe = () => { + const frameId = this.newId(); + return { + frameId, + frameSrc: this.frameSrc(this.extUrl('chrome/elements/pgp_block.htm'), { + frameId, + }), + }; }; public srcPgpPubkeyIframe = (armoredPubkey: string, isOutgoing?: boolean) => { @@ -224,8 +208,11 @@ export class XssSafeFactory { }); }; - public embeddedMsg = (type: MsgBlockType, armored: string, msgId?: string, isOutgoing?: boolean, sender?: string, signature?: string | boolean) => { - return this.iframe(this.srcPgpBlockIframe(armored, msgId, isOutgoing, sender, signature), ['pgp_block', type]) + this.hideGmailNewMsgInThreadNotification; + public embeddedMsg = ( + type: string // for diagnostic purposes + ) => { + const { frameId, frameSrc } = this.srcPgpBlockIframe(); + return { frameId, frameXssSafe: this.iframe(frameSrc, ['pgp_block', type]) + this.hideGmailNewMsgInThreadNotification }; // xss-safe-factory }; public embeddedPubkey = (armoredPubkey: string, isOutgoing?: boolean) => { diff --git a/extension/js/content_scripts/webmail/gmail-element-replacer.ts b/extension/js/content_scripts/webmail/gmail-element-replacer.ts index 0898db14854..744cb7929eb 100644 --- a/extension/js/content_scripts/webmail/gmail-element-replacer.ts +++ b/extension/js/content_scripts/webmail/gmail-element-replacer.ts @@ -4,15 +4,12 @@ import { Dict, Str } from '../../common/core/common.js'; import { FactoryReplyParams, XssSafeFactory } from '../../common/xss-safe-factory.js'; -import { GmailParser, GmailRes } from '../../common/api/email-provider/gmail/gmail-parser.js'; import { IntervalFunction, WebmailElementReplacer } from './setup-webmail-content-script.js'; -import { AjaxErr } from '../../common/api/shared/api-error.js'; import { ApiErr } from '../../common/api/shared/api-error.js'; import { Attachment } from '../../common/core/attachment.js'; import { BrowserMsg } from '../../common/browser/browser-msg.js'; import { Catch } from '../../common/platform/catch.js'; import { GlobalStore, LocalDraft } from '../../common/platform/store/global-store.js'; -import { Gmail } from '../../common/api/email-provider/gmail/gmail.js'; import { Injector } from '../../common/inject.js'; import { PubLookup } from '../../common/api/pub-lookup.js'; import { Notifications } from '../../common/notifications.js'; @@ -21,26 +18,21 @@ import { Ui } from '../../common/browser/ui.js'; import { WebmailCommon } from '../../common/webmail.js'; import { Xss } from '../../common/platform/xss.js'; import { ClientConfiguration } from '../../common/client-configuration.js'; -import { SendAsAlias } from '../../common/platform/store/acct-store.js'; // todo: can we somehow define a purely relay class for ContactStore to clearly show that crypto-libraries are not loaded and can't be used? import { ContactStore } from '../../common/platform/store/contact-store.js'; -import { Buf } from '../../common/core/buf.js'; -import { MsgBlockParser } from '../../common/core/msg-block-parser.js'; - -type JQueryEl = JQuery; +import { MessageRenderer } from '../../common/message-renderer.js'; +import { RelayManager } from '../../common/relay-manager.js'; +import { MessageInfo } from '../../common/render-message.js'; +import { GmailLoaderContext } from './gmail-loader-context.js'; +import { JQueryEl } from '../../common/loader-context-interface.js'; +import { MessageBody, Mime } from '../../common/core/mime.js'; +import { MsgBlock } from '../../common/core/msg-block.js'; export class GmailElementReplacer implements WebmailElementReplacer { private debug = false; - private gmail: Gmail; private recipientHasPgpCache: Dict = {}; - private sendAs: Dict; - private factory: XssSafeFactory; - private clientConfiguration: ClientConfiguration; private pubLookup: PubLookup; - private acctEmail: string; - private injector: Injector; - private notifications: Notifications; private webmailCommon: WebmailCommon; private currentlyEvaluatingStandardComposeBoxRecipients = false; private currentlyReplacingAttachments = false; @@ -71,22 +63,16 @@ export class GmailElementReplacer implements WebmailElementReplacer { }; public constructor( - factory: XssSafeFactory, + private readonly factory: XssSafeFactory, clientConfiguration: ClientConfiguration, - acctEmail: string, - sendAs: Dict, - injector: Injector, - notifications: Notifications + private readonly acctEmail: string, + private readonly messageRenderer: MessageRenderer, + private readonly injector: Injector, + private readonly notifications: Notifications, + private readonly relayManager: RelayManager ) { - this.factory = factory; - this.acctEmail = acctEmail; - this.sendAs = sendAs; - this.injector = injector; - this.notifications = notifications; this.webmailCommon = new WebmailCommon(acctEmail, injector); - this.gmail = new Gmail(acctEmail); - this.clientConfiguration = clientConfiguration; - this.pubLookup = new PubLookup(this.clientConfiguration); + this.pubLookup = new PubLookup(clientConfiguration); } public getIntervalFunctions = (): Array => { @@ -106,7 +92,7 @@ export class GmailElementReplacer implements WebmailElementReplacer { }; public reinsertReplyBox = (replyMsgId: string) => { - const params: FactoryReplyParams = { sendAs: this.sendAs, replyMsgId }; + const params: FactoryReplyParams = { replyMsgId }; $('.reply_message_iframe_container:visible').last().append(this.factory.embeddedReply(params, false, true)); // xss-safe-value }; @@ -153,7 +139,7 @@ export class GmailElementReplacer implements WebmailElementReplacer { }; private everything = () => { - this.replaceArmoredBlocks(); + this.replaceArmoredBlocks().catch(Catch.reportErr); this.replaceAttachments().catch(Catch.reportErr); this.replaceComposeDraftLinks(); this.replaceConvoBtns(); @@ -161,9 +147,10 @@ export class GmailElementReplacer implements WebmailElementReplacer { this.evaluateStandardComposeRecipients().catch(Catch.reportErr); this.addSettingsBtn(); this.renderLocalDrafts().catch(Catch.reportErr); + this.messageRenderer.deleteExpired(); }; - private replaceArmoredBlocks = () => { + private replaceArmoredBlocks = async () => { const emailsContainingPgpBlock = $(this.sel.msgOuter).find(this.sel.msgInnerContainingPgp).not('.evaluated'); for (const emailContainer of emailsContainingPgpBlock) { if (this.debug) { @@ -173,23 +160,39 @@ export class GmailElementReplacer implements WebmailElementReplacer { if (this.debug) { console.debug('replaceArmoredBlocks() for of emailsContainingPgpBlock -> emailContainer added evaluated'); } - const senderEmail = this.getSenderEmail(emailContainer); - const isOutgoing = !!this.sendAs[senderEmail]; const msgId = this.determineMsgId(emailContainer); - const { blocks } = MsgBlockParser.detectBlocks(emailContainer.innerText); - if (blocks.length === 1 && blocks[0].type === 'plainText') { + let blocks: MsgBlock[] = []; + let messageInfo: MessageInfo | undefined; + try { + ({ messageInfo, blocks } = await this.messageRenderer.msgGetProcessed(msgId)); + } catch (e) { + this.handleException(e); + // fill with fallback values from the element + blocks = Mime.processBody({ text: emailContainer.innerText }); + // todo: print info for offline? + } + const setMessageInfo = messageInfo ?? { + isPwdMsgBasedOnMsgSnippet: MessageRenderer.isPwdMsg(emailContainer.innerText), + plainSubject: undefined, // todo: take from this.sel.subject? + }; + if (blocks.length === 0 || (blocks.length === 1 && blocks[0].type === 'plainText')) { // only has single block which is plain text - } else { - const replacementXssSafe = XssSafeFactory.renderableMsgBlocks(this.factory, blocks, msgId, senderEmail, isOutgoing); - $(this.sel.translatePrompt).hide(); - if (this.debug) { - console.debug('replaceArmoredBlocks() for of emailsContainingPgpBlock -> emailContainer replacing'); - } - this.updateMsgBodyEl_DANGEROUSLY(emailContainer, 'set', replacementXssSafe); // xss-safe-factory: replace_blocks is XSS safe - if (this.debug) { - console.debug('replaceArmoredBlocks() for of emailsContainingPgpBlock -> emailContainer replaced'); - } + continue; + } + if (!setMessageInfo.from) { + setMessageInfo.from = this.getFrom(this.getMsgBodyEl(msgId)); } + const { renderedXssSafe, blocksInFrames } = this.messageRenderer.renderMsg({ blocks, senderEmail: setMessageInfo.from?.email }, false); // xss-safe-value + if (!renderedXssSafe) continue; + $(this.sel.translatePrompt).hide(); + if (this.debug) { + console.debug('replaceArmoredBlocks() for of emailsContainingPgpBlock -> emailContainer replacing'); + } + GmailLoaderContext.updateMsgBodyEl_DANGEROUSLY(emailContainer, 'set', renderedXssSafe); // xss-safe-factory: replace_blocks is XSS safe + if (this.debug) { + console.debug('replaceArmoredBlocks() for of emailsContainingPgpBlock -> emailContainer replaced'); + } + await this.messageRenderer.startProcessingInlineBlocks(this.relayManager, this.factory, setMessageInfo, blocksInFrames).catch(Catch.reportErr); } }; @@ -390,23 +393,13 @@ export class GmailElementReplacer implements WebmailElementReplacer { if (this.debug) { console.debug('processNewPgpAttachments() -> msgGet may take some time'); } - const msg = await this.gmail.msgGet(msgId, 'full'); // todo: cache or thoroughly refactor in #5022 + const { attachments, messageInfo, body } = await this.messageRenderer.msgGetProcessed(msgId); if (this.debug) { - console.debug('processNewPgpAttachments() -> msgGet done -> processAttachments', msg); + console.debug('processNewPgpAttachments() -> msgGet done -> processAttachments', attachments); } - await this.processAttachments(msgId, GmailParser.findAttachments(msg), attachmentsContainer, false); + await this.processAttachments(msgId, attachments, attachmentsContainer, messageInfo, body, false); } catch (e) { - if (ApiErr.isAuthErr(e)) { - this.notifications.showAuthPopupNeeded(this.acctEmail); - $(newPgpAttachments).find('.attachment_loader').text('Auth needed'); - } else if (ApiErr.isNetErr(e)) { - $(newPgpAttachments).find('.attachment_loader').text('Network error'); - } else { - if (!ApiErr.isServerErr(e) && !ApiErr.isMailOrAcctDisabledOrPolicy(e) && !ApiErr.isNotFound(e)) { - Catch.reportErr(e); - } - $(newPgpAttachments).find('.attachment_loader').text('Failed to load'); - } + this.handleException(e, $(newPgpAttachments).find('.attachment_loader')); } } else { $(newPgpAttachments).prepend(this.factory.embeddedAttachmentStatus('Unknown message id')); // xss-safe-factory @@ -416,101 +409,46 @@ export class GmailElementReplacer implements WebmailElementReplacer { private processAttachments = async ( msgId: string, - attachmentMetas: Attachment[], - attachmentsContainerInner: JQueryEl | HTMLElement, + attachments: Attachment[], + attachmentsContainerInner: JQueryEl, + messageInfo: MessageInfo, + body: MessageBody, skipGoogleDrive: boolean ) => { if (this.debug) { - console.debug('processAttachments()', attachmentMetas); + console.debug('processAttachments()', attachments); + } + const msgEl = this.getMsgBodyEl(msgId); + if (!messageInfo.from?.email) { + messageInfo.from = this.getFrom(msgEl); } - let msgEl = this.getMsgBodyEl(msgId); // not a constant because sometimes elements get replaced, then returned by the function that replaced them - const isBodyEmpty = msgEl.text() === '' || msgEl.text() === '\n'; - const senderEmail = this.getSenderEmail(msgEl); - const isOutgoing = !!this.sendAs[senderEmail]; + const loaderContext = new GmailLoaderContext(this.factory, msgEl, attachmentsContainerInner); attachmentsContainerInner = $(attachmentsContainerInner); attachmentsContainerInner.parent().find(this.sel.numberOfAttachments).hide(); - let nRenderedAttachments = attachmentMetas.length; - for (const a of attachmentMetas) { - const treatAs = a.treatAs(attachmentMetas, isBodyEmpty); - // todo - [same name + not processed].first() ... What if attachment metas are out of order compared to how gmail shows it? And have the same name? + let nRenderedAttachments = attachments.length; + for (const a of attachments) { const attachmentSel = this.filterAttachments( attachmentsContainerInner.children().not('.attachment_processed'), new RegExp(`^${Str.regexEscape(a.name || 'noname')}$`) ).first(); - if (this.debug) { - console.debug('processAttachments() treatAs'); - } - try { - if (treatAs !== 'plainFile') { - this.hideAttachment(attachmentSel, attachmentsContainerInner); - nRenderedAttachments--; - if (treatAs === 'encryptedFile') { - // actual encrypted attachment - show it - attachmentsContainerInner.prepend(this.factory.embeddedAttachment(a, true)); // xss-safe-factory - nRenderedAttachments++; - } else if (treatAs === 'encryptedMsg') { - const isAmbiguousAscFile = a.name.substr(-4) === '.asc' && !Attachment.encryptedMsgNames.includes(a.name); // ambiguous .asc name - const isAmbiguousNonameFile = !a.name || a.name === 'noname'; // may not even be OpenPGP related - if (isAmbiguousAscFile || isAmbiguousNonameFile) { - // Inspect a chunk - if (this.debug) { - console.debug('processAttachments() try -> awaiting chunk + awaiting type'); - } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const data = await this.gmail.attachmentGetChunk(msgId, a.id!); // .id is present when fetched from api - const openpgpType = await BrowserMsg.send.bg.await.pgpMsgType({ data: data.toBase64Str() }); // base64 for FF, see #2587 - if (openpgpType && openpgpType.type === 'publicKey' && openpgpType.armored) { - // if it looks like OpenPGP public key - nRenderedAttachments = await this.renderPublicKeyFromFile(a, attachmentsContainerInner, msgEl, isOutgoing, attachmentSel, nRenderedAttachments); - } else if (openpgpType && ['encryptedMsg', 'signedMsg'].includes(openpgpType.type)) { - msgEl = this.updateMsgBodyEl_DANGEROUSLY(msgEl, 'append', this.factory.embeddedMsg(openpgpType.type, '', msgId, false, senderEmail)); // xss-safe-factory - } else { - attachmentSel.show().children('.attachment_loader').text('Unknown OpenPGP format'); - nRenderedAttachments++; - } - if (this.debug) { - console.debug('processAttachments() try -> awaiting done and processed'); - } - } else { - msgEl = this.updateMsgBodyEl_DANGEROUSLY(msgEl, 'set', this.factory.embeddedMsg('encryptedMsg', '', msgId, false, senderEmail)); // xss-safe-factory - } - } else if (treatAs === 'publicKey') { - // todo - pubkey should be fetched in pgp_pubkey.js - nRenderedAttachments = await this.renderPublicKeyFromFile(a, attachmentsContainerInner, msgEl, isOutgoing, attachmentSel, nRenderedAttachments); - } else if (treatAs === 'privateKey') { - nRenderedAttachments = await this.renderBackupFromFile(a, attachmentsContainerInner, msgEl, attachmentSel, nRenderedAttachments); - } else if (treatAs === 'signature') { - const embeddedSignedMsgXssSafe = this.factory.embeddedMsg('signedMsg', '', msgId, false, senderEmail, true); - msgEl = this.updateMsgBodyEl_DANGEROUSLY(msgEl, 'set', embeddedSignedMsgXssSafe); // xss-safe-factory - } - } else if (treatAs === 'plainFile' && a.name.substr(-4) === '.asc') { - // normal looking attachment ending with .asc - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const data = await this.gmail.attachmentGetChunk(msgId, a.id!); // .id is present when fetched from api - const openpgpType = await BrowserMsg.send.bg.await.pgpMsgType({ data: data.toBase64Str() }); // base64 for FF, see #2587 - if (openpgpType && openpgpType.type === 'publicKey' && openpgpType.armored) { - // if it looks like OpenPGP public key - nRenderedAttachments = await this.renderPublicKeyFromFile(a, attachmentsContainerInner, msgEl, isOutgoing, attachmentSel, nRenderedAttachments); - this.hideAttachment(attachmentSel, attachmentsContainerInner); - nRenderedAttachments--; - } else { - attachmentSel.addClass('attachment_processed').children('.attachment_loader').remove(); - } - } else { - // standard file - attachmentSel.addClass('attachment_processed').children('.attachment_loader').remove(); - } - } catch (e) { - if (!ApiErr.isSignificant(e) || (e instanceof AjaxErr && e.status === 200)) { - attachmentSel.show().children('.attachment_loader').text('Categorize: net err'); - nRenderedAttachments++; - } else { - Catch.reportErr(e); - attachmentSel.show().children('.attachment_loader').text('Categorize: unknown err'); - nRenderedAttachments++; - } + const renderStatus = await this.messageRenderer.processAttachment( + a, + body, + attachments, + loaderContext, + attachmentSel, + msgId, + messageInfo, + skipGoogleDrive + ); + if (renderStatus === 'hidden') { + nRenderedAttachments--; } } + if (nRenderedAttachments !== attachments.length) { + // according to #4200, no point in showing "download all" button if at least one attachment is encrypted etc. + $(this.sel.attachmentsButtons).hide(); + } if (nRenderedAttachments >= 2) { // Aligned with Gmail, the label is shown only if there are 2 or more attachments attachmentsContainerInner.parent().find(this.sel.numberOfAttachmentsDigit).text(nRenderedAttachments); @@ -520,11 +458,11 @@ export class GmailElementReplacer implements WebmailElementReplacer { attachmentsContainerInner.parents(this.sel.attachmentsContainerOuter).first().hide(); } if (!skipGoogleDrive) { - await this.processGoogleDriveAttachments(msgId, msgEl, attachmentsContainerInner); + await this.processGoogleDriveAttachments(msgId, loaderContext.msgEl, attachmentsContainerInner, messageInfo); } }; - private processGoogleDriveAttachments = async (msgId: string, msgEl: JQueryEl, attachmentsContainerInner: JQueryEl) => { + private processGoogleDriveAttachments = async (msgId: string, msgEl: JQueryEl, attachmentsContainerInner: JQueryEl, messageInfo: MessageInfo) => { const notProcessedAttachmentsLoaders = attachmentsContainerInner.find('.attachment_loader'); if (notProcessedAttachmentsLoaders.length && msgEl.find('.gmail_drive_chip, a[href^="https://drive.google.com/file"]').length) { // replace google drive attachments - they do not get returned by Gmail API thus did not get replaced above @@ -542,63 +480,15 @@ export class GmailElementReplacer implements WebmailElementReplacer { treatAs: 'encryptedFile', }) ); + // todo: start download } else { console.info('Missing Google Drive attachments download_url'); } } - await this.processAttachments(msgId, googleDriveAttachments, attachmentsContainerInner, true); + await this.processAttachments(msgId, googleDriveAttachments, attachmentsContainerInner, messageInfo, {}, true); } }; - private renderPublicKeyFromFile = async ( - attachmentMeta: Attachment, - attachmentsContainerInner: JQueryEl, - msgEl: JQueryEl, - isOutgoing: boolean, - attachmentSel: JQueryEl, - nRenderedAttachments: number - ) => { - let downloadedAttachment: GmailRes.GmailAttachment; - try { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - downloadedAttachment = await this.gmail.attachmentGet(attachmentMeta.msgId!, attachmentMeta.id!); // .id! is present when fetched from api - } catch (e) { - attachmentsContainerInner.show().addClass('attachment_processed').find('.attachment_loader').text('Please reload page'); - nRenderedAttachments++; - return nRenderedAttachments; - } - const openpgpType = await BrowserMsg.send.bg.await.pgpMsgType({ - data: Buf.fromUint8(downloadedAttachment.data.subarray(0, 1000)).toBase64Str(), - }); // base64 for FF, see #2587 - if (openpgpType && openpgpType.type === 'publicKey') { - this.updateMsgBodyEl_DANGEROUSLY(msgEl, 'after', this.factory.embeddedPubkey(downloadedAttachment.data.toUtfStr(), isOutgoing)); // xss-safe-factory - } else { - attachmentSel.show().addClass('attachment_processed').children('.attachment_loader').text('Unknown Public Key Format'); - nRenderedAttachments++; - } - return nRenderedAttachments; - }; - - private renderBackupFromFile = async ( - attachmentMeta: Attachment, - attachmentsContainerInner: JQueryEl, - msgEl: JQueryEl, - attachmentSel: JQueryEl, - nRenderedAttachments: number - ) => { - let downloadedAttachment: GmailRes.GmailAttachment; - try { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - downloadedAttachment = await this.gmail.attachmentGet(attachmentMeta.msgId!, attachmentMeta.id!); // .id! is present when fetched from api - } catch (e) { - attachmentsContainerInner.show().addClass('attachment_processed').find('.attachment_loader').text('Please reload page'); - nRenderedAttachments++; - return nRenderedAttachments; - } - this.updateMsgBodyEl_DANGEROUSLY(msgEl, 'append', this.factory.embeddedBackup(downloadedAttachment.data.toUtfStr())); // xss-safe-factory - return nRenderedAttachments; - }; - private filterAttachments = (potentialMatches: JQueryEl | HTMLElement, regExp: RegExp) => { return $(potentialMatches) .filter('span.aZo:visible, span.a5r:visible') @@ -610,17 +500,6 @@ export class GmailElementReplacer implements WebmailElementReplacer { .closest('span.aZo, span.a5r'); }; - private hideAttachment = (attachmentEl: JQueryEl | HTMLElement, attachmentsContainerSel: JQueryEl | HTMLElement) => { - attachmentEl = $(attachmentEl); - attachmentsContainerSel = $(attachmentsContainerSel); - attachmentEl.hide(); - if (!attachmentEl.length) { - attachmentsContainerSel.children('.attachment_loader').text('Missing file info'); - } - // according to #4200, no point in showing "download all" button if at least one attachment is encrypted etc. - $(this.sel.attachmentsButtons).hide(); - }; - private determineMsgId = (innerMsgEl: HTMLElement | JQueryEl) => { const parents = $(innerMsgEl).parents(this.sel.msgOuter); return parents.attr('data-legacy-message-id') || parents.attr('data-message-id') || ''; @@ -630,65 +509,13 @@ export class GmailElementReplacer implements WebmailElementReplacer { return $(this.sel.msgOuter).filter(`[data-legacy-message-id="${msgId}"]`).find(this.sel.msgInner); }; - private wrapMsgBodyEl = (htmlContent: string) => { - return '
' + htmlContent + '
'; - }; - - /* eslint-disable @typescript-eslint/naming-convention */ - /** - * XSS WARNING - * - * new_html_content must be XSS safe - */ - // prettier-ignore - private updateMsgBodyEl_DANGEROUSLY(el: HTMLElement | JQueryEl, method: 'set' | 'append' | 'after', newHtmlContent_MUST_BE_XSS_SAFE: string): JQueryEl { // xss-dangerous-function - /* eslint-enable @typescript-eslint/naming-convention */ - // Messages in Gmail UI have to be replaced in a very particular way - // The first time we update element, it should be completely replaced so that Gmail JS will lose reference to the original element and stop re-rendering it - // Gmail message re-rendering causes the PGP message to flash back and forth, confusing the user and wasting cpu time - // Subsequent times, it can be updated naturally - const msgBody = $(el); - const replace = !msgBody.is('.message_inner_body'); // not a previously replaced element, needs replacing - if (method === 'set') { - if (replace) { - const parent = msgBody.parent(); - msgBody.replaceWith(this.wrapMsgBodyEl(newHtmlContent_MUST_BE_XSS_SAFE)); // xss-safe-value - this.ensureHasParentNode(msgBody); // Gmail is using msgBody.parentNode (#2271) - return parent.find('.message_inner_body'); // need to return new selector - old element was replaced - } else { - return msgBody.html(newHtmlContent_MUST_BE_XSS_SAFE); // xss-safe-value - } - } else if (method === 'append') { - if (replace) { - const parent = msgBody.parent(); - const wrapper = msgBody.wrap(this.wrapMsgBodyEl('')); - wrapper.append(newHtmlContent_MUST_BE_XSS_SAFE); // xss-reinsert // xss-safe-value - this.ensureHasParentNode(wrapper); // Gmail is using msgBody.parentNode (#2271) - return parent.find('.message_inner_body'); // need to return new selector - old element was replaced - } else { - return msgBody.append(newHtmlContent_MUST_BE_XSS_SAFE); // xss-safe-value - } - } else if (method === 'after') { - msgBody.after(newHtmlContent_MUST_BE_XSS_SAFE); - return msgBody; - } else { - throw new Error('Unknown update_message_body_element method:' + method); - } - } - - private ensureHasParentNode = (el: JQuery) => { - if (!el.parent().length) { - const dummyParent = $('
'); - dummyParent.append(el); // xss-direct - } - }; - - private getSenderEmail = (msgEl: HTMLElement | JQueryEl) => { - return ($(msgEl).closest('.gs').find('span.gD').attr('email') || '').toLowerCase(); + private getFrom = (msgEl: HTMLElement | JQueryEl) => { + const from = $(msgEl).closest('.gs').find('span.gD').attr('email')?.toLowerCase(); + return from ? Str.parseEmail(from) : undefined; }; private getLastMsgReplyParams = (convoRootEl: JQueryEl): FactoryReplyParams => { - return { sendAs: this.sendAs, replyMsgId: this.determineMsgId($(convoRootEl).find(this.sel.msgInner).last()) }; + return { replyMsgId: this.determineMsgId($(convoRootEl).find(this.sel.msgInner).last()) }; }; private getGonvoRootEl = (anyInnerElement: HTMLElement) => { @@ -698,8 +525,8 @@ export class GmailElementReplacer implements WebmailElementReplacer { private insertEncryptedReplyBox = (messageContainer: JQuery) => { const msgIdElement = messageContainer.find('[data-legacy-message-id], [data-message-id]'); const msgId = msgIdElement.attr('data-legacy-message-id') || msgIdElement.attr('data-message-id'); - const replyParams: FactoryReplyParams = { sendAs: this.sendAs, replyMsgId: msgId, removeAfterClose: true }; - const secureReplyBoxXssSafe = `
${this.factory.embeddedReply( + const replyParams: FactoryReplyParams = { replyMsgId: msgId, removeAfterClose: true }; + const secureReplyBoxXssSafe = /* xss-safe-factory */ `
${this.factory.embeddedReply( replyParams, true, true @@ -758,7 +585,7 @@ export class GmailElementReplacer implements WebmailElementReplacer { const isReplyButtonView = replyBoxEl.className.includes('nr'); const replyBoxes = document.querySelectorAll('iframe.reply_message'); const alreadyHasSecureReplyBox = replyBoxes.length > 0; - const secureReplyBoxXssSafe = ` + const secureReplyBoxXssSafe = /* xss-safe-factory */ `
${this.factory.embeddedReply(replyParams, this.shouldShowEditableSecureReply || alreadyHasSecureReplyBox)}
@@ -783,6 +610,25 @@ export class GmailElementReplacer implements WebmailElementReplacer { } }; + // loaderEl is a loader reference in case we're processing an attachment + // todo: we could also re-use a common method like this in Inbox + private handleException = (e: unknown, loaderEl?: JQueryEl) => { + if (ApiErr.isAuthErr(e)) { + this.notifications.showAuthPopupNeeded(this.acctEmail); + loaderEl?.text('Auth needed'); + } else if (ApiErr.isNetErr(e)) { + loaderEl?.text('Network error'); + // todo: } else if (ApiErr.isInPrivateMode(e)) { + // this.notifications.show(`FlowCrypt does not work in a Firefox Private Window (or when Firefox Containers are used). Please try in a standard window.`); + } else { + if (!ApiErr.isServerErr(e) && !ApiErr.isMailOrAcctDisabledOrPolicy(e) && !ApiErr.isNotFound(e)) { + Catch.reportErr(e); + } + loaderEl?.text('Failed to load'); + // todo: show somenotification if this error happened when replacing armored blocks? + } + }; + private showSwitchToEncryptedReplyWarningIfNeeded = (reployBox: JQueryEl) => { const showSwitchToEncryptedReplyWarning = reployBox.closest('div.h7').find(this.sel.msgOuter).find('iframe.pgp_block').hasClass('encryptedMsg'); if (showSwitchToEncryptedReplyWarning) { diff --git a/extension/js/content_scripts/webmail/gmail-loader-context.ts b/extension/js/content_scripts/webmail/gmail-loader-context.ts new file mode 100644 index 00000000000..1d098c71ab2 --- /dev/null +++ b/extension/js/content_scripts/webmail/gmail-loader-context.ts @@ -0,0 +1,110 @@ +/* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ + +'use strict'; + +import { Attachment } from '../../common/core/attachment.js'; +import { JQueryEl, LoaderContextInterface } from '../../common/loader-context-interface.js'; +import { XssSafeFactory } from '../../common/xss-safe-factory.js'; + +export class GmailLoaderContext implements LoaderContextInterface { + public constructor(private readonly factory: XssSafeFactory, public msgEl: JQueryEl, private readonly attachmentsContainerInner: JQueryEl) {} + + /* eslint-disable @typescript-eslint/naming-convention */ + /** + * XSS WARNING + * + * newHtmlContent must be XSS safe + */ + // prettier-ignore + public static updateMsgBodyEl_DANGEROUSLY( // xss-dangerous-function + el: HTMLElement | JQueryEl, + method: 'set' | 'append' | 'after', + newHtmlContent_MUST_BE_XSS_SAFE: string + ): JQueryEl { + /* eslint-enable @typescript-eslint/naming-convention */ + // Messages in Gmail UI have to be replaced in a very particular way + // The first time we update element, it should be completely replaced so that Gmail JS will lose reference to the original element and stop re-rendering it + // Gmail message re-rendering causes the PGP message to flash back and forth, confusing the user and wasting cpu time + // Subsequent times, it can be updated naturally + const msgBody = $(el); + const replace = !msgBody.is('.message_inner_body'); // not a previously replaced element, needs replacing + if (method === 'set') { + if (replace) { + const parent = msgBody.parent(); + msgBody.replaceWith(this.wrapMsgBodyEl(newHtmlContent_MUST_BE_XSS_SAFE)); // xss-safe-value + this.ensureHasParentNode(msgBody); // Gmail is using msgBody.parentNode (#2271) + return parent.find('.message_inner_body'); // need to return new selector - old element was replaced + } else { + return msgBody.html(newHtmlContent_MUST_BE_XSS_SAFE); // xss-safe-value + } + } else if (method === 'append') { + if (replace) { + const parent = msgBody.parent(); + const wrapper = msgBody.wrap(this.wrapMsgBodyEl('')); + wrapper.append(newHtmlContent_MUST_BE_XSS_SAFE); // xss-reinsert // xss-safe-value + this.ensureHasParentNode(wrapper); // Gmail is using msgBody.parentNode (#2271) + return parent.find('.message_inner_body'); // need to return new selector - old element was replaced + } else { + return msgBody.append(newHtmlContent_MUST_BE_XSS_SAFE); // xss-safe-value + } + } else if (method === 'after') { + msgBody.after(newHtmlContent_MUST_BE_XSS_SAFE); + return msgBody; + } else { + throw new Error('Unknown update_message_body_element method:' + method); + } + } + + private static ensureHasParentNode = (el: JQuery) => { + if (!el.parent().length) { + const dummyParent = $('
'); + dummyParent.append(el); // xss-direct + } + }; + + private static wrapMsgBodyEl = (htmlContent: string) => { + return '
' + htmlContent + '
'; + }; + + public renderPlainAttachment = (a: Attachment, attachmentSel?: JQueryEl, error?: string) => { + // simply show existing attachment + if (!attachmentSel) { + // todo: do we need this clause? + this.attachmentsContainerInner + .show() + .addClass('attachment_processed') + .find('.attachment_loader') + .text(error || 'Please reload page'); + } else { + const el = attachmentSel.show(); + if (error) { + el.children('.attachment_loader').text(error); + } else { + el.addClass('attachment_processed').children('.attachment_loader').remove(); + } + } + }; + + public prependEncryptedAttachment = (a: Attachment) => { + this.attachmentsContainerInner.prepend(this.factory.embeddedAttachment(a, true)); // xss-safe-factory + }; + + /* eslint-disable @typescript-eslint/naming-convention */ + /** + * XSS WARNING + * + * newHtmlContent must be XSS safe + */ + // prettier-ignore + public setMsgBody_DANGEROUSLY = (newHtmlContent_MUST_BE_XSS_SAFE: string, method: 'set' | 'append' | 'after') => { // xss-dangerous-function + /* eslint-enable @typescript-eslint/naming-convention */ + this.msgEl = GmailLoaderContext.updateMsgBodyEl_DANGEROUSLY(this.msgEl, method, newHtmlContent_MUST_BE_XSS_SAFE); // xss-safe-value + }; + + public hideAttachment = (attachmentEl: JQueryEl) => { + attachmentEl.hide(); + if (!attachmentEl.length) { + this.attachmentsContainerInner.children('.attachment_loader').text('Missing file info'); + } + }; +} diff --git a/extension/js/content_scripts/webmail/setup-webmail-content-script.ts b/extension/js/content_scripts/webmail/setup-webmail-content-script.ts index 96c573a7ce4..611f359bcf3 100644 --- a/extension/js/content_scripts/webmail/setup-webmail-content-script.ts +++ b/extension/js/content_scripts/webmail/setup-webmail-content-script.ts @@ -24,6 +24,7 @@ import { AcctStore } from '../../common/platform/store/acct-store.js'; import { GlobalStore } from '../../common/platform/store/global-store.js'; import { InMemoryStore } from '../../common/platform/store/in-memory-store.js'; import { WebmailVariantString, XssSafeFactory } from '../../common/xss-safe-factory.js'; +import { RelayManager } from '../../common/relay-manager.js'; export type WebmailVariantObject = { newDataLayer: undefined | boolean; @@ -44,7 +45,8 @@ type WebmailSpecificInfo = { inject: Injector, notifications: Notifications, factory: XssSafeFactory, - notifyMurdered: () => void + notifyMurdered: () => void, + relayManager: RelayManager ) => Promise; }; export interface WebmailElementReplacer { @@ -152,6 +154,7 @@ export const contentScriptSetupIfVacant = async (webmailSpecific: WebmailSpecifi inject: Injector, factory: XssSafeFactory, notifications: Notifications, + relayManager: RelayManager, ppEvent: { entered?: boolean } ) => { BrowserMsg.addListener('set_active_window', async ({ frameId }: Bm.ComposeWindow) => { @@ -197,16 +200,6 @@ export const contentScriptSetupIfVacant = async (webmailSpecific: WebmailSpecifi BrowserMsg.addListener('reinsert_reply_box', async ({ replyMsgId }: Bm.ReinsertReplyBox) => { webmailSpecific.getReplacer().reinsertReplyBox(replyMsgId); }); - BrowserMsg.addListener('render_public_keys', async ({ traverseUp, afterFrameId, publicKeys }: Bm.RenderPublicKeys) => { - const traverseUpLevels = (traverseUp as number) || 0; - let appendAfter = $(`iframe#${afterFrameId}`); - for (let i = 0; i < traverseUpLevels; i++) { - appendAfter = appendAfter.parent(); - } - for (const armoredPubkey of publicKeys) { - appendAfter.after(factory.embeddedPubkey(armoredPubkey, false)); - } - }); BrowserMsg.addListener('close_dialog', async () => { Swal.close(); }); @@ -241,6 +234,9 @@ export const contentScriptSetupIfVacant = async (webmailSpecific: WebmailSpecifi BrowserMsg.addListener('show_attachment_preview', async ({ iframeUrl }: Bm.ShowAttachmentPreview) => { await Ui.modal.attachmentPreview(iframeUrl); }); + BrowserMsg.addListener('ajax_progress', async (progress: Bm.AjaxProgress) => { + relayManager.renderProgress(progress); + }); BrowserMsg.listen(tabId); }; @@ -424,7 +420,8 @@ export const contentScriptSetupIfVacant = async (webmailSpecific: WebmailSpecifi await showNotificationsAndWaitTilAcctSetUp(acctEmail, notifications); Catch.setHandledTimeout(() => updateClientConfiguration(acctEmail), 0); const ppEvent: { entered?: boolean } = {}; - browserMsgListen(acctEmail, tabId, inject, factory, notifications, ppEvent); + const relayManager = new RelayManager(); + browserMsgListen(acctEmail, tabId, inject, factory, notifications, relayManager, ppEvent); const clientConfiguration = await ClientConfiguration.newInstance(acctEmail); await startPullingKeysFromEkm( acctEmail, @@ -433,7 +430,12 @@ export const contentScriptSetupIfVacant = async (webmailSpecific: WebmailSpecifi ppEvent, Catch.try(() => notifyExpiringKeys(acctEmail, clientConfiguration, notifications)) ); - await webmailSpecific.start(acctEmail, clientConfiguration, inject, notifications, factory, notifyMurdered); + window.addEventListener('message', e => { + if (e.origin === Env.getExtensionOrigin()) { + relayManager.handleMessageFromFrame(e.data); + } + }); + await webmailSpecific.start(acctEmail, clientConfiguration, inject, notifications, factory, notifyMurdered, relayManager); } catch (e) { if (e instanceof TabIdRequiredError) { console.error(`FlowCrypt cannot start: ${String(e)}`); diff --git a/extension/js/content_scripts/webmail/webmail.ts b/extension/js/content_scripts/webmail/webmail.ts index 7b321afef07..3fb52842a76 100644 --- a/extension/js/content_scripts/webmail/webmail.ts +++ b/extension/js/content_scripts/webmail/webmail.ts @@ -4,8 +4,6 @@ // todo - a few things are duplicated here, refactor -/// - import { WebmailVariantObject, contentScriptSetupIfVacant } from './setup-webmail-content-script.js'; import { Catch } from '../../common/platform/catch.js'; import { ContentScriptWindow } from '../../common/browser/browser-window.js'; @@ -16,7 +14,9 @@ import { Notifications } from '../../common/notifications.js'; import { Str } from '../../common/core/common.js'; import { XssSafeFactory } from '../../common/xss-safe-factory.js'; import { ClientConfiguration } from '../../common/client-configuration.js'; -import { AcctStore } from '../../common/platform/store/acct-store.js'; +import { RelayManager } from '../../common/relay-manager.js'; +import { MessageRenderer } from '../../common/message-renderer.js'; +import { Gmail } from '../../common/api/email-provider/gmail/gmail.js'; Catch.try(async () => { const gmailWebmailStartup = async () => { @@ -98,16 +98,13 @@ Catch.try(async () => { injector: Injector, notifications: Notifications, factory: XssSafeFactory, - notifyMurdered: () => void + notifyMurdered: () => void, + relayManager: RelayManager ) => { hijackGmailHotkeys(); - const storage = await AcctStore.get(acctEmail, ['sendAs', 'full_name']); - if (!storage.sendAs) { - storage.sendAs = {}; - storage.sendAs[acctEmail] = { name: storage.full_name, isPrimary: true }; - } injector.btns(); - replacer = new GmailElementReplacer(factory, clientConfiguration, acctEmail, storage.sendAs, injector, notifications); + const messageRenderer = await MessageRenderer.newInstance(acctEmail, new Gmail(acctEmail), relayManager, factory); + replacer = new GmailElementReplacer(factory, clientConfiguration, acctEmail, messageRenderer, injector, notifications, relayManager); await notifications.showInitial(acctEmail); const intervaliFunctions = replacer.getIntervalFunctions(); for (const intervalFunction of intervaliFunctions) { diff --git a/extension/manifest.json b/extension/manifest.json index 9a1161f5ad1..757607ad905 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -42,7 +42,22 @@ { "matches": ["https://mail.google.com/*"], "css": ["/css/webmail.css", "/css/sweetalert2.css"], - "js": ["/lib/purify.js", "/lib/jquery.min.js", "/lib/openpgp.js", "/lib/sweetalert2.js", "/lib/streams_web.js", "/js/content_scripts/webmail_bundle.js"] + "js": [ + "/lib/purify.js", + "/lib/jquery.min.js", + "/lib/openpgp.js", + "/lib/sweetalert2.js", + "/lib/streams_web.js", + "/lib/emailjs/punycode.js", + "/lib/iso-8859-2.js", + "/lib/emailjs/emailjs-stringencoding.js", + "/lib/emailjs/emailjs-mime-codec.js", + "/lib/emailjs/emailjs-mime-types.js", + "/lib/emailjs/emailjs-addressparser.js", + "/lib/emailjs/emailjs-mime-builder.js", + "/lib/emailjs/emailjs-mime-parser.js", + "/js/content_scripts/webmail_bundle.js" + ] }, { "matches": ["https://www.google.com/robots.txt*"], diff --git a/scripts/build.sh b/scripts/build.sh index ee0e135fc63..6cb799a5ea5 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -108,13 +108,24 @@ main() { # until https://github.com/openpgpjs/web-stream-tools/pull/20 is resolved STREAMS_REGEX="s/'\.\/(streams|util|writer|reader|node-conversions)'/'\.\/\1\.js'/g" STREAMS_FILES=$OUTPUT_DIRECTORY/lib/streams/* - # patch isUint8Array until https://github.com/openpgpjs/web-stream-tools/pull/23 is resolved - ISUINT8ARRAY_REGEX="s/(\s*)return\x20Uint8Array\.prototype\.isPrototypeOf\(input\);/\1return\x20Uint8Array\.prototype\.isPrototypeOf\(input\)\x20\|\|\x20globalThis\.Uint8Array\.prototype\.isPrototypeOf\(input\);/g" OPENPGP_FILE=$OUTPUT_DIRECTORY/lib/openpgp.js + # patch isUint8Array until https://github.com/openpgpjs/web-stream-tools/pull/23 is resolved + ISUINT8ARRAY_REGEX1="s/(\s*)return\x20Uint8Array\.prototype\.isPrototypeOf\(input\);/\1return\x20Uint8Array\.prototype\.isPrototypeOf\(input\)\x20\|\|\x20globalThis\.Uint8Array\.prototype\.isPrototypeOf\(input\);/g" + + # the following patches are until https://github.com/openpgpjs/openpgpjs/issues/1648 is fixed + + # this patch handles patterns like (n instanceof Uint8Array) or (arguments[i] instanceof Uint8Array) + # to replace them with (\1 instanceof Uint8Array || \1 instanceof globalThis.Uint8Array) + ISUINT8ARRAY_REGEX2="s/\(([^\(\)\x20]+)\x20instanceof\x20Uint8Array\)/\(\1\x20instanceof\x20Uint8Array\x20\|\|\x20\1\x20instanceof\x20globalThis\.Uint8Array\)/g" + # this patch handles pattern like \x20n instanceof Uint8Array; + ISUINT8ARRAY_REGEX3="s/return\x20([^\(\)\x20]+)\x20instanceof\x20Uint8Array;/return\x20\(\1\x20instanceof\x20Uint8Array\x20\|\|\x20\1\x20instanceof\x20globalThis\.Uint8Array\);/g" + apply_regex_replace $STREAMS_REGEX $STREAMS_FILES - apply_regex_replace $ISUINT8ARRAY_REGEX $STREAMS_FILES - apply_regex_replace $ISUINT8ARRAY_REGEX $OPENPGP_FILE + apply_regex_replace $ISUINT8ARRAY_REGEX1 $STREAMS_FILES + apply_regex_replace $ISUINT8ARRAY_REGEX1 $OPENPGP_FILE + apply_regex_replace $ISUINT8ARRAY_REGEX2 $OPENPGP_FILE + apply_regex_replace $ISUINT8ARRAY_REGEX3 $OPENPGP_FILE # bundle web-stream-tools as Stream var for the content script ( cd conf && npx webpack ) & pids+=($!) @@ -140,4 +151,4 @@ main() { node ./build/tooling/build-types-and-manifests } -main "$@" \ No newline at end of file +main "$@" diff --git a/test/source/browser/controllable.ts b/test/source/browser/controllable.ts index 5ca2147da48..fc2ce8a47ce 100644 --- a/test/source/browser/controllable.ts +++ b/test/source/browser/controllable.ts @@ -519,8 +519,9 @@ abstract class ControllableBase { const resolvePromise: Promise = (async () => { const downloadPath = path.resolve(__dirname, 'download', Util.lousyRandom()); mkdirp.sync(downloadPath); + const page = 'page' in this.target ? this.target.page() : this.target; // eslint-disable-next-line @typescript-eslint/no-explicit-any, no-underscore-dangle - await (this.target as any)._client().send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath }); + await (page as any)._client().send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath }); if (typeof selector === 'string') { await this.waitAndClick(selector); } else { diff --git a/test/source/mock/google/exported-messages/corrupted-1.json b/test/source/mock/google/exported-messages/corrupted-1.json deleted file mode 100644 index 4ec8933e97c..00000000000 --- a/test/source/mock/google/exported-messages/corrupted-1.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "acctEmail": "flowcrypt.compatibility@gmail.com", - "full": { - "id": "corrupted-1", - "threadId": "corrupted-1", - "historyId": "corrupted-1" - }, - "raw": { - "id": "corrupted-1", - "threadId": "corrupted-1", - "labelIds": ["INBOX"], - "sizeEstimate": 2, - "raw": "RSo", - "historyId": "corrupted-1" - } -} diff --git a/test/source/mock/google/exported-messages/message-export-15f7f5e966792203.json b/test/source/mock/google/exported-messages/message-export-15f7f5e966792203.json new file mode 100644 index 00000000000..3598213d1a0 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-15f7f5e966792203.json @@ -0,0 +1,71 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "15f7f5e966792203", + "threadId": "15f7f5e966792203", + "labelIds": [ + "IMPORTANT", + "STARRED", + "CATEGORY_PERSONAL", + "Label_4", + "INBOX" + ], + "snippet": "-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Standard message signed inline should easily verify This is email footer -----BEGIN PGP SIGNATURE----- Version: FlowCrypt 5.0.4 Gmail Encryption", + "payload": { + "partId": "", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "AMCzsaULbONjxuOMpEc2a1JkbQC/SVGvvFoKC15wLWI6HWy+gneXeEFG RMLGsUQPi33rBmNVhp84pNfWPZX2+ZpMF/RNM3M=" + }, + { + "name": "Openpgp", + "value": "id=6D24791A5B106262B06217C606CA553EC2455D70" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Date", + "value": "Thu, 2 Nov 2017 17:53:45 -0700" + }, + { + "name": "Subject", + "value": "signed with FlowCrypt Extension (inline signature)" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Content-Type", + "value": "text/plain; charset=\"UTF-8\"" + } + ], + "body": { + "size": 1071, + "data": "LS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UtLS0tLQ0KSGFzaDogU0hBMjU2DQoNClN0YW5kYXJkIG1lc3NhZ2UNCg0Kc2lnbmVkIGlubGluZQ0KDQpzaG91bGQgZWFzaWx5IHZlcmlmeQ0KVGhpcyBpcyBlbWFpbCBmb290ZXINCi0tLS0tQkVHSU4gUEdQIFNJR05BVFVSRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgNS4wLjQgR21haWwgRW5jcnlwdGlvbiBmbG93Y3J5cHQuY29tDQpDb21tZW50OiBTZWFtbGVzc2x5IHNlbmQsIHJlY2VpdmUgYW5kIHNlYXJjaCBlbmNyeXB0ZWQgZW1haWwNCg0Kd3NGY0JBRUJDQUFRQlFKWis3NFlDUkFHeWxVK3drVmRjQUFBZkFrUUFLWXdUQ1FVWDRLMjZqd3pLUEcwDQp1ZTYralN5Z3BrTmxzSHFmbzdaVTBTWWJ2YW8weEVvMVFRUHk5elZXN3pQMzlVQUpaa041RXBJQVJCekYNCjY3MUFBM3MwS3Rrbkx0MEFZZmlUSmRrcVRpaFJqSlpIQkhRY3hra2Fqd3MrM0JyOG9CaWVCNHppMTlHSg0Kb09xanlpMnV4bDdCeTVDU1AyMzhCNkNYQlRnYVlraC83VHBZSkRnRnp1aHRYdHgwYVdCUDloN1RnRVlODQpBWU5tdEdJdFQ2VzJRL0pvQjI5Y1ZzeHl1Z1ZzUWhkZk04REE1TXBFWlkyWmsvK1VIWE4wTDQ1ckVKRmoNCjhISmtSODN2b2l3QWU2RGRrTFFIYllmVnl0U0RaTitLODB4Ti9WQ1FmZGQ3K0hLcEtiZnRJaWcwY1htcg0KK09zb0RNR3ZQV2tHRXFKUmg1N2JleldmejZqbmtTU0pTWDltWEZHNktTSjJ4dWozMG5QWHNsMVduMVh2DQp3UjVUM0wya0R1c2x1RkVSaXEwTm5LRHdBdmVIWkl6aDd4dGptWVJsR1ZOdWp0YTBxVFFYVHlhanhEcHUNCmdaSXFaS2pEVlpwN0NqS1lZUHp2Z1VzaWhQemxneXFBb2RrTXBsL0loWWlkUE1CMTM1bFY0QkJLSHJGMg0KVXJiYjJ0WE1IYTZyRVpvajZqYlMwdXcvTzFmU0JKQVNZZmxySjFNOFlMc0ZDd0JIcE1XV0wzOG9qYm1LDQppMUVIWUlVOEEveTBxRUxQcEtvcmduTE5LaDh0MDVhMDFuclVXZC9lWERLUzFiYkdsTGVSNlIvWXZPTTUNCkFEanZneXdwaUdtcndkZWhpb0t0UzBTckhSdkV4WXg4b3J5MGlMbzBjTEdFUkFyWjNqeWNGOEYrUzJYcA0KNUJuSQ0KPUYyb20NCi0tLS0tRU5EIFBHUCBTSUdOQVRVUkUtLS0tLQ0K" + } + }, + "sizeEstimate": 5805, + "historyId": "1405939", + "internalDate": "1509670425000" + }, + "attachments": {}, + "raw": { + "id": "15f7f5e966792203", + "threadId": "15f7f5e966792203", + "labelIds": ["IMPORTANT", "STARRED", "CATEGORY_PERSONAL", "Label_4", "INBOX"], + "snippet": "-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Standard message signed inline should easily verify This is email footer -----BEGIN PGP SIGNATURE----- Version: FlowCrypt 5.0.4 Gmail Encryption", + "sizeEstimate": 5805, + "historyId": "1405939", + "internalDate": "1509670425000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-15f7f5f098d6bc36.json b/test/source/mock/google/exported-messages/message-export-15f7f5f098d6bc36.json new file mode 100644 index 00000000000..3a9b97a37b4 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-15f7f5f098d6bc36.json @@ -0,0 +1,73 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "15f7f5f098d6bc36", + "threadId": "15f7f5f098d6bc36", + "labelIds": [ + "IMPORTANT", + "STARRED", + "Label_8", + "Label_3", + "CATEGORY_PERSONAL", + "Label_12", + "INBOX" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 5.0.4 Gmail Encryption flowcrypt.com Comment: Seamlessly send, receive and search encrypted email wcFMA+ADv/5v4RgKAQ/", + "payload": { + "partId": "", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "AMCzsaWhLvT1I9D3MUtiK8AZOkKOcQaoGSd2mq5SCZCIGDakUB3Ii8Cg kyxMVL3SBmcv2IZIUPpj1E6axOuKWlqu68U9dHU=" + }, + { + "name": "Openpgp", + "value": "id=6D24791A5B106262B06217C606CA553EC2455D70" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Date", + "value": "Thu, 2 Nov 2017 17:54:14 -0700" + }, + { + "name": "Subject", + "value": "encrypted utf8" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Content-Type", + "value": "text/plain; charset=\"UTF-8\"" + } + ], + "body": { + "size": 1916, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgNS4wLjQgR21haWwgRW5jcnlwdGlvbiBmbG93Y3J5cHQuY29tDQpDb21tZW50OiBTZWFtbGVzc2x5IHNlbmQsIHJlY2VpdmUgYW5kIHNlYXJjaCBlbmNyeXB0ZWQgZW1haWwNCg0Kd2NGTUErQUR2LzV2NFJnS0FRLzhDaGduYmhHWm9QV2x1cmdZSUl2MlFyWTE5aGphVXMzY3B1S01EbER1DQpWRXRSUmt0S3RYMmFRM1VvYThVdWpjNXhiUC90ajRQSTJUcTdIcTJKNmUrZXZKODNRT2tLaFQ5empmYUoNCk1xdXROZVA2VEZEZHRCc3VtZG9MTUVQWGVHUkw1aVExUXBJbGlmZW5JTXNHSTBKUlJZWm5aSklhK2V6Zg0KQWhwL0tyd0swNmJuVDdtb3BtNHpOUmFpMkpSRHBwQ2JzNDg2WGs5RXJPTXRDTEV6V0RaY1ZQRDc2YWdDDQpvVGlSUWpYK0hlSXlQZ0FxWVRGZ1M0bjVPeU9sMjRhbHdId1BBdllWOXVNRW1LZm9XWkFPYzg3bFo1M3YNCm1xbXlqMTRrV010SHdOaGdROEFuY296R2J2KzBqNTIvSkFUSzlVNjA1Y0Y2ZjAvdWM0d3ZkMmpxcGZXWQ0KK3lKdzhFMXdMUjkzb0h2cDBvc3lySFBxNVRGZVFPMkN5THpPaGhac1Q1MGt5WEp1RCtRZmdqN2J1TmVkDQpRUVkyVmU0bnJrWVBnSElNdWtmWFFEajhXMFpDbHVjdDNXQ2c3TTBZV0ppekRuSTlHRTJVTjlWTjRPSG4NCmRmbGUvQWpCQ2lqeFdMeFFxV0NTeXV3Tm1abDJRYUhTK1RyR2o3KzI3R3RzUWMzSlB1MjZENTBhM1BSZw0KSFo5c3JPWUhWUlIxOFBnb1NmdW55U05pbzZGdU1DcmVnK3RQZHMwZE4vWWFwQ2tYbk9TcklXVUdoT3YvDQo1WGFsSXBNSzRJQ2E3bUNtdGdHVjdDOUJXL2x2RHIyakw0by9FMGp5SkhNRjdlVWlteWxHTFU1RVR1MGUNCjN3SkZlbWxMTWxDbGNmc29vN0RqcHYvWkx2N004U3ZCTHdTenI4L2tGMW5Cd1V3RFMxb3YvT1l0bFFFQg0KRC8wWUc0UUdJa2t4TGpLNXBITGxXR0Q5azRWSjB2eE1qZ1Azekk1aExHM1Y5ajltUjNkbTd6bWlVTHBODQoveWVEbFU3djFzZG1oMnM4eDR5Slo1eEphaUw2Z0RQR294S2cwMTdMMUd5Tnpxdm5hOXFvRGMySHhCTWoNCmVnczhSUjZEbzhycWs5cDhFQlhpSTNGbEhIbi81aEc0OU5pL0xOTnhjcWY2ZE9leHRUV3BtNHRGZU1IeA0KOW5BK1BPMk1vRjZvR2tyZ2JPTURVdEtad25RR0N4QTMvWVhndjd3eWEvb0FTMUhZVnZSeDZMYmwxWU1FDQpITTdlNG5ZaUFPZmx3VTJnZXRFdFNYZnUxQ0Q4cDMwRi9Ba08rcUthaXRaRjJMWG1TLzQxeUlqRDY5b1ENCnNZNUVSS1JkTlFUQmtyNWVVaFM2ckZYSUk4U1h0SlZ3K0RZMjlBQWVsWlRJeElKL3pMVzZBaVB5ZFJTcA0KbXU0dmkxL3k3WVdUUTFiV2x2eUlqSFdEUnB3VnY0SzdWTVdJazh3VXEzdVJGNS8yKzRoL2VtY1hjN3BHDQpMdVgrd2lxTVd3OEhqdjM0LzhIbGx0clFSRzM4SnRzVEtDOURQS1RxZXpySWNkUHZ2NFBrVlhHSEx4WWcNCmRGeWZrWXIvYjNtS2lHVnBwdEdFRTFyQ1B6ZzBUQ2Q4Sk5RZ0ZyMDRYcTVnRWxQUDZYQmN2czNKNStoKw0KdUhsYUZzb1BNenRobjgrZU5tdnhpQ0hwZDkyVklibDlWcTYvWnRTUGNKbjRkcnJmdG4zVjF6dlVDNzEyDQo0TE5wMmlpcGRTQXluZmtCUUUwRkp2N205bWJ1bkNhNWFBRVZRN2J4aGdOWDFDcUF0Um1lc2hkOHc3U0ENCm95VHd4TitWc1FVaHg4T01LQi92UTRTUU5OSzJBVmdhS25WWEV0UFdKc3lqMEhVbHdIQjlqalY1TDRJLw0KaTRPb1ZFeTVBTkwyZjA5Y1BlSEdrYmFLYjhzNExUcVpBVTZaeitMZkRmVGp6UHJSRDNxVmNuM0tjd2ozDQo0ZUN2a0JJRXQ4Tko1K1pWSUtoTjNsR0NDYWIrRkpPdGxYYUNMMG9rczdKR2xRbjU3SVBtdG1XQ2FHS2ENClZSaHA0V1Uzb0lWWmtLakkyM3NJV2R0MGwwejFIMXhLaEZWRitMRTRraVEvQ0l3aWZHWUoyUjVlUWk1SQ0KcXRGeFZXeThUNFk0YVdQY2l2NzNQK1JML25EZDNKVT0NCj13bVNXDQotLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tDQoNClRoaXMgaXMgZW1haWwgZm9vdGVyDQo=" + } + }, + "sizeEstimate": 6617, + "historyId": "1406105", + "internalDate": "1509670454000" + }, + "attachments": {}, + "raw": { + "id": "15f7f5f098d6bc36", + "threadId": "15f7f5f098d6bc36", + "labelIds": ["IMPORTANT", "STARRED", "Label_8", "Label_3", "CATEGORY_PERSONAL", "Label_12", "INBOX"], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 5.0.4 Gmail Encryption flowcrypt.com Comment: Seamlessly send, receive and search encrypted email wcFMA+ADv/5v4RgKAQ/", + "sizeEstimate": 6617, + "historyId": "1406105", + "internalDate": "1509670454000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-15f7fcace2d72246.json b/test/source/mock/google/exported-messages/message-export-15f7fcace2d72246.json new file mode 100644 index 00000000000..1b39392540e --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-15f7fcace2d72246.json @@ -0,0 +1,124 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "15f7fcace2d72246", + "threadId": "15f7fcace2d72246", + "labelIds": [ + "Label_17", + "IMPORTANT", + "STARRED", + "Label_3", + "CATEGORY_PERSONAL", + "INBOX" + ], + "snippet": "", + "payload": { + "partId": "", + "mimeType": "multipart/encrypted", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "AMCzsaVCahez44KcMFESFt+eUr6/bxGK0QniBj+Znt7jhbtmbulBwEiU 6wWUlJgNQktMrrNNsMOqq5kJDLFJ" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "Subject", + "value": "[enigmail] encrypted PGP/MIME" + }, + { + "name": "Date", + "value": "Thu, 2 Nov 2017 19:51:56 -0700" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Content-Type", + "value": "multipart/encrypted; protocol=\"application/pgp-encrypted\"; boundary=\"gTs1bjSPE0g6EP73GHCSwKUV373k4TIBx\"" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "application/pgp-encrypted", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "application/pgp-encrypted" + }, + { + "name": "Content-Description", + "value": "PGP/MIME version identification" + } + ], + "body": { + "attachmentId": "ANGjdJ8EH4iYMPUGqyh7OK5tJ_-hBTIbule8WQ41oXO0bJVeSyawwCnFBk2lBop0XCWMvMDgoxm7n4dbr5FCl85cLv2pPaK4Wzpfir3BEgaAkIfZhLGxmy6yl7nFLNW4h5YVI1rveoMtl4nsUQeAeYxTs5veh-hmFJIb0yGLs-bPC-gMzFwNLKSM7G2BUkxa_S-n55VdZPbTK8js7xgPyxlqJzJWVWGtCjNgFQOgoSF2VoLPdT96dlL_sYJqPf0Rhri5dbmu3rhxq8BnRXLULqT-_p8cc6kNFyQgGGYvGOTnMQLMQh9mZRHLuqifIn47sJbxdibutWn1DK0Vdf7o3eHNy1JWHmwpzWpyGHSftmnpKzlleKbFUf2IHCOTzaM", + "size": 12 + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "encrypted.asc", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream; name=\"encrypted.asc\"" + }, + { + "name": "Content-Description", + "value": "OpenPGP encrypted message" + }, + { + "name": "Content-Disposition", + "value": "inline; filename=\"encrypted.asc\"" + } + ], + "body": { + "attachmentId": "ANGjdJ_ZMdRmdVaPWjkUVEHPIAu5TzxAzffEgX_0Y40hQnFWJymuadXf4UJBeX_L6dZC0dCBPzdsfUlKO3eLtomPhMHIDScpg8OyzKiaft07iniPA21cNLsrFxwfxF0eovsJfMMxW3qnGovigbdwxcT5zsykhysMb6STbZWlzKK4cbLCw6FNmP1daHfV4ht8MpTfQfYK-_UhUhk-CaWBDVxbYap8Ozx92SJPwPj9gxKTUZikWP4kUCfR7gqfopb4uHsM9M7g3A5cLwQwBIkB4fB-9xIfLbY1OT8ExoQcyfDJZybLq61iMQwAvoQ_yDTjDumzAlVEZyaDFLe6EFdaN2IQzbWLWXNl_BIGbPbXD1Km7XfxgDmRDfVMUB0ts2c", + "size": 2164 + } + } + ] + }, + "sizeEstimate": 7695, + "historyId": "1406055", + "internalDate": "1509677516000" + }, + "attachments": { + "ANGjdJ8EH4iYMPUGqyh7OK5tJ_-hBTIbule8WQ41oXO0bJVeSyawwCnFBk2lBop0XCWMvMDgoxm7n4dbr5FCl85cLv2pPaK4Wzpfir3BEgaAkIfZhLGxmy6yl7nFLNW4h5YVI1rveoMtl4nsUQeAeYxTs5veh-hmFJIb0yGLs-bPC-gMzFwNLKSM7G2BUkxa_S-n55VdZPbTK8js7xgPyxlqJzJWVWGtCjNgFQOgoSF2VoLPdT96dlL_sYJqPf0Rhri5dbmu3rhxq8BnRXLULqT-_p8cc6kNFyQgGGYvGOTnMQLMQh9mZRHLuqifIn47sJbxdibutWn1DK0Vdf7o3eHNy1JWHmwpzWpyGHSftmnpKzlleKbFUf2IHCOTzaM": { + "data": "VmVyc2lvbjogMQ0K", + "size": 12 + }, + "ANGjdJ_ZMdRmdVaPWjkUVEHPIAu5TzxAzffEgX_0Y40hQnFWJymuadXf4UJBeX_L6dZC0dCBPzdsfUlKO3eLtomPhMHIDScpg8OyzKiaft07iniPA21cNLsrFxwfxF0eovsJfMMxW3qnGovigbdwxcT5zsykhysMb6STbZWlzKK4cbLCw6FNmP1daHfV4ht8MpTfQfYK-_UhUhk-CaWBDVxbYap8Ozx92SJPwPj9gxKTUZikWP4kUCfR7gqfopb4uHsM9M7g3A5cLwQwBIkB4fB-9xIfLbY1OT8ExoQcyfDJZybLq61iMQwAvoQ_yDTjDumzAlVEZyaDFLe6EFdaN2IQzbWLWXNl_BIGbPbXD1Km7XfxgDmRDfVMUB0ts2c": { + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBHbnVQRyB2Mg0KDQpoUUlNQTB0YUwvem1MWlVCQVJBQW1TZm9hWEZiQTB0djB1bEZ4VmlUd3JEVmNiUEhhUFF4eDN2YVgyY0hMQUJlDQpLUzJQMndPZWtxKzhxRC83Mk1NV01VK3Z4MWZiVnUrME1Ea0FFY3lnQ1AxbzU0bUlSOHZZR2twTDcwSmFMeU1GDQowanF5OExLZmhlSk81bytkQllNdjNyazU1L1FsTWdyS1NyWFVtR3IvRUFNNmtMaDZVd1dTL0swMFRGcndtUEF4DQoyYzRuZ1JRTHF5SHlnOURPTEw4eDJTa0JvUFlMSFR5Y0tZMW9NMUNnZHdjTnFqeTVSWER3ck40NFdzOEhSWDU3DQpQS0xnckFNK3ZVdjU4YlRoWVQyb1MxTDJsN3JJcThTMG4yZUZJMjFISFVRRkRBM3JCSkp5dm1oVjRKQXk5QkxpDQpVWXFtQkRqdk10ZGZuOWlCa0ZoemFwT1JxaWdBVWRzNGFUaUJud1dpamdmdXppbFhxOTdPVG1iL0hOVnZQZDBBDQpzWFk4dTFjNnNuQnF1OXZ1c3B1LzJxWFBMWWgwNkgxYVFsTVAxMXEvaFdWZlZMbmo4dkZtWXB3UVJFVmU4Y1hkDQpLVldOOCtoWWlxS29TbXU1bkticXdYTXFlSGpTOUwrRUdaTXlpUmxTd0ltVXErQjlnR01jVEJGUjJFQytPRDNVDQp3ZVdoc2VLOWpJT2lvMG90RjFFRjRwVi8rVlVVMmdQQ1poVXJ5dEdJdHdmY0R4eW8yRFBXVXVuMlNBOUVESDMvDQpwR2Y2T0RVd0NiNjdnTkRERm9SK1krV3hmR0NLSzFDU1BBRUhIbktYVFVQMTQ4M0l6VUhXeFA2UjAreGhneXBRDQovdWZFaFhPVndFamRWK0NUTWxFTmVTTnBRZE50MXR5eTJUTWhsTmQxQTBkblJNaXZ2Z1ZwcWsyaEhIMzhpR2VGDQpBZ3dEbHVBT2xLWFFvNXNCRC93TGVOWmlLSnpuTGE2NVZOekpvdDI4VGM3Qk9aUXlmbXRiakY5SDQ2UlJCOGE4DQpJQ3F1NzhLOFBhZjlRQlAvL1djUEwwUkZ2V2Y0Mms0ZlozZHkzRGdQY3dab3VyWUtKcHZGa2RhaUl1RlExdWE3DQpJZ0g2c0pqVHJ2K2JzQmJDTmxvRlRNZ2xqQmxkbWlTWFNaUGRPamYvQXQ4RVUvRzQ0SXU5Tld6dW93TURnWGlaDQpVZlRVbTNSWGRXWVlpODRXbEwxb01XZE1UckhtdnBkM3MxeWF0NFk3eWFCR3JseHIwVmVwNmhtVUFYdERxRWVwDQpjalByK0JsMHR6WEM5WEo5UkpzQXAwM3BEd0VrZlhpU2ZJUUI5eW9yR0Y0NlhPVCtkUm5pY3drN0hnVVFJa3cxDQpiUDN4c09GcFA0Ujh4ZGEzUVoweVNEbW4zRTRiQWM5VDZMdTBxS0VCcjZjRUNnWlhwN05mSnhwam9RYm5IeGQxDQpxUzBGWG1iVHVIV2FnSmJFU0hxWHRyQkJ6NlVnK0ZvVmg0ZnV4eTUvdTNRRk1hVkZSb0F5QTNQYlVUYk9maUphDQpQTWlXMW5USkc3b2ZzcEtnbXNnK3hGcWc5L2RMZXBnQncyUVUwYXpzYlhQbW1TWEdKRXdsenJydmtLejFFaUs0DQovcDNyNUFnajdTNGpYU1VzREVoV0Ztcm1xWG1qNVN2M0VjQzJKZXcvenlrV0c1Tk9NeHVxNG1QVFd4MWNLMVB1DQpQMWVCbnpYbEhNWldOQnZuNmxEd1B2MUN5UytUNVNyVGp4dUZtSllzNnNQR2lvVklUL2lWbUFWZ2g3Y3RxVjJhDQozZGFQVTViTEVWVkgybTRtY013VUxiUTkrVmMxbElidUc1UGxKdkFZdVJUeTNRRXNHczJWRmQydDhsRytFTkxCDQpCZ0c2RThMbjN6aXFFQ3FRWlY0V0xUbjVmUkd0dEt1QTMvK29zUUJDNTUrdGNQc0trNmoySjRweGFVOEt3SzR6DQpUNDBNS0ZScEJUTlhaUU9FV0V2Tm5ndjNSc00zZHA2RnZWV2dVb1VodTYzNDBIN09xQVN1S2Q5UW9pcUlaalh6DQo0TzcrcVZ6anBKeWtpSnlYb0pEVFhCQ0Y5Qk85U3Z4QURHOUlEVFVzSjFpRllSRGtXSDNqamYyOUUzbDQ3enJ1DQo0UEZuS01Rc0RSVDlVcnRBak5SK0hEMUFaYWtaY3pobGpjUnFsODNyRzdoRFNPakJ3VU1ML2NrcEozSEE0d3gyDQpiZUFONHk4eXdKUEhXYlp4Y1Qvd1psTFp6SW4vMXVzL1FoWXRJZlU4L2hQYVUwTjQ5b01WeTZTVTY0S0E0cmdUDQpqVVZoVW9CSVEzaXZpNmhzMEdBVUFhcGN3ZHVsRWN1dlFFSjFKYlBYTXN0NmFVNUg3M01iaGpZVE5kdUszUVpjDQpYcG9rUU44QVpZTDlwcWJVY1ZpTUxXQnF6bnVGK2JPSU1LTmZ0RW9qOU1WUGJIVkt2SElaWlFyS1ZaYjdVTWNsDQpUY1NzSTBKbSs1ZldrZHJIa0k1MVl4Y3JWYXBOa1QrcEdvK01CelRWdHc3b1o4NDRlVllVbkY0NEFqYURFcjh4DQpSM2xRL0hTaDRIeTZpYlJKMFpHUVpzYkFnMVNMQWcraGc4aHpnMXV1eTlFME1EYUkxNW1kejdGcnNJd2JiaThPDQp1UlRXRFFnTFF0eENZNDV4dlNtVkpxYW5nSWc4cGtRPQ0KPXY2dnMNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg", + "size": 2164 + } + }, + "raw": { + "id": "15f7fcace2d72246", + "threadId": "15f7fcace2d72246", + "labelIds": ["Label_17", "IMPORTANT", "STARRED", "Label_3", "CATEGORY_PERSONAL", "INBOX"], + "snippet": "", + "sizeEstimate": 7695, + "historyId": "1406055", + "internalDate": "1509677516000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-15f7fcb7fabc7511.json b/test/source/mock/google/exported-messages/message-export-15f7fcb7fabc7511.json new file mode 100644 index 00000000000..86f75abccd9 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-15f7fcb7fabc7511.json @@ -0,0 +1,80 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "15f7fcb7fabc7511", + "threadId": "15f7fcb7fabc7511", + "labelIds": [ + "Label_17", + "IMPORTANT", + "STARRED", + "Label_3", + "CATEGORY_PERSONAL", + "INBOX" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Charset: utf-8 Version: GnuPG v2 hQIMA0taL/zmLZUBAQ//RO4wLVr52Zf0v6/fa19/noJFsFLIEqsWkX3OPOZfiRew tcI17dq5u854lbuXwSELEAUkhX0NJ2ZM+jNPRyW4dqhcuFBebBXN10/pzBaG+nKi", + "payload": { + "partId": "", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "AMCzsaU9vkCt3G0OQkWukzGyeozyKVL+YaGn4UCf994KxLSIox7PmP9r m91Xndv+3hZSjwvowIz53KCGETEe" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "Subject", + "value": "[enigmail] encrypted inline" + }, + { + "name": "Date", + "value": "Thu, 2 Nov 2017 19:52:42 -0700" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Content-Type", + "value": "text/plain; charset=utf-8" + }, + { + "name": "Content-Transfer-Encoding", + "value": "quoted-printable" + }, + { + "name": "Content-Language", + "value": "en-US" + } + ], + "body": { + "size": 1716, + "data": "DQotLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS0NCkNoYXJzZXQ6IHV0Zi04DQpWZXJzaW9uOiBHbnVQRyB2Mg0KDQpoUUlNQTB0YUwvem1MWlVCQVEvL1JPNHdMVnI1MlpmMHY2L2ZhMTkvbm9KRnNGTElFcXNXa1gzT1BPWmZpUmV3DQp0Y0kxN2RxNXU4NTRsYnVYd1NFTEVBVWtoWDBOSjJaTStqTlBSeVc0ZHFoY3VGQmViQlhOMTAvcHpCYUcrbktpDQpDSzNCNG1BaHFZZUZBelZlSW5GUzlNUGJwMStYemN5UG0va1BzMm94SVNrNENVR2FGQ2xTVEdGVWRSamR3Vnl0DQowNkJFVng0bzBkdnUwZW01TzRzYm1BcUFpY3RMOUtjN2MrQllSbXZJQkJhdDJ4a0p0b09peDNIbUpCY05SMHczDQpBUXhvQjFwS2tienFPdHdlT2hjUDlvcFN2TzhHWHgrOXZYelNpODhQSjR1TUtPU0ZVYnRLR2F2TXlYWWtLcElzDQpOL2hZaUs0TDBCOC9xY0pTNkxzTTI2bzBrWnNWTWc5cHorQkszWnNwQXlxM1FuTVJHYVZlenpyQStlQTIvR3o4DQpvdTVDVTB0QlhNTGJ1QlBqOHFXQkJnYURKeldCSnlROVZSTnd4MU9FNHlXTitSLzVIMzhmeTZaL0JqOE5pdWVXDQpiU1ZWaFhWZHdQellvRzZXZzA2Q1VTL3V5alRVdFVrR0d5N25vaWk2MTBYTHNPaGZPY3NCY1lPRXdGdVE5RlluDQpuOXgycU1mbzcxY3VXd3REY3hkVUJmR3NvWnpKa24xYXVENlhmSHJKWTVmdXgwSmkrYXYrbmtXdGdSc3UyL0plDQpCRUZpa3VCWUZaeGpXT2lBckdHeWJ6blZaWEU4bThvZ1pXWU1seVFZeWJTaHMrY3RwKzRXeDVvTldCUDRFMEpiDQpUM3FXNkdYU3JlUC9FQ2ZaTlVnZ1BnT05VWW04WUtUWm9XZ3dMK3N4eURsTDZzblpNaWRQNEZyQzM1Qm52UStGDQpBZ3dEbHVBT2xLWFFvNXNCRC85aDZONEtXbEw0MWUwakhKWC8yS2JQWGcxL2NVL1c0dXJkRnhteC9IdTF5OVkvDQpKOVZLWXhuZTNId0piOUJ4TnU2ZzFRSmlyR1NMK040ZEgvYmFSOUJsMDF1UGRSNktaZzA2bHlnV2VWUklNUE8rDQoyeXRsYTlHeDlsditHOGJYTTFhZE5WYkNlUlgvSUx2VTEzU000ck8yZUh2Wm9kQlEvWXlhUWZVT2M1OWlkTkh4DQphWFNEVDE5L2lCVkI2N1h4cS90NEo1bjh4V3QwYjBnQjZwRXpBRG5KOTJpSzFzbzdpdmlTeFdibjBsZDRFOWpmDQpjemFsRkNaQmIySGxxbHQ3cVV5T1F2cVBJdzVZUjVSMjRvNFRGZHRxOER6akxkTmZhejhlSWxIanVoL3J2cHJxDQp4QmhkcWdXRk1jMlY4Yk9QSWtRU21ZZlZRWFBMV2ZsbldWME1IdW9vN1JnVzMzeEQyQVNQS0hwVVgxYnI2NUM0DQpoc3ExZTNSMzJ0WGNPTy9iaDlTb0pLajd2TCtOUDYxUVlrYXJtaDMweWg1WXhOY0pWMzNsa21aLzRBdkY4ZlJhDQplZVRRZEhLZHZKdGdtTWdXdVJTZVIxektTSWFkdnlsR1pvdHFUSTY2MnBmbS96R2pkVmo4Z0pXdmNONFhuQXFJDQprdGczbXBJOG1SUzZ5ekRMY2JXSStxRmtjQWtCZmtLM0hUdzlLcWo1OTZqUXVXYmQwOE9SbTZOeEgyTDQ3QlpFDQpmVjRPaVRtNW1KRm4yZVJha3JTOVVtWWhWa3ZMOWpJVFh3aHFNeTFNajcycXhaVm54NFBTbm44d2dNdDBKZDA0DQozNlFLd3Ntc2w0b2F4QkF0OTVRUVZ1NWEzVVFhOFAvMnZUZGluS2FMVjl2b1FkRlc1bGNPVVBWTzk1NW1zOUp3DQpBUkxJbTI5cHRCa1ZLNk4zZnF1RVFRdHNzUjRadDk3SEs0TzdsL1lpbFJhNW05aVFGYVBJcWFzSEhKYVZ4aEtNDQpaazN6ZlRUTlI4dDMvbW9hU2JvNDViWFFrNFZnbXV4MUFUck5jS2p5SVJpTnFQUnoydGJKSWMySDA1bmFpanNiDQp5VHUzczdDblNFQ01XRjI4M3MyRHRnPT0NCj1sM1dQDQotLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tDQoNCg0K" + } + }, + "sizeEstimate": 6935, + "historyId": "1406044", + "internalDate": "1509677562000" + }, + "attachments": {}, + "raw": { + "id": "15f7fcb7fabc7511", + "threadId": "15f7fcb7fabc7511", + "labelIds": ["Label_17", "IMPORTANT", "STARRED", "Label_3", "CATEGORY_PERSONAL", "INBOX"], + "snippet": "-----BEGIN PGP MESSAGE----- Charset: utf-8 Version: GnuPG v2 hQIMA0taL/zmLZUBAQ//RO4wLVr52Zf0v6/fa19/noJFsFLIEqsWkX3OPOZfiRew tcI17dq5u854lbuXwSELEAUkhX0NJ2ZM+jNPRyW4dqhcuFBebBXN10/pzBaG+nKi", + "sizeEstimate": 6935, + "historyId": "1406044", + "internalDate": "1509677562000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-15f7fd2fd072cff2.json b/test/source/mock/google/exported-messages/message-export-15f7fd2fd072cff2.json new file mode 100644 index 00000000000..73addec5a58 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-15f7fd2fd072cff2.json @@ -0,0 +1,81 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "15f7fd2fd072cff2", + "threadId": "15f7fd2fd072cff2", + "labelIds": [ + "Label_17", + "IMPORTANT", + "STARRED", + "Label_3", + "CATEGORY_PERSONAL", + "Label_4", + "INBOX" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Charset: utf-8 Version: GnuPG v2 hQIMA0taL/zmLZUBAQ/9FX0uRThi4ZT1KmNEZYS3WC+Noqommn5szVhI72E03HUp 3JMub2XMmU80Oe6WybHancEZw3w/oWR5CvdQx9414jub4uXxaE91wBuqlS3Ow6/o", + "payload": { + "partId": "", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "AMCzsaWRAkVD71Q6REZLpGHEsGNfrwfkle+cXoaIDcHAGIqem63MLBlU stIcRQKcw2Ly0r+n23F/BzvuQiZr" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "Subject", + "value": "[enigmail] message encrypted+signed inline" + }, + { + "name": "Date", + "value": "Thu, 2 Nov 2017 20:00:53 -0700" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Content-Type", + "value": "text/plain; charset=utf-8" + }, + { + "name": "Content-Transfer-Encoding", + "value": "quoted-printable" + }, + { + "name": "Content-Language", + "value": "en-US" + } + ], + "body": { + "size": 2566, + "data": "DQotLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS0NCkNoYXJzZXQ6IHV0Zi04DQpWZXJzaW9uOiBHbnVQRyB2Mg0KDQpoUUlNQTB0YUwvem1MWlVCQVEvOUZYMHVSVGhpNFpUMUttTkVaWVMzV0MrTm9xb21tbjVzelZoSTcyRTAzSFVwDQozSk11YjJYTW1VODBPZTZXeWJIYW5jRVp3M3cvb1dSNUN2ZFF4OTQxNGp1YjR1WHhhRTkxd0J1cWxTM093Ni9vDQpYZlhaQXpUMGFFejdqWGtoOXJBWkR6S2p3cUpqRC9VSUNIbVpzZ1ZzeDEvWlpCWU5CcGJoMmVzREZHY0NFK24wDQpoZ2Q1K2VrYk5xWFUxQnlVMGVaUk1vMzB1M2h3NFJBcDNkUGNmSUpPM21UTlVUWGJBdW5IenRidkdGazFUSTJzDQphU3h2SlEvUU50NElSTWFWRzdwbCtHd2MyOHltV2JOT3Y5dlZRUUI4MFRKdDV4N3hKOFM2TWl0b0F6VFowS1RhDQp3ajJCUTlKUE8xZmd4VHc3WmVoYWI1VWhRTEpYc29mZTBXblU3WEl4ekZZeVpkWlNHTnE2dStjSStEZlVIODM2DQpVRFl5RU9obElPeVlmOFNDZDdCM0FUN1dkNC81YzMzM0VDL1duRzdXN2Y4UnNkV0FRdGY4RTZpV0VEZ25HbXZ1DQoydHJ4SFpkVElPaEVxd2d3UFdrVlgwVWpCZEo3VThuQmhQKy9jc24yaDZicHhPQVJGcFhPd2dtbG1qakEvUVFMDQpSZ2FLMFRDeTdKY25RL3Q5U0NHdzYyWVlRc2dGOFJDVVB2bXorS3BaVis5Y2t3T2xqOHZONzVzeEZ0aXRkL0hxDQpoU1ZNVWVJc2dCR3ZvK094RkErTkZMUVR4ZDhUOWhVTnBVMlk3Uld2MEdMcWdRdGo2R0U3eWtoNEk0ZGNiL2dmDQpJQXBGNFhLbnpHbE9Jb0hOVWY5dE9uWThKVitUTGJRbDNoblJYNjRRQ05pbWdsYWdRMHl4ZTNwNWp6WDF1SW1GDQpBZ3dEbHVBT2xLWFFvNXNCRUFDVTNyeDZ1OVhoKzYxRGNwVUhNeGdRNDNLcUVYV3dNcHprOFl1ZFdybU5LTDIzDQphNjUvT1lweUNCc0wvRDArYlZLdkxNaG15ZmF6MDlNM3E1bGg4Nm9OcnZISEZzYkRPS3pIbEFlQkY5eDgrSE9SDQpMQU5qMFRDdHROUjA4ZTRpM0hQYlVUNnVLL2ZLbEhicUE2K2lLZ2JCYWZiZEhKcmVYdEtLUzdnOWVyRVlnQlllDQpFZzE0czdYOHErbkhYWjVzUzgvcHRXVWgzQ29WdFJnQnNZZTZBZ0grNnVEdnRRV3UrbTNOUlpaclRCVWo5NC92DQpCbGtBVjZwdFJiVHNCV1FKWmpSYUtHUXVOMTE1V0JyS0FvUHpJWG9Jay8zTEpTZTF6WlU5a3BtZEo0d3Jhd3NFDQp3Y01SSlNqWVdSMm1qcElLWlphMlVFTWFIU05LRDB0Zk1ZbnQyZXR2bURycnQxZUxNZnpkOE56Mlo0cmo3N2M5DQpyZkk4blFnVG1YNUVhSEpRMFBjSjBIMEpuNTE0Z3ozd09oMUI4ekNEMzRLbFMvd1JsNHYyYmM3TW9kTjBwVFVJDQplb2hOQTRqKzlHYW1KTm9NUGJMR2k3bzBKcWFnTFRQaUY0SnV1RW1WME11L3BqV0tpaWsrU2k2SElkZFhzUDRzDQpXYlBmSVZ3ZU9oQ0tma04xNjFUd1N3KzFjZEhPdytEK1BBeE1PQ3BTRFU4R09WOTR1b1RMMEp0SkVkQWFaSHNqDQpaWmJNR0MrekFUSUt4cG9YSU9OcjVRd3k1MGhIZituWlJRZnZmbjhpbC9GME5veWcwOHBNYWZabUFValdRZ1NtDQp1OWJFM05rVEY3RlhZckorWDI2ODdpLzFLSjdVcmpoSlFGY3oxKzB3YlJtbVNtSmxxcXc3QUpLeHpPN3dSTkxwDQpBWmxZVDJmbDdqTFV2bnEvS2VFaHBVL0hJUThraUhDMzFKOC9TWUJ2dDFzNC8vMCtjeWtBOGJLRUM0M1ZLWjNSDQpwbmNPNVAzTGFzeENNbTZkUGNyV3VSL29OOFVNOHVUUWpVc3hoSmxGNmZOVXYzZ0RxdDBlbTI0Wm9nS3VLcHpTDQpJUFhYOUVHb3RONVh4S2diQ1k2bEFPaUhPakhKMHRmTXBQUXZ0cVAxWTI4bUpqcC94M2tiOHVsNWg0SDZVaWdyDQpCN3U4dEhJYlI4MmdoYnF6RTd2S3JHbGQrMzFoUDdzUkt0aHRkMTdxSlBFdkRmdndXLzZDN3E4RG8yUE9iVnFZDQpScXd6VlduczhtcmtUdXpKZ3pTVWdXQ0hCVS9yRFZ4ZjN1Y1Z1N2JEcUNZa1dWa203YmQ4R3B5MCtha284N1VNDQo5M0ZhL2YvVGVncldHYkZxajJtYW9QZ0JWSENlL2FFTjJNMmR5amVsdHFXOUFUSHllZWxxNFBncU82aTdDRTAwDQpSQzVaS3BkUGtNcnVyb3ZpUCtXcjU5b0l4RVU5WXpUVnd2N0I0aklyM0k5WnhGcnJkejV4SVd3QTNrZkhvQnMwDQp5OEgwMXRrekpWRmxMMHRSVGQ2U1pPQ01hbzlTWEZhMTZTQWQ2Ym9MMnJ6QjRLaFFQbDJLWW9wNGpGUUdQdkJhDQpadGxHZ0k4bWpMNVVIOTRZQU8vcE1RYjVlQjBmWXhuWjVXQ3JqcjNQTWpnL3c5T0I4eTZETDdjcEkxLzlreHFQDQpmUGxuRHYrNlUrOCtjKzk2czUyQzRRSXBkZGVBcXN5RGJpVXYzRDdLZmFqaEYwV0RhZjU5OVlLMVRBeU9SM3RYDQp0bUNxNEp0S1E5K0hlaHp0dndETS92V2YyS3UwaGsvSGpQd0owMWN0L0pMQUdtMVVlWi9qdWhhcVFsZG1PTUJKDQpiaFNIVDlVL2Z5NzJHV05pREFlWDZmNEZhNmFKdU9WS1lqRFVTQWhkZ0dzZmRmclBKN2tKUGNPT3lJKy9jQzFwDQphc3ZmYzlPdkpXeVo3MTZNZDVqMGhUVmZLV2ZYdG5oektjR2w4bnJBNFhZWkdBOCtsWllhbWVmS3pJVm00Nmt3DQpvd3NCMTVOVUk3NzNaRFRkZFNDTDhjNkpRdU90NUswRzYwdzlNMHF4WW91WkVuV1Q0TEU4ZWcxUzYxVnJibDZQDQozeWlHN01EeTJwNi9GbG1DWmdESFFSVXFraXVDR1VWcEN3S2lad056RU1xZS9NTng5ODhkTWtud2FkWEVBdCtJDQpSMXhwa2t5VUREOGNkYmIxDQo9V3JNaQ0KLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQ0KDQoNCg==" + } + }, + "sizeEstimate": 7799, + "historyId": "1406019", + "internalDate": "1509678053000" + }, + "attachments": {}, + "raw": { + "id": "15f7fd2fd072cff2", + "threadId": "15f7fd2fd072cff2", + "labelIds": ["Label_17", "IMPORTANT", "STARRED", "Label_3", "CATEGORY_PERSONAL", "Label_4", "INBOX"], + "snippet": "-----BEGIN PGP MESSAGE----- Charset: utf-8 Version: GnuPG v2 hQIMA0taL/zmLZUBAQ/9FX0uRThi4ZT1KmNEZYS3WC+Noqommn5szVhI72E03HUp 3JMub2XMmU80Oe6WybHancEZw3w/oWR5CvdQx9414jub4uXxaE91wBuqlS3Ow6/o", + "sizeEstimate": 7799, + "historyId": "1406019", + "internalDate": "1509678053000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-15f7fd3ba3f37cf3.json b/test/source/mock/google/exported-messages/message-export-15f7fd3ba3f37cf3.json new file mode 100644 index 00000000000..7401e8cf753 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-15f7fd3ba3f37cf3.json @@ -0,0 +1,125 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "15f7fd3ba3f37cf3", + "threadId": "15f7fd3ba3f37cf3", + "labelIds": [ + "Label_17", + "IMPORTANT", + "STARRED", + "Label_3", + "CATEGORY_PERSONAL", + "Label_4", + "INBOX" + ], + "snippet": "", + "payload": { + "partId": "", + "mimeType": "multipart/encrypted", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "AMCzsaXJgc3mefFxateCLQYptuBMVOZ4fh6PUIFRw1lEiVDQt/Fl51CV ENzcJNCxaDl1Sqvp5dwNXthnbH66" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "Subject", + "value": "[enigmail] encrypted+signed PGP/MIME" + }, + { + "name": "Date", + "value": "Thu, 2 Nov 2017 20:01:41 -0700" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Content-Type", + "value": "multipart/encrypted; protocol=\"application/pgp-encrypted\"; boundary=\"H2AmhlIW7oAFHfcmukpDpEd1f6QdrFED5\"" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "application/pgp-encrypted", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "application/pgp-encrypted" + }, + { + "name": "Content-Description", + "value": "PGP/MIME version identification" + } + ], + "body": { + "attachmentId": "ANGjdJ_CxJsNjFWOK3LuGZUd4ov1tt3sMEWvH5JfoQX9qGaPwGycuPXIMfYOFe41deBBdK3x6lgzZHJBNxHiZjFKRa0ZALcqWBzPBEkNiB2yIZ-PXGcIZBeReZ4f1knicXsL03yjkVfYY5lVb2kTQ12ypu9xlDsj5mQ3e27Ee4Bo1nWIP4gR4bp0g-jgS0McFi8NEhULCkvqDE84IoYdyNFnP0QPU7tC65Z_IH5F5u15fiPlhpYtMIhxJxzGmiXNiByRV6ykp38yFlPLNLNHWBZCuOy_7Pe9ZxZM71dBvXWF6ToIQmfaYl-F_c8_0bkVdEA1weUpmHhAvFGJ4hZEQ9AVNQSm6CR03mymrp2YAzOq2YcYNHrow6fFvG4j4y4", + "size": 12 + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "encrypted.asc", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream; name=\"encrypted.asc\"" + }, + { + "name": "Content-Description", + "value": "OpenPGP encrypted message" + }, + { + "name": "Content-Disposition", + "value": "inline; filename=\"encrypted.asc\"" + } + ], + "body": { + "attachmentId": "ANGjdJ_OEr3mZHLHkK7tsButwfhCTjjspi3QtJPzeWkOIiyd_AJvj5YgCBckucdcclPg63sVkny3VKDsKZIXQ4IsaunagImnZlXZVkAPNr1q-ZruMyBMDymcvM39n4t9c3KjzmoU10sDQVfs8ixTp0TpXqmcq9eRJZ0QAtZG_3fVa0otn_k0wAXm3L4NV7Ht6QMQ4qgKTYJEJY3F0YUkAYCmqP6y_FlIj5d_LCoWrecJdzxx1LWm4E6aBhBjxTJjpFRdWfSLG0nSNS8VI7p_4l44Lk4J3e-Prfb17bKAByXfcF9jUl4bLIkCiRwMmcRhl2ePmRGAPtUROgWIHKwTVRiKm0Nd2zw7qOK4_0vQOVvzm3jUXaskKnDra7LQ4fM", + "size": 3050 + } + } + ] + }, + "sizeEstimate": 8587, + "historyId": "1405999", + "internalDate": "1509678101000" + }, + "attachments": { + "ANGjdJ_CxJsNjFWOK3LuGZUd4ov1tt3sMEWvH5JfoQX9qGaPwGycuPXIMfYOFe41deBBdK3x6lgzZHJBNxHiZjFKRa0ZALcqWBzPBEkNiB2yIZ-PXGcIZBeReZ4f1knicXsL03yjkVfYY5lVb2kTQ12ypu9xlDsj5mQ3e27Ee4Bo1nWIP4gR4bp0g-jgS0McFi8NEhULCkvqDE84IoYdyNFnP0QPU7tC65Z_IH5F5u15fiPlhpYtMIhxJxzGmiXNiByRV6ykp38yFlPLNLNHWBZCuOy_7Pe9ZxZM71dBvXWF6ToIQmfaYl-F_c8_0bkVdEA1weUpmHhAvFGJ4hZEQ9AVNQSm6CR03mymrp2YAzOq2YcYNHrow6fFvG4j4y4": { + "data": "VmVyc2lvbjogMQ0K", + "size": 12 + }, + "ANGjdJ_OEr3mZHLHkK7tsButwfhCTjjspi3QtJPzeWkOIiyd_AJvj5YgCBckucdcclPg63sVkny3VKDsKZIXQ4IsaunagImnZlXZVkAPNr1q-ZruMyBMDymcvM39n4t9c3KjzmoU10sDQVfs8ixTp0TpXqmcq9eRJZ0QAtZG_3fVa0otn_k0wAXm3L4NV7Ht6QMQ4qgKTYJEJY3F0YUkAYCmqP6y_FlIj5d_LCoWrecJdzxx1LWm4E6aBhBjxTJjpFRdWfSLG0nSNS8VI7p_4l44Lk4J3e-Prfb17bKAByXfcF9jUl4bLIkCiRwMmcRhl2ePmRGAPtUROgWIHKwTVRiKm0Nd2zw7qOK4_0vQOVvzm3jUXaskKnDra7LQ4fM": { + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBHbnVQRyB2Mg0KDQpoUUlNQTB0YUwvem1MWlVCQVEvL2ViNDBBbXNSOGRqWkFOaTYzY0N4NHNrMlRJbE5hdVo5T2RucU1FYklJN3NCDQpZb0svMEtEUm5INUkwY05md3BGY21Ya1VoclNMS3RuMCtmeUNyeHJ4by9RWlpPOGZENzhPcVV1M1p3QzNoRlBtDQpPaUxseDlvSTQ4aGozSHJ3LzRDVThGUXRib01BL3FQUExxdGpuSUpMREhRaVpheUNGNlhub2tITkY0Q2ozd3FuDQo0K0duOEFha1VHc0FyN2lVeUlrWisvcFIwVmJQU2dlakZnZGR1OEg5Mjk2bzIxTVIvdEIrRk43REsvTDdmYTY5DQpEWnlMTGRHcDV2UEhVQjNHaWtBdVMvcG95Z2dSYytsU1VhNFQ2anRqVVNBVUd0T1VXdFJnQkZMQWVldUhvc2tYDQo2dHc1QTdPeURCVEd5UVNXSVJiMUo1TjdQNWRYclUvdnQ5N3BRaHJWZ1JYeGZiZXEwT0xrTG05Rzk4dGhFKy9HDQptd3c1Q1ErWk5mUk1vdVB6QkRQVDA1MFRHQjIzSk1UeFR4OG8zYlBMYi9VQ21CMlFodGI5MFhOY1VpeVUzZ3lKDQpQbmtJOTFmS0dmdFQ2YkcvOWxrNzZSdXNabkVxV2hORXN2WFM4S0Y1OXBqM0VhMWNWZW93d1FacS81N0M2cFdRDQpOU0tNUUpJMFczVkNDeXJ4TVhiZWRxYlhmVnVJK21PWXQ0K3lSS3AwbVBXY2VkNGQ1blY2TzhxSUNyZnIzL2trDQpuZDdWdFdxUkw3bkRUYmNQV1pOU1BPUC9ESGo1eVo0dytjcStyT2o1QXRqUnNiV0l0M05SL3BvK2h5eXUzekhEDQpNNEdrdFhxUHh0RFpsMkhzVEM2Z2MwMENGUDh6cVRLcW5EcFFSWitLbDZ4ZnZlbVBRTG16NHBucnpFeUVzYlNGDQpBZ3dEbHVBT2xLWFFvNXNCRC85RU9iTXREYlducXRScElJWVhwM2VzNDdGUEJLZ1I1T3VjL2NydGYzSzluMTY4DQpNcDdLL3R0MUpzckNuTzRvM29qaUlLNk80MElpbHFuaEJOM2hGWWNSUEoybFcyamVmSnZLTzFrc2ppMXE3azZIDQpkbVR6K2pFM21vdytQQW43RCt5MUNWZ1RwdnkrTmcyRG8vNlVSMGRueTRNbTdsWmhIMmwyc0NUSDZGRlhza0JWDQozSXpBd1NPTnR3a3hwdlQ3K01xY3E3azlENVA1aFpUUHVpcDhjaytJRnIvRUtVYUptOGZBblRjYmY1dFJxZ2VwDQpjK1Z5NFF4S1h1NkdnVERId1l3SEx6VmJpUEQ4R0c1Y0FwYnBuOGMrbmZLcWdqR3VhMHp5WWwwRlVkMDIza1p5DQo5YzRXZWJpODNOVk1aRG04LzVTQ0h2Vkp0aUtKYTBicXV4eTFhQk81bkxseHhuSU02SDNvQjFVclFwaWo1b0MxDQprdGFXMDhyd0JTa0RIbmFGTGZXOGJ4ZHlBa2pzaWJhaHZJVzNlcElLNWFMb09pRGtoTUloa0thQnZCT09TVmV0DQpPMDRYSmF1RzJyQWVZRjlKRlY4RnhleE9uY1hCU1pmQkZXSGplTjNiK2NyaUt1RDQxRndMeDFuSWtWSVpZZDZhDQpZWHh2Ynk3aktUTzQrOFh5KzZRdURGUEttVUlSYlNaWjA3bjhENlpzSnp3Y1U0TUlCQ3RoTTMyMG9JRm5EOVc0DQpxNmRrNTZKbWErcldzTGJRb3FoNEkxckoya0ozeVQxalFXQnVBd0xXejVIemRvbXoxUTlpZitTRGxReTlzamwrDQpPK3pLQjM0dmNxZmV0M3diQTQ0UDNST2htYW5CYTFUT29CRyt3a2hoOHh1c0h5SmQ1YVU2QWJ1RW9pNlhydExxDQpBUzMxRjlOVm5Fam5DeWtyQlpJajJCNVRsQzFtVDB5RU5SeUNrcUV2bUJXVmpNL3hmaVcydkJwbUVqLzdySS8zDQpwMGVRYWJieVZTSFhuZ3owSWxBY2gvY1Y4d3A1OHRYa1ZVcFd6bjZHVTBCMUtDeHVjN0Z5UGNkQUFUaE56WlAwDQpSRWh1SVJnakpTUitqNG9rSGdKaEtueGZ2SXhxbHJuS1lOeUdXRXZ2TDYxRDJuQmlSbENQR2wzOENNU2xUOGVQDQo4N2hVMmtzMkk5enR2NGw5WjlPYjYzOW5ZRkJMUTVVbGVzVWdRTkQ2ZCtmSHFrM21kQzZIem0ya0hIQmR1amdsDQpGdWo2NmVHcmZnSHdjTkN0UWlOa1lYY2doNlRtY0lNdkZnT2lFMVB5RTN2NngwNE43STcxY0ZnVU5rb2VvNGtlDQo0ampPZ0dKSkhSRG9mV3ZUR3ZUNEp0Q25vcUxQYWhRV3F0UitCTk1ZNXBoRkVWdHNmdU1ORDZmSlRrellFRHBRDQpCVk0zTm11a1BhdzZMSWpsTjFFbW9lU1gyQmxlcXZ2RElrOXJBdDNpZWtPbGlvWUtxdmsrN3hqUzJPOW90V1g2DQoxNW1IV1J4NjJFdDRSU0FydlJKZEdpVVA2VVRMcUdkODlJbDU3NHBvUVhCTUJEZmtUdmYrRVF3Z3BlYjhXRWhhDQordEZJMmFUTWozbWxnc2tFVVhTeHRPMFpCN2FPUmZDUWl5MkprZjM2cHVFZkh3T3kwbDVZblFzaFhhL3lKQ1FSDQpDSWM0SDhkblN1UWxrZ1JuU09ET25ZR3FwU3FmVS83K01jTTJuYTFqaHNWTFg2TVB6U3I2Yk9TQjNRd1RiR1RrDQpMZE84OWREM2RuTWVIbVZqYUtUZzV3bzZpN2sxRVJFMVVtMmdITWxydFc1OEFaTjRLUEFCcDA3QlhnVjRIN1A5DQpya0lCUDQyY2ZrUG9VTkpYZDBCQ0dFaU9nNC9OY1RqU2cxL3ZXdUF2bVdFTjI4c0FCZk84MWQ3dWNHWnR0MUpzDQp1eUhwVm11bW9TRC9pMXdvUjU4aXdTUGQ1TDNhNEF4K0JDZzd0MHlUUC9QSlJ0WDdodlNoM0Zhak5rRStleFNxDQpKWlBMcTVDWUFQTmFnQldZK1l6UldUSkN6OW5DK3B1T3B4WjA4eC9kelg0QUVjd3ZBRzhwZzArK0JvN0p3RGQ2DQo4dG0wSTVMVVhYbS8vVmYzQVFmMEdUZnBNNjFicnUrVHl2anZSaG1RSjhTNXF3b3phelp0ckpVcERRSkRLaFBZDQorZU1IZ3JsQkRUSHRYVkxYZlQwcUtoZnQxVU5YQ1kydi9VVXE0QzUvTmptMUtIZk1ueWRoSGcrdnpFZzltRTRXDQoybWRiV1ZTejUzWGRmekJzcEFZRTg4RUlULzhXMmJpZWJsbFdJdXhiMS9JYklwbmtWMHU1R2phME9CNWNWVm15DQo2NHpOT09rNXNnT0lsc0VncGd4QVU4bkhybm1nOTU4NVhpU2pUU01BZmI1aDJ6YlFVMHNFa09IdkFEbm44QXN4DQpFV00waXF1SzdscE1hUUtwRTU1NFVnQmNETWpiWm5oc3MxdFpmNXV6NlNYNFlFSTJ5NjRrSUhYaVRFTDZzcWorDQpvMVhXa3E5U0RaT3V2YnErVU9nQjZ5YVh3WnIrQjFmajZmR3Fvenl5K0hiVGRnMVkyYS9iVE9HNytyTS9kbCs5DQo3QlVWWnNDaUY1Q3MrVlJMTm1JcGZwSDgwVTRBR0hvVHlBVHN5YmlIOVpDWm44cXNGbVoyaE5wZVdHck0vYlFVDQo5M1dlMEc1bG11bjFxZDM0N1VobmNFdmZodHl0NDQ5aUh5dFdlYmV4ekRxRE1MZnVvNUJadFZmZS9YSkZocmlQDQoyekZMZTlnWnUvT2pNK2w2VGg2VUdKMDFqclVtcUtJMXZlYWkyeTRqcXpxUlpiU2cyRWluQkFwKzFoST0NCj1GZ01SDQotLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tDQo", + "size": 3050 + } + }, + "raw": { + "id": "15f7fd3ba3f37cf3", + "threadId": "15f7fd3ba3f37cf3", + "labelIds": ["Label_17", "IMPORTANT", "STARRED", "Label_3", "CATEGORY_PERSONAL", "Label_4", "INBOX"], + "snippet": "", + "sizeEstimate": 8587, + "historyId": "1405999", + "internalDate": "1509678101000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-15f7ffbebc6ba296.json b/test/source/mock/google/exported-messages/message-export-15f7ffbebc6ba296.json new file mode 100644 index 00000000000..59dfe182cc6 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-15f7ffbebc6ba296.json @@ -0,0 +1,98 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "15f7ffbebc6ba296", + "threadId": "15f7ffbebc6ba296", + "labelIds": [ + "IMPORTANT", + "STARRED", + "Label_3", + "SENT", + "INBOX" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 5.0.4 Gmail Encryption flowcrypt.com Comment: Seamlessly send, receive and search encrypted email wcFMA+ADv/5v4RgKAQ/+K2rrAqhjMe9FLCfklI9Y30Woktg0Q/", + "payload": { + "partId": "", + "mimeType": "multipart/alternative", + "filename": "", + "headers": [ + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Date", + "value": "Thu, 2 Nov 2017 20:45:37 -0700" + }, + { + "name": "Subject", + "value": "missing checksum" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Content-Type", + "value": "multipart/alternative; boundary=\"001a113e58a0117b3a055d0bf06a\"" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/plain; charset=\"UTF-8\"" + } + ], + "body": { + "size": 2905, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgNS4wLjQgR21haWwgRW5jcnlwdGlvbiBmbG93Y3J5cHQuY29tDQpDb21tZW50OiBTZWFtbGVzc2x5IHNlbmQsIHJlY2VpdmUgYW5kIHNlYXJjaCBlbmNyeXB0ZWQgZW1haWwNCg0Kd2NGTUErQUR2LzV2NFJnS0FRLytLMnJyQXFoak1lOUZMQ2ZrbEk5WTMwV29rdGcwUS94ZTcxRVZ3NldPDQp0VkQvVksreHY0Q0h6aStIb2p0RTBVMkYrdnFvUFNPMHE1VE45Z2lLUE1UaUsyNVBuQ3pmZDdRK3pYaUYNCmorNVJTSFRWSnhDNjJxTEhodEtzQVF0QzRhc3ViOGNRSUZYYlp6M05zNCs3akt0U1dQY1JxaEtUdXJXdg0KWFZIMFlBRkpEc0ZZbzI2cjJWOWMrSWUwdW9RUHg4Z3JhRUdwS085R3RvUWpYTUtLMzJvQXB1QlNTbG1TDQpRK254eXhNeDFWK2d4UDRxZ0dCQ3hxa0JGUllCL1ZlNnlnTkhMMUt4eENWVEV3OXBnbnhKc2NuODlJaW8NCmRPNnFaOUVnSVYwUFZRTjBZdzAzM01UZ0FoQ0h1bmxFL3FYdkR4aWI0dGRpaG9Oc0xOMHE1a2RPZWlNVw0KK250bTNrcGhqTXBRNlRNQ1VHdGRTN1Vtdm5hZForZGg1czc4NU04UzlvWTY0bVFkNlF1WUEyaXkxSVF2DQpxM3pwVzQvYmEyZ3FMMzZxQ0N3L09hcnVYcFE0TmVCcjNoTWFKUWpXZ2VTdU1zUW5OR1lVbjVObjErOVgNCnd0bGl0aE84ZUxpM00xZGcxOWRwRGt5OENhY1dmR2dIRDdTTnNaMnpxRnF5ZDFxdGRGY2l0NXluUVVIUw0KSWlKS2VVa25HdjFkUUFuUFBKMUZkWHl5cUMvVkRCWkc2Q05kbnhqb25tUURSaDFZbHFOd1NubXJSL1N5DQpYN24rbkdyYSsvMEVISlc2b2hhU2RlcDJqQXdKRGVscS9ESTFscWlOMTZaWEoyL1dINnBJdEE5dG1rTFUNCjYxUVV6NnF3UEFuZDB0Nml5L1lrT2kyL3MxK2R3QzBEd09jWm9VUEY4YlRCd1V3RFMxb3YvT1l0bFFFQg0KRC80NnJDUFJaclgzNGlwc2VUa1p4dHczWVBoYk5rTkhvOTVNemg5bHBlYWFaSXF0VWcyeWlGVW5od0xpDQp0WXd5QkNrWENiOTJsMUdYWHhHU212U0xEU0tmUWZJcFowclY1ajUwTVlLSXBqU2VKWnlILzNxUCtKWHYNClo0N0dzVHAwejUvb05hdTVYUXd1aExoVXRSb1pkMVdTOWFoU0oxYWtpS2VZSnJvTGJUZzEwZmpMMjV5cA0KaWFvVjE2U3FLQTFIL0pPdWo2bFQ1ejFudWV6MzVKamVTcFVjN2tzZG90NjBab3ZNZldDK09HUm5rWUtiDQo3S3hGZDd1YXhMNnVPQk9GeXZSeFllb2hLZDczYVZraUtwY1dkNG9ySTE4RmhsZnRGTkF3SWRzbWZ6TmMNCm16VEhaYVVsODlpWXhFS1I2YWU2QUt3czF3ekxxMG5vYXJzZjJlS0JWYlRTZm1LM1MzeEZxZHVLSU5uYw0KZTVZYjNGNWFkU2oxZFVqbTFCWjRhcXpzZ0t5QmIrSjhrZUc5RVNzbkZPeXhPSVVYRE0xbklvMUlPZ3pDDQpNOTI4SmI5R1ZhK3VoZFhScmI1Y0xqVGloVHVzSk4wSThvSnJ3S2t3SXBDSlZnUE1kRExrZXVick1CUTQNCmZicGw0Vjc2c09VMk54KzZuRzJGbkZCRkJGb2hPTCswblRLNS82TnM5YXRlTjdLOVZQKytRY29lcWZQaw0KSVVPMytsQ1pXK3RyVFN2dkZJZDN6aVVWc1BUZXVBUys3bnhTTWZXWi9LOUNpNlFWL1hueDNGL3FTbXVTDQpBVW00elBRMUVqWmYxTi81Syt2aGNDVE40TU14NDA2VmxxdGVka1hMMktQd1o2akRTL3d3OFJmY21QbkQNCnM5NGN0MFdDWlp0TmxuUXErNWgweWJ3VEpOTEMyUUZ5cmhoUHF6dFZZOTVuOUxhMk13NVdJVENXemcvZA0KSUJVY2VXL093SFl0ZVB5YVNRa0NuZWdEdy8ybU4yL0dDOGQwT2x3VUxjVFlHNnVWZW5HdjJVT1ViQ3IzDQpQZnkvRWIvVnFVRVpLMDBQZHZWUVY3RldZQXNodVRGUFRxaWRwaDA0Q2dRdkJwaTNTREVFbzhTa0VJRlMNCi9pRWVSUWFXakZFWEtVSTNGd0tYUEpRV3ZGcGJyWEJPQWpueFhYYkFGWU9MeGR5ZG1xMUdWbDlNbTNHVQ0KQ2xjOWc2dDl2YVlEQlB4MmdONTYyL0NNL25UOFZxNDVWSGU3OVhrcnJjSER3TG43eWVISlNjTkZzaWIrDQpWdndUUG9VZnRsaEMvYWkyMUQ0MDNUc0pwbTdabVBjRGphZ29JY1hyUy9sTjAzejc5UkJtU0tGdFlpWFcNCjRvYmtLU0dvdzYxdk1CaDIvWExWWUtKS3BZS20vR25WbEp4QTB6UVZsNTU4eDhJL25BTWF4U3p3eCtaWQ0Kd2FWVS9zNVBMWjdHaGczTU9ndWlSVGxmbEtVUXlMMEE3TlI0Nk9qRmdVbkhBWlJ4cjRLTzNHb3hWUHk0DQpYTGVTNCtXbDY4czdRbFY2V0YxSUtDSFdFVU1FZVJSZWEyL092dmxTL29MczJNTk5XRGVtbEo0U2lYSGYNCnhJTlUzOFR4bzg0QTAwTkFMYktwcHNTeXk5R3dqLy9yTy9GY2VydXBrZmV1T205bkhGd0lRZWVDNWJXRA0KbW1SbEM5MHIyalk4Z00vdjNKank5aDhQYlhXeGg5TVVwYzcva0FjVHdkR2xNeGlWakUyOXAwNjVxVFJyDQpPaTZzSjdwV3VZVGZXbGRacVRWbWFCamx2MHp1WFE4RW84by9VU3ZvVHMrb2loWUlNY3FSZXFkZXFyL04NCmUrc0R0WUtSZy9MS3AvSko1bkFRelZNUDY3RHhrZ3dMTnh4MGlqQkx5c2FRbXZSbHNpWVdheXhaQjFYZA0KQnhBMmJqWlJ2c213dytoZ1NLTmxjc2l1YkpHQnFmcXZnbWxlYlp1SkhIU0MxTDZtZE1ZZ2NpaEttWUFqDQpwK0hGTHlxZ3llUlZNZGpSSGNyRWR4TlBHNGZKbWxrMWJZaVZRUTRYQWQ3MncrQUhTL3NlWjVIemJBSzANCm9tdUhZVUQ1UFRFcVoxSzlKT2JTc2gzWE1Va0pLK3ozQm5yT3huVE9PeUcycis0Rnhpekg2cmZ6L1BnZw0Kc1B4cXhFOUVMVWxnUWU4cGxjUEZnZTZhTjl0VW9TZSt2TXREYUVBcUt3OUp3b2ZCRjdqbHhUcU1NdlFDDQpnV2JuOXgzVzVvNFZybnBqWUd0UGw4c2gxUVJFdTBBKzBQVUpBS0w0QTNHU01ZUm91R2V3TFNNTkpsT2cNCi8wcFBGNnFCK0ZpNEdKN2p1NUMwN3Rmcjl6OVVxUmowOWtEWEp1b0pkOTVOZFNpQ3o2bmR1Z242Z3M4Qg0KUWYvWFB4WlZlZmVNTGlCNnA4cEcwaVovamNKanlZSkx0VGc2a0ErMS9mZm1KUGZILzc2WkE5ZGdFSkxqDQovVzJ1MExwNE5ZOGN3cWNYdUdLZ2w3MlRWSjM0SWF3bDM1WTB5cjQ3ay83WTF2RVE1UTNiVDdIUDVBPT0NCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg==" + } + }, + { + "partId": "1", + "mimeType": "text/html", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/html; charset=\"UTF-8\"" + }, + { + "name": "Content-Transfer-Encoding", + "value": "quoted-printable" + } + ], + "body": { + "size": 11313, + "data": "PGRpdiBkaXI9Imx0ciI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLTwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5WZXJzaW9uOiBGbG93Q3J5cHQgNS4wLjQgR21haWwgRW5jcnlwdGlvbsKgPC9zcGFuPjxhIGhyZWY9Imh0dHA6Ly9mbG93Y3J5cHQuY29tLyIgcmVsPSJub3JlZmVycmVyIiB0YXJnZXQ9Il9ibGFuayIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPmZsb3djcnlwdC5jb208L2E-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-Q29tbWVudDogU2VhbWxlc3NseSBzZW5kLCByZWNlaXZlIGFuZCBzZWFyY2ggZW5jcnlwdGVkIGVtYWlsPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-d2NGTUErQUR2LzV2NFJnS0FRLys8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPksycnJBcWhqTWU5RkxDZmtsSTlZMzBXb2t0ZzBRLzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-eGU3MUVWdzZXTzwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij50VkQvVksreHY0Q0h6aStIb2p0RTBVMkYrPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij52cW9QU08wcTVUTjlnaUtQTVRpSzI1UG5DemZkN1E8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPit6WGlGPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPmorPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij41UlNIVFZKeEM2MnFMSGh0S3NBUXRDNGFzdWI4Y1E8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPklGWGJaejNOczQrN2pLdFNXUGNScWhLVHVyV3Y8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-WFZIMFlBRkpEc0ZZbzI2cjJWOWMrPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5JZTB1b1FQeDhncmFFR3BLTzlHdG9RalhNS0szMm88L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPkFwdUJTU2xtUzwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5RK254eXhNeDFWK2d4UDRxZ0dCQ3hxa0JGUllCLzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-VmU2eWdOSEwxS3h4Q1ZURXc5cGdueEpzY244OUlpPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5vPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPmRPNnFaOUVnSVYwUFZRTjBZdzAzM01UZ0FoQ0h1bjwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-bEUvcVh2RHhpYjR0ZGlob05zTE4wcTVrZE9laU1XPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPitudG0za3Boak1wUTZUTUNVR3RkUzdVbXZuYWRaKzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-ZGg1czc4NU04UzlvWTY0bVFkNlF1WUEyaXkxSVF2PC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPnEzenBXNC9iYTJncUwzNnFDQ3cvPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5PYXJ1WHBRNE5lQnIzaE1hSlFqV2dlU3VNc1FuTkc8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPllVbjVObjErOVg8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-d3RsaXRoTzhlTGkzTTFkZzE5ZHBEa3k4Q2FjV2ZHPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5nSEQ3U05zWjJ6cUZxeWQxcXRkRmNpdDV5blFVSFM8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-SWlKS2VVa25HdjFkUUFuUFBKMUZkWHl5cUMvPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5WREJaRzZDTmRueGpvbm1RRFJoMVlscU53U25tclI8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPi9TeTwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5YN24rbkdyYSsvPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij4wRUhKVzZvaGFTZGVwMmpBd0pEZWxxLzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-REkxbHFpTjE2WlhKMi9XSDZwSXRBOXRta0xVPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjYxUVV6NnF3UEFuZDB0Nml5L1lrT2kyL3MxKzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-ZHdDMER3T2Nab1VQRjhiVEJ3VXdEUzFvdi88L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPk9ZdGxRRUI8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-RC88L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjQ2ckNQUlpyWDM0aXBzZVRrWnh0dzNZUGhiTmtOSDwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-bzk1TXpoOWxwZWFhWklxdFVnMnlpRlVuaHdMaTwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij50WXd5QkNrWENiOTJsMUdYWHhHU212U0xEU0tmUWY8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPklwWjByVjVqNTBNWUtJcGpTZUpaeUgvM3FQK0pYdjwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5aNDdHc1RwMHo1Lzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-b05hdTVYUXd1aExoVXRSb1pkMVdTOWFoU0oxYWtpPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5LZVlKcm9MYlRnMTBmakwyNXlwPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPmlhb1YxNlNxS0ExSC88L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPkpPdWo2bFQ1ejFudWV6MzVKamVTcFVjN2tzZG90Njwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-MFpvdk1mV0MrT0dSbmtZS2I8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-N0t4RmQ3dWF4TDZ1T0JPRnl2UnhZZW9oS2Q3M2FWPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5raUtwY1dkNG9ySTE4RmhsZnRGTkF3SWRzbWZ6TmM8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-bXpUSFphVWw4OWlZeEVLUjZhZTZBS3dzMXd6THEwPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5ub2Fyc2YyZUtCVmJUU2ZtSzNTM3hGcWR1S0lObmM8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-ZTVZYjNGNWFkU2oxZFVqbTFCWjRhcXpzZ0t5QmIrPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5KOGtlRzlFU3NuRk95eE9JVVhETTFuSW8xSU9nekM8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-TTkyOEpiOUdWYSs8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPnVoZFhScmI1Y0xqVGloVHVzSk4wSThvSnJ3S2t3STwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-cENKVmdQTWRETGtldWJyTUJRNDwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5mYnBsNFY3NnNPVTJOeCs8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjZuRzJGbkZCRkJGb2hPTCswblRLNS88L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjZOczlhdGVON0s5VlArK1Fjb2VxZlBrPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPklVTzMrbENaVys8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPnRyVFN2dkZJZDN6aVVWc1BUZXVBUys8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjdueFNNZldaL0s5Q2k2UVYvWG54M0YvcVNtdVM8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-QVVtNHpQUTFFalpmMU4vNUsrPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij52aGNDVE40TU14NDA2VmxxdGVka1hMMktQd1o2akQ8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPlMvd3c4UmZjbVBuRDwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5zOTRjdDBXQ1padE5sblFxKzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-NWgweWJ3VEpOTEMyUUZ5cmhoUHF6dFZZOTVuOUxhPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij4yTXc1V0lUQ1d6Zy9kPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPklCVWNlVy9Pd0hZdGVQeWFTUWtDbmVnRHcvPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij4ybU4yLzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-R0M4ZDBPbHdVTGNUWUc2dVZlbkd2MlVPVWJDcjM8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-UGZ5L0ViLzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-VnFVRVpLMDBQZHZWUVY3RldZQXNodVRGUFRxaWRwPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5oMDRDZ1F2QnBpM1NERUVvOFNrRUlGUzwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij4vPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5pRWVSUWFXakZFWEtVSTNGd0tYUEpRV3ZGcGJyWEI8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPk9Bam54WFhiQUZZT0x4ZHlkbXExR1ZsOU1tM0dVPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPkNsYzlnNnQ5dmFZREJQeDJnTjU2Mi9DTS88L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPm5UOFZxNDVWSGU3OVhrcnJjSER3TG43eWVISlNjTjwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-RnNpYis8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-VnZ3VFBvVWZ0bGhDLzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-YWkyMUQ0MDNUc0pwbTdabVBjRGphZ29JY1hyUy88L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPmxOMDN6NzlSQm1TS0Z0WWlYVzwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij40b2JrS1NHb3c2MXZNQmgyL1hMVllLSktwWUttLzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-R25WbEp4QTB6UVZsNTU4eDhJL25BTWF4U3p3eCs8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPlpZPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPndhVlUvPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5zNVBMWjdHaGczTU9ndWlSVGxmbEtVUXlMMEE3TlI8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjQ2T2pGZ1VuSEFaUnhyNEtPM0dveFZQeTQ8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-WExlUzQrPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5XbDY4czdRbFY2V0YxSUtDSFdFVU1FZVJSZWEyLzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-T3Z2bFMvb0xzMk1OTldEZW1sSjRTaVhIZjwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij54SU5VMzhUeG84NEEwME5BTGJLcHBzU3l5OUd3ai88L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPi9yTy9GY2VydXBrZmV1T205bkhGd0lRZWVDNWJXRDwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5tbVJsQzkwcjJqWThnTS88L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPnYzSmp5OWg4UGJYV3hoOU1VcGM3Lzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-a0FjVHdkR2xNeGlWakUyOXAwNjVxVFJyPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPk9pNnNKN3BXdVlUZldsZFpxVFZtYUJqbHYwenVYUTwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-OEVvOG8vVVN2b1RzK29paFlJTWNxUmVxZGVxci9OPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPmUrc0R0WUtSZy9MS3AvPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5KSjVuQVF6Vk1QNjdEeGtnd0xOeHgwaWpCTHlzYVE8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPm12UmxzaVlXYXl4WkIxWGQ8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-QnhBMmJqWlJ2c213dys8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPmhnU0tObGNzaXViSkdCcWZxdmdtbGViWnVKSEhTQzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-MUw2bWRNWWdjaWhLbVlBajwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5wKzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-SEZMeXFneWVSVk1kalJIY3JFZHhOUEc0ZkptbGsxPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5iWWlWUVE0WEFkNzJ3K0FIUy9zZVo1SHpiQUswPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPm9tdUhZVUQ1UFRFcVoxSzlKT2JTc2gzWE1Va0pLKzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-ejNCbnJPeG5UT095RzJyKzRGeGl6SDZyZnovUGdnPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPnNQeHF4RTlFTFVsZ1FlOHBsY1BGZ2U2YU45dFVvUzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-ZSt2TXREYUVBcUt3OUp3b2ZCRjdqbHhUcU1NdlFDPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPmdXYm45eDNXNW80VnJucGpZR3RQbDhzaDFRUkV1MDwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-QSswUFVKQUtMNEEzR1NNWVJvdUdld0xTTU5KbE9nPC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPi8wcFBGNnFCKzwvc3Bhbj48d2JyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-Rmk0R0o3anU1QzA3dGZyOXo5VXFSajA5a0RYSnVvPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5KZDk1TmRTaUN6Nm5kdWduNmdzOEI8L3NwYW4-PGJyIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48c3BhbiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-UWYvWFB4WlZlZmVNTGlCNnA4cEcwaVovPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5qY0pqeVlKTHRUZzZrQSsxL2ZmbUpQZkgvPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij43NlpBOWRnRUpMajwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij4vPC9zcGFuPjx3YnIgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij5XMnUwTHA0Tlk4Y3dxY1h1R0tnbDcyVFZKMzRJYXc8L3NwYW4-PHdiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPmwzNVkweXI0N2svN1kxdkVRNVEzYlQ3SFA1QT09PC9zcGFuPjxiciBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI-PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS08L3NwYW4-PGJyPjwvZGl2Pg0K" + } + } + ] + }, + "sizeEstimate": 15939, + "historyId": "1406074", + "internalDate": "1509680737000" + }, + "attachments": {}, + "raw": { + "id": "15f7ffbebc6ba296", + "threadId": "15f7ffbebc6ba296", + "labelIds": ["IMPORTANT", "STARRED", "Label_3", "SENT", "INBOX"], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 5.0.4 Gmail Encryption flowcrypt.com Comment: Seamlessly send, receive and search encrypted email wcFMA+ADv/5v4RgKAQ/+K2rrAqhjMe9FLCfklI9Y30Woktg0Q/", + "sizeEstimate": 15939, + "historyId": "1406074", + "internalDate": "1509680737000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-1600f39127880eed.json b/test/source/mock/google/exported-messages/message-export-1600f39127880eed.json new file mode 100644 index 00000000000..5dc28d7900b --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-1600f39127880eed.json @@ -0,0 +1,208 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "1600f39127880eed", + "threadId": "1600f39127880eed", + "labelIds": [ + "IMPORTANT", + "STARRED", + "Label_25", + "Label_3", + "CATEGORY_PERSONAL", + "INBOX" + ], + "snippet": "", + "payload": { + "partId": "", + "mimeType": "multipart/encrypted", + "filename": "", + "headers": [ + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Subject", + "value": "Compatibility test email" + }, + { + "name": "Thread-Topic", + "value": "Compatibility test email" + }, + { + "name": "Thread-Index", + "value": "AdNqL2dEjOWpYlfLRJy0MJqgS/rz/w==" + }, + { + "name": "Date", + "value": "Thu, 30 Nov 2017 23:18:05 +0000" + }, + { + "name": "Accept-Language", + "value": "en-US" + }, + { + "name": "Content-Language", + "value": "en-US" + }, + { + "name": "X-MS-Has-Attach", + "value": "yes" + }, + { + "name": "X-MS-TNEF-Correlator", + "value": "" + }, + { + "name": "x-ms-publictraffictype", + "value": "Email" + }, + { + "name": "x-microsoft-exchange-diagnostics", + "value": "1;DM5PR05MB3321;6:m2nvFEcpnALTj6KYk8A3Z8/wSex5pOST96zQv+PgzJPP0ecX1RGS6+qzfmQ7UfFkBHN7eS2HgGtg1/Bcu78HASoo7yewtRp5+OrUHvcQ0Qi4DbSOz/JomqyINLzRvWFh0CIFWpF/ENAwIRjUck3BsVC7l2ni4FsJomfQYmRibAOm+XY1Xh8OCa+thEeLnk21l3fEBez9CtK6uwCk/4bh+TqW0DPjZ2CU36w9VJjTD4IBoqnVlWCAoV728OIxFtJ7;5:gV3DgQE/HMBBDE08qVManBvw/p5HVcs6D60IxPhVSs+4nVvrK1EyqIa6hMmaCKX2uPqEjUvnBXbfsFY+o4D/3hoQVAWHzx/b81lC638s4o+e362u9jvGe/DqMLazn+1IT6GgECxjEKMY0sb79xzLXvbnVwS/4G/9vKTE8dhPi+Y=;24:tx2+YH3CVZdyGARf9hdmBe5y4/VTcQ2a0RXmkGUEp+7Ht2jD1HzgPJMfmBvqT2RQ2s+msq9x5M9pqxeglrweN934ZYa5aod2wbxDo3EkRFo=;7:h2eQsleuWf1xW7cvr6Hx198W9iuz2pLRNFZNL9gdQkwGmv8A8FY3hK1bGBixTLUkdjMydv3zfDTuTycYFEWW8PX3Gxviq/eL/1r3FpsBJ3EflzoJ8lUeLMkshmJf+XsMwWchUqB77O3R0NDdbhSSgpYIxS8G7xc7IYhswp3oYmrKUHsmsrnkYwX3oy3G7dHjZowXdfF5jEcMH9pVoGPKKZYi0IDd96VxUs7dv34EeIuq1LsE0R9b3sZWofVRQdi5" + }, + { + "name": "x-ms-exchange-antispam-srfa-diagnostics", + "value": "SSOS;" + }, + { + "name": "x-ms-office365-filtering-correlation-id", + "value": "919ee7c6-e026-40fe-b29c-08d538489c53" + }, + { + "name": "x-microsoft-antispam", + "value": "UriScan:;BCL:0;PCL:0;RULEID:(5600026)(4604075)(4534020)(4602075)(4603075)(4627115)(201702281549075)(2017052603286)(49563074);SRVR:DM5PR05MB3321;" + }, + { + "name": "x-ms-traffictypediagnostic", + "value": "DM5PR05MB3321:" + }, + { + "name": "x-microsoft-antispam-prvs", + "value": "" + }, + { + "name": "x-exchange-antispam-report-test", + "value": "UriScan:;" + }, + { + "name": "x-exchange-antispam-report-cfa-test", + "value": "BCL:0;PCL:0;RULEID:(102415395)(6040450)(2401047)(8121501046)(5005006)(93006095)(93001095)(3231022)(3002001)(10201501046)(6041248)(20161123558100)(20161123555025)(20161123564025)(20161123562025)(20161123560025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(2016111802025)(6072148)(6043046)(201708071742011);SRVR:DM5PR05MB3321;BCL:0;PCL:0;RULEID:(100000803101)(100110400095);SRVR:DM5PR05MB3321;" + }, + { + "name": "x-forefront-prvs", + "value": "05079D8470" + }, + { + "name": "x-forefront-antispam-report", + "value": "SFV:NSPM;SFS:(10009020)(6009001)(39830400002)(376002)(366004)(346002)(199003)(189002)(1361003)(3280700002)(99936001)(3660700001)(478600001)(53936002)(6506006)(6436002)(2351001)(105586002)(106356001)(8676002)(7116003)(316002)(81156014)(81166006)(2501003)(621065002)(2906002)(14454004)(101416001)(6916009)(54356011)(97736004)(74316002)(305945005)(7736002)(9686003)(39060400002)(3846002)(102836003)(7696005)(6116002)(86362001)(4270600006)(99286004)(73894003)(25786009)(55016002)(33656002)(5640700003)(66066001)(3480700004)(2900100001)(77096006)(8936002)(68736007);DIR:OUT;SFP:1101;SCL:1;SRVR:DM5PR05MB3321;H:DM5PR05MB3324.namprd05.prod.outlook.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en;" + }, + { + "name": "spamdiagnosticoutput", + "value": "1:99" + }, + { + "name": "spamdiagnosticmetadata", + "value": "NSPM" + }, + { + "name": "Content-Type", + "value": "multipart/encrypted; protocol=\"application/pgp-encrypted\"; boundary=\"=-=r0qLQ2SG/GIupk=-=\"" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "X-OriginatorOrg", + "value": "stresearch.com" + }, + { + "name": "X-MS-Exchange-CrossTenant-originalarrivaltime", + "value": "30 Nov 2017 23:18:05.2918 (UTC)" + }, + { + "name": "X-MS-Exchange-CrossTenant-fromentityheader", + "value": "Hosted" + }, + { + "name": "X-MS-Exchange-CrossTenant-id", + "value": "ef5b6252-b9a8-467b-a557-2d798f439afd" + }, + { + "name": "X-MS-Exchange-Transport-CrossTenantHeadersStamped", + "value": "DM5PR05MB3321" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "application/pgp-encrypted", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "application/pgp-encrypted" + } + ], + "body": { + "attachmentId": "ANGjdJ_GdXJpH7b_3NKyEcUFEgGYxm0cwHupRPMyQQn0dDpjU8kmCGVBVoMRwRkt4EUvyNuCBjB7hRz3i-41LCg8mYB3X1cMcrD2FTnXp0g0NNimL2DFOxtbV6b6QxCfV_JkUjrBaHKPMSI7EjK9_goCoOIxO2wVAHW3hPP_vXCerlRVoyXY7WqHMAxUTqMivhiZR-7cOhqtDH3E9z0jnhY8ydx1zBv0lhRfPE89g4dNnvBZxEvJa8QazNOCmxNdCWA_QfrF5YWxb-qK9cIQOWkHZ0bJpddqF6HcGcYPe0NNSrwlhIb9Yh3jWTqf7pwDvoE_0FBnDImzIsBK0p-oStPV9sLv-89cjgBW4f_oPa1Fa8hcQRWCocY5Tp1H8ZM", + "size": 12 + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream" + } + ], + "body": { + "attachmentId": "ANGjdJ8vunEUe0k10JJkf5HxHDeVHInEKQK46jXFdoeea-Xh_Bung2AB9D8mpws24YdrULk_1tLWOURBX0nDwS-YYmIKU_3K2u8prrrH6PSiQ1AuUSGj5U1wFvsENbMNsVp7n9Ljupz4zL74uE3ycGDME2RZDTIOIARSSD-IZeyk2yM9n2ZtI_ZNGTEWNoDS8bfllpakH3bbBdkodXTBY5Z1bAMD4yprhXDSN1-HDfR4WMyoE1rHLU-UzJIbssGmlg46ZL5P4Y6UwexbZxwayHyVAn3Yi1UGcfXImwtswIYj113ScKZrSf19HGocU3DAMUNfdP4A1IfH45oLivQdIDEBZwmdsyhh7DI7dVecu4HA_LndGPL8PlqyEgmbcv0", + "size": 2565 + } + } + ] + }, + "sizeEstimate": 10353, + "historyId": "1405857", + "internalDate": "1512083885000" + }, + "attachments": { + "ANGjdJ_GdXJpH7b_3NKyEcUFEgGYxm0cwHupRPMyQQn0dDpjU8kmCGVBVoMRwRkt4EUvyNuCBjB7hRz3i-41LCg8mYB3X1cMcrD2FTnXp0g0NNimL2DFOxtbV6b6QxCfV_JkUjrBaHKPMSI7EjK9_goCoOIxO2wVAHW3hPP_vXCerlRVoyXY7WqHMAxUTqMivhiZR-7cOhqtDH3E9z0jnhY8ydx1zBv0lhRfPE89g4dNnvBZxEvJa8QazNOCmxNdCWA_QfrF5YWxb-qK9cIQOWkHZ0bJpddqF6HcGcYPe0NNSrwlhIb9Yh3jWTqf7pwDvoE_0FBnDImzIsBK0p-oStPV9sLv-89cjgBW4f_oPa1Fa8hcQRWCocY5Tp1H8ZM": { + "data": "VmVyc2lvbjogMQ0K", + "size": 12 + }, + "ANGjdJ8vunEUe0k10JJkf5HxHDeVHInEKQK46jXFdoeea-Xh_Bung2AB9D8mpws24YdrULk_1tLWOURBX0nDwS-YYmIKU_3K2u8prrrH6PSiQ1AuUSGj5U1wFvsENbMNsVp7n9Ljupz4zL74uE3ycGDME2RZDTIOIARSSD-IZeyk2yM9n2ZtI_ZNGTEWNoDS8bfllpakH3bbBdkodXTBY5Z1bAMD4yprhXDSN1-HDfR4WMyoE1rHLU-UzJIbssGmlg46ZL5P4Y6UwexbZxwayHyVAn3Yi1UGcfXImwtswIYj113ScKZrSf19HGocU3DAMUNfdP4A1IfH45oLivQdIDEBZwmdsyhh7DI7dVecu4HA_LndGPL8PlqyEgmbcv0": { + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCmhRRU1BK2E1ekpsdWNST25BUWYrSmMza2tRUElrbzVnbnEwYk41MTBlMTZway9CTnEzdzAwQldaWm1xZThRWjMNCjJDRGkxaThtSkNUZjBheDl6Q2pKbU5Fb0s0c29uWDg4WnRRM25EWDgxOUFUZXU4Z2k2Y1dUYWFUcmR0Zkk1d0YNCkdvRDNJZ1Jpd09HSmYzTkFVU2E4WUI3Ny9weDZBTDM1amU0NHVYSHZzdG1tV3J0NExNUUJRYVJVR0hHNTF2eGYNClFLTng5aEJITE92ODN3R2pqS29ET0J5YjBMZjJzR0lsRUNnZU9IR2Zvd0tHM2ZINE5OTzBrV2JhTGNWdk05RGgNCmdXalFRV1dBV2haQ3VGbXBZZElrdFl6QzRDTjdKYVRSZEdieXVLMnN5cnNpV3ljMXR0eS9sVjFYTTA2ZHdZTzgNCjd4Z2RYVERibVZ3dWpFdFFKVzFiSnVPb0k4RGl1UmJZZkVnR1NHQURtSVVDREFOTFdpLzg1aTJWQVFFUC8xcVINCmlZTEc1SU1TNjBLSmY4OUdLMTNQTmVvMVF6Yk5OWXJOanhXeWlFWk95N24wcVoxWDdKV2ZHclJTeDJXcXRlc2gNCnZ6WTVEdC9XUVdWRVMvNHNsNTRHTzhQamxoaTZZakluM3dGeVpyeWZ0T0Y0ZVhqb1E3ZGJicG9Pc0hoT2l6Y0QNCnAzbDR6WFBSbmc4aEM0Z0YvWjZYeENzRlJITFhnRFJzSkt1NWJaOFZFSnZLMm0xc29HK0NEbDlzL0RpZmpmL1UNCkpWYzNEV2g3bFFQR3krOFR4a3ZIdHZhRDFaYk5Tak9JZmRtc3liQlMzSGsrU29hTGIzTUkrdjJjbEhNWW5TS3MNCjFaMnpFbjIxU0J4ckxkK1lLV0Q1bUJFOVVaR3lhckFOdnZiTWtpUEdWa0h6elVyZnU2TmpGOXNWS29OTERKbXUNCmVnanI2UldOdjJDckhyK1JFUVdSYVE0MDA0WGZ1MldSWmtjWkg3RExhT3ZJTWx2aThtSE5XMUVwbEwyU3J2RjkNCm9IN1lNZXYwajJ4MEJMRWtyT1d0RmZSRzdOcGdNVS9PMWJEejNERDd1REhJZ2kzMktKK1VoU1lYcWlNT2xJUEsNCjh3QjM5bUNxZ1kxdkQ1Ymt3N2wvVkhYK2Z3VTdRVEFLMkxnNytVR0QyOVZtSmhzbzQ2TXB6MXBiTDBIWml1Q1kNCjlKUnIxQ3hpL1h3S1dYZ25nOGlqSVVoUTgvc0RkVXh1Ukl4L3hnTENuK055NjlNcmpablhFMlQwVzUrZ0JwdVgNCmM3S1VkSndDVUVrZGlCL1dsejRpemRQVUNCVW5jMFFBcUN0N0l4eDRTNEhuK1UxbE5mckVDcUpJMTRrYmYyN3INCkxtTGlacUVCNVdKSExCdFVrZWd5RldyNld3SG1xUUZ4dHV1MlRnL3owdWtCa1pEek9ETnowZVZRQU5FYi9rV24NCnhhYUgvRGh2a3grRHhLZXloaTZMRGZBdFU3b09PbzhDMytpVEZ6aytTc3IyVGw2TWI2ZnVTU3h4VmMvaTFZWmINCkVPV0V1dytUTEdoSDNueldHMXJlTTdOMHE3bE5WeTVtejNWOWNYUmN2UlVqN3dZQmh4ZjRMeUJSdENxM2xPVWwNCmhmSGY3VTN6azZacElVQ3ExNDZDYldWQXk4M2puS2JKd3ptbE9DV295MXJWZmJSZzYrZW1TaG1sM3VnT0NqZnANCkpWVml1VzMzWlVFR1lJZURIYThDaWhHbjNhaTBhTjRDSFFpdURlL0E5dGxqRnNlWWkrSWRmVmhJejEwVlJQQk8NCmJSVFcvbkZEa1ZqSTlFM0JkK0g1K3lqNExFYkdGWWZjU0hNamdvTWpTNTc4cDVkbWJsL1ZlTnQvd1M5ZHhQRjgNCjhpUlYydGNTdTVIYkxoV0daSjFsK2NuNk4xUHdXNlJzOU5yZGZzTUQ3UU5zeURVNzFoT3oxMGFzT2dlYnhZTk0NCmdGaGh3L2x4SGlnOWl1TndPOEdFMEhCRG1SditIS3hMWHVlMHBIUFd0OVV0L21ZNHIvK3J1WGxveFJzVThnakcNCmh6U2FtVjVJZHZmUXkweENvZzJiV0RDTDRyQ25naDFJa3JGaTBDdE5ObDFtUHNraG9acU1aanNvMjkweU5hVWMNCkhlRklkeVB5dmpqeHlvSGQ5SzNCdVh4NmZQdlliWnpGUno5WWlrTXFIeHo2QXlIQWlNSm5sOE9QRkg2WE9Ua2kNCk8xbGlVOUxJK01zTENtZURxR2xpTmFwOVZNdnBCa0pLNmxXb0MwUkR0cUhNNDhzSTRCcUhCZ1c2blV3bkd2NUgNCnRLYkRUZ0ZmTVp3NWMra2xPV0lVSE1FNGVGTnlSZWo2OXVvb2ZGeWIyck5qWEJxdktsTDJnMGRVWGJtMm5tWUcNClVXNEpQSFdyaWE2ZGp2NnpnMGgwMzdjL1A2K0RoVmRtMk84aW44YitCZ3FzZHI3Q2hZUHAyalVYOHJvdUZOd2QNClU0eEFYWW83aUxvRE43QVhIVWIrRzE5cXJ4M2MvWEJyYjVtc1ZsbGZqRGZLc3BYOWZ0VEJ1a2wxL0p2MlFkRTANCkcwa0VWekFWQjNhbXQ5S0hOWCtmTUMyOHJCbGE2MGdmeG1wRUo5UTdmWkNBT3FUSlBQY1MxRDlBS1ZtM3dwb2gNCk5XTkpYWXN0YmxWR05CR3VZZUp1dkh5amNHZnMyM1JQZ3kxUEkvQXFKSmN1bVVDY0diOEFhNEJ1ZnN5Wkx3NEwNCkNrTjZ5YUN1dzVEZG1lTmtsa20vTlZESkpKcHZrTFlyVFJyNlY1VkllTzF1c3ZtVFl3QWc1MzAxRGpHL0k2cVANClZSSlE3R2VVWEI5RzZyNmcxNUtiTmZJQUx6MFNVdDZ3S3JGbjZIMzlhVmxCWHpGTzVZNkVtbUQrWWFwZkpIMG8NCmhPSGlJYldIWHFVOXJQVG9MQzJQbjlXRHE5RklVTXgrMHdMMEVuMTcyZTIrVU9mRW9QcmNveWtWRlhlbUdDVnANCkliQjlIc0lVVnJzWXlxdnM3SExRZk1kUi9Tancrc0ZpbEt6SUlCRmpnTldIaXlPd3NoVk1rSENVSG9oY3c2bUoNCjNjeDAxeFdnSmFHNDJnZ0dTWXZrYjRCdlpFZmdLbXNsd0lWNzlwYndReHVheUtOTnFDcFB3SHVxQTFmZGxaMkUNCmhSOERuK1NocTJlUDVsU3RsSzBWK0dZVDlmQmNmdXFBcGRVS05tSkExUGtzK2o5aDBDenNlV1lBDQo9SFJ1aQ0KLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQ0K", + "size": 2565 + } + }, + "raw": { + "id": "1600f39127880eed", + "threadId": "1600f39127880eed", + "labelIds": [ + "IMPORTANT", + "STARRED", + "Label_25", + "Label_3", + "CATEGORY_PERSONAL", + "INBOX" + ], + "snippet": "", + "sizeEstimate": 10353, + "raw": "RGVsaXZlcmVkLVRvOiBmbG93Y3J5cHQuY29tcGF0aWJpbGl0eUBnbWFpbC5jb20NClJlY2VpdmVkOiBieSAxMC4xNzYuMjUuOTcgd2l0aCBTTVRQIGlkIHUzM2NzcDU2NTQ2NHVhZzsNCiAgICAgICAgVGh1LCAzMCBOb3YgMjAxNyAxNToxODowNiAtMDgwMCAoUFNUKQ0KWC1Hb29nbGUtU210cC1Tb3VyY2U6IEFHczR6TVpqdXpvVWdzU0k5R3JmYmhNdG9iMUwxc0VzOXhoamVURFdNeGRpc1U0bDlMSjQyV2xwMnM3QmtrbzR0YmxaTlBpaXZMd2cNClgtUmVjZWl2ZWQ6IGJ5IDEwLjU1LjEwNC4xMzUgd2l0aCBTTVRQIGlkIGQxMjltcjUxMjc5NDZxa2MuMzQ5LjE1MTIwODM4ODY4MTc7DQogICAgICAgIFRodSwgMzAgTm92IDIwMTcgMTU6MTg6MDYgLTA4MDAgKFBTVCkNCkFSQy1TZWFsOiBpPTE7IGE9cnNhLXNoYTI1NjsgdD0xNTEyMDgzODg2OyBjdj1ub25lOw0KICAgICAgICBkPWdvb2dsZS5jb207IHM9YXJjLTIwMTYwODE2Ow0KICAgICAgICBiPWNDdm1Pek4zd2M3NzRXRzhrMG9OVzVhM2NGL210MXI0NkdTUk5OZlFpRVBFNGl0UGNDR1ZsbUMwVUFoUUl2amVhOQ0KICAgICAgICAgZklLdVN1M1FPQkRyQ1B2U3pwN3BJOXdpcjFxbisrdnpDQ2VEc3BhendmbHFGWWtOUmpCY2hFT09nQnJrTWM5elRxejMNCiAgICAgICAgIDUvWU44NnJuQWJPVU5rR3FHUzRXWVpKY1JvZE5ycnlPbmNLbTFHakdPcnVmOGhTWmFrcklsY1k3dW1uTWRNRXNVbFVRDQogICAgICAgICBiaGhnZlpqQUd3NDYrVVVYZmI2VW80M3A4YkFFV1psSE1NQTJpeGhrUDQzVmdJNjJHUFNWbTArL2Exdi9tZVA2T0JOUQ0KICAgICAgICAga1MxWVYwcEEzWWRFcmY1Mld6bUhkODBvbjF0VnAvR2ZNRE9aOHNrMDlvM0xXdUVldzRYU1hqYVNRR3JWbElxUFFVV1YNCiAgICAgICAgIDB4alE9PQ0KQVJDLU1lc3NhZ2UtU2lnbmF0dXJlOiBpPTE7IGE9cnNhLXNoYTI1NjsgYz1yZWxheGVkL3JlbGF4ZWQ7IGQ9Z29vZ2xlLmNvbTsgcz1hcmMtMjAxNjA4MTY7DQogICAgICAgIGg9bWltZS12ZXJzaW9uOnNwYW1kaWFnbm9zdGljbWV0YWRhdGE6c3BhbWRpYWdub3N0aWNvdXRwdXQNCiAgICAgICAgIDpjb250ZW50LWxhbmd1YWdlOmFjY2VwdC1sYW5ndWFnZTptZXNzYWdlLWlkOmRhdGU6dGhyZWFkLWluZGV4DQogICAgICAgICA6dGhyZWFkLXRvcGljOnN1YmplY3Q6dG86ZnJvbTpka2ltLXNpZ25hdHVyZQ0KICAgICAgICAgOmFyYy1hdXRoZW50aWNhdGlvbi1yZXN1bHRzOw0KICAgICAgICBiaD14VkZtanpqRUxXLzArR1lBWmxMWjY1dVVCdVFVa0RKTHJVOHNzYlVTdERFPTsNCiAgICAgICAgYj1GSHgwbW1iMW1GbFVmeFZobkZoRk5Bb0h4dXVqbFdKS1BXYlA4clJpaXJ2ZDU2ZzgrQmp1VEVmSEJ1V05yQnpMY0gNCiAgICAgICAgIHpKTHVnUHZRbmliTXI4Tm5RWS8xRXdidXg3Rk9sc0Q3RzkyK3pYQm9jZGpmWjRvb1JVMXVvRmRucTI2TlFDOXA5QjhmDQogICAgICAgICBYWlgxd201NUlxalY3eEcxUXVRTnlJYzI4R1ZoeWxEYUx2WEs5NXBzSi9CamMxQjZOV2x3ajFkcWVBN1FVWHppcDREWA0KICAgICAgICAgREVia3B4bWN0djhkK0dOSjhyUWpXOE1iWFBaWWNLZzFhcWszcllNQVQvelJaYTBrd0x2Skd0aUZXSnpVdllzMVJxekENCiAgICAgICAgIFBtNU1XTnZQSXhjUHhnajhQeWE5OWJhYnJBaWFYbzRNbVk3WUpybHk3ekoxdXNGUXJKNE5VTnk0alhFTjRQUjdueHRPDQogICAgICAgICA2SmRRPT0NCkFSQy1BdXRoZW50aWNhdGlvbi1SZXN1bHRzOiBpPTE7IG14Lmdvb2dsZS5jb207DQogICAgICAgZGtpbT1wYXNzIGhlYWRlci5pPUBzeXN0ZWNocmVzZWFyY2gub25taWNyb3NvZnQuY29tIGhlYWRlci5zPXNlbGVjdG9yMS1zdHJlc2VhcmNoLWNvbSBoZWFkZXIuYj1UYXc2NC9hbTsNCiAgICAgICBzcGY9cGFzcyAoZ29vZ2xlLmNvbTogZG9tYWluIG9mIHBhdWwuaWxhcmRpQHN0cmVzZWFyY2guY29tIGRlc2lnbmF0ZXMgMTA0LjQ3LjMzLjcxIGFzIHBlcm1pdHRlZCBzZW5kZXIpIHNtdHAubWFpbGZyb209cGF1bC5pbGFyZGlAc3RyZXNlYXJjaC5jb20NClJldHVybi1QYXRoOiA8cGF1bC5pbGFyZGlAc3RyZXNlYXJjaC5jb20-DQpSZWNlaXZlZDogZnJvbSBOQU0wMS1CTjMtb2JlLm91dGJvdW5kLnByb3RlY3Rpb24ub3V0bG9vay5jb20gKG1haWwtYm4zbmFtMDFvbjAwNzEub3V0Ym91bmQucHJvdGVjdGlvbi5vdXRsb29rLmNvbS4gWzEwNC40Ny4zMy43MV0pDQogICAgICAgIGJ5IG14Lmdvb2dsZS5jb20gd2l0aCBFU01UUFMgaWQgbTEzc2k0MDU5MTcxcXRmLjc1LjIwMTcuMTEuMzAuMTUuMTguMDYNCiAgICAgICAgZm9yIDxmbG93Y3J5cHQuY29tcGF0aWJpbGl0eUBnbWFpbC5jb20-DQogICAgICAgICh2ZXJzaW9uPVRMUzFfMiBjaXBoZXI9RUNESEUtUlNBLUFFUzEyOC1TSEEgYml0cz0xMjgvMTI4KTsNCiAgICAgICAgVGh1LCAzMCBOb3YgMjAxNyAxNToxODowNiAtMDgwMCAoUFNUKQ0KUmVjZWl2ZWQtU1BGOiBwYXNzIChnb29nbGUuY29tOiBkb21haW4gb2YgcGF1bC5pbGFyZGlAc3RyZXNlYXJjaC5jb20gZGVzaWduYXRlcyAxMDQuNDcuMzMuNzEgYXMgcGVybWl0dGVkIHNlbmRlcikgY2xpZW50LWlwPTEwNC40Ny4zMy43MTsNCkF1dGhlbnRpY2F0aW9uLVJlc3VsdHM6IG14Lmdvb2dsZS5jb207DQogICAgICAgZGtpbT1wYXNzIGhlYWRlci5pPUBzeXN0ZWNocmVzZWFyY2gub25taWNyb3NvZnQuY29tIGhlYWRlci5zPXNlbGVjdG9yMS1zdHJlc2VhcmNoLWNvbSBoZWFkZXIuYj1UYXc2NC9hbTsNCiAgICAgICBzcGY9cGFzcyAoZ29vZ2xlLmNvbTogZG9tYWluIG9mIHBhdWwuaWxhcmRpQHN0cmVzZWFyY2guY29tIGRlc2lnbmF0ZXMgMTA0LjQ3LjMzLjcxIGFzIHBlcm1pdHRlZCBzZW5kZXIpIHNtdHAubWFpbGZyb209cGF1bC5pbGFyZGlAc3RyZXNlYXJjaC5jb20NCkRLSU0tU2lnbmF0dXJlOiB2PTE7IGE9cnNhLXNoYTI1NjsgYz1yZWxheGVkL3JlbGF4ZWQ7DQogZD1zeXN0ZWNocmVzZWFyY2gub25taWNyb3NvZnQuY29tOyBzPXNlbGVjdG9yMS1zdHJlc2VhcmNoLWNvbTsNCiBoPUZyb206RGF0ZTpTdWJqZWN0Ok1lc3NhZ2UtSUQ6Q29udGVudC1UeXBlOk1JTUUtVmVyc2lvbjsNCiBiaD14VkZtanpqRUxXLzArR1lBWmxMWjY1dVVCdVFVa0RKTHJVOHNzYlVTdERFPTsNCiBiPVRhdzY0L2FtcWplUUp5UERleGlmaGU5Q3FPRUQ5dURoRlJIZHVibUhoR1JqbS9BTlY5N0NST1VMVk9CcUF0ZG1keVRHcG00TmxTMkprcUlWemNFczczTG1WZWtYcXlzMTlmOGVEMStNSkt6SUtEWDRaOGplekpIeldqZjJEbDlEaDNyOHlXa2JuOE54SHFZeEJsVzVjRkxYeHcxZnFKNytIK3lVaE8vdUg4UT0NClJlY2VpdmVkOiBmcm9tIERNNVBSMDVNQjMzMjQubmFtcHJkMDUucHJvZC5vdXRsb29rLmNvbSAoMTAuMTc0LjE5MS4zOSkgYnkNCiBETTVQUjA1TUIzMzIxLm5hbXByZDA1LnByb2Qub3V0bG9vay5jb20gKDEwLjE3NC4xOTEuMzYpIHdpdGggTWljcm9zb2Z0IFNNVFANCiBTZXJ2ZXIgKHZlcnNpb249VExTMV8yLCBjaXBoZXI9VExTX0VDREhFX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQTM4NF9QMjU2KSBpZA0KIDE1LjIwLjI4Mi4zOyBUaHUsIDMwIE5vdiAyMDE3IDIzOjE4OjA1ICswMDAwDQpSZWNlaXZlZDogZnJvbSBETTVQUjA1TUIzMzI0Lm5hbXByZDA1LnByb2Qub3V0bG9vay5jb20gKFsxMC4xNzQuMTkxLjM5XSkgYnkNCiBETTVQUjA1TUIzMzI0Lm5hbXByZDA1LnByb2Qub3V0bG9vay5jb20gKFsxMC4xNzQuMTkxLjM5XSkgd2l0aCBtYXBpIGlkDQogMTUuMjAuMDI4Mi4wMDY7IFRodSwgMzAgTm92IDIwMTcgMjM6MTg6MDUgKzAwMDANCkZyb206IFBhdWwgSWxhcmRpIDxwYXVsLmlsYXJkaUBzdHJlc2VhcmNoLmNvbT4NClRvOiAiZmxvd2NyeXB0LmNvbXBhdGliaWxpdHlAZ21haWwuY29tIiA8Zmxvd2NyeXB0LmNvbXBhdGliaWxpdHlAZ21haWwuY29tPg0KU3ViamVjdDogQ29tcGF0aWJpbGl0eSB0ZXN0IGVtYWlsDQpUaHJlYWQtVG9waWM6IENvbXBhdGliaWxpdHkgdGVzdCBlbWFpbA0KVGhyZWFkLUluZGV4OiBBZE5xTDJkRWpPV3BZbGZMUkp5ME1KcWdTL3J6L3c9PQ0KRGF0ZTogVGh1LCAzMCBOb3YgMjAxNyAyMzoxODowNSArMDAwMA0KTWVzc2FnZS1JRDogPERNNVBSMDVNQjMzMjQ5MUM0MzM0MjE2NUZFMDQyMTVDNDk2MzgwQERNNVBSMDVNQjMzMjQubmFtcHJkMDUucHJvZC5vdXRsb29rLmNvbT4NCkFjY2VwdC1MYW5ndWFnZTogZW4tVVMNCkNvbnRlbnQtTGFuZ3VhZ2U6IGVuLVVTDQpYLU1TLUhhcy1BdHRhY2g6IHllcw0KWC1NUy1UTkVGLUNvcnJlbGF0b3I6DQphdXRoZW50aWNhdGlvbi1yZXN1bHRzOiBzcGY9bm9uZSAoc2VuZGVyIElQIGlzICkNCiBzbXRwLm1haWxmcm9tPXBhdWwuaWxhcmRpQHN0cmVzZWFyY2guY29tOyANCngtb3JpZ2luYXRpbmctaXA6IFs0MC4xMzkuNTUuOTldDQp4LW1zLXB1YmxpY3RyYWZmaWN0eXBlOiBFbWFpbA0KeC1taWNyb3NvZnQtZXhjaGFuZ2UtZGlhZ25vc3RpY3M6IDE7RE01UFIwNU1CMzMyMTs2Om0ybnZGRWNwbkFMVGo2S1lrOEEzWjgvd1NleDVwT1NUOTZ6UXYrUGd6SlBQMGVjWDFSR1M2K3F6Zm1RN1VmRmtCSE43ZVMySGdHdGcxL0JjdTc4SEFTb283eWV3dFJwNStPclVIdmNRMFFpNERiU096L0pvbXF5SU5MelJ2V0ZoMENJRldwRi9FTkF3SVJqVWNrM0JzVkM3bDJuaTRGc0pvbWZRWW1SaWJBT20rWFkxWGg4T0NhK3RoRWVMbmsyMWwzZkVCZXo5Q3RLNnV3Q2svNGJoK1RxVzBEUGpaMkNVMzZ3OVZKalRENElCb3FuVmxXQ0FvVjcyOE9JeEZ0Sjc7NTpnVjNEZ1FFL0hNQkJERTA4cVZNYW5CdncvcDVIVmNzNkQ2MEl4UGhWU3MrNG5WdnJLMUV5cUlhNmhNbWFDS1gydVBxRWpVdm5CWGJmc0ZZK280RC8zaG9RVkFXSHp4L2I4MWxDNjM4czRvK2UzNjJ1OWp2R2UvRHFNTGF6bisxSVQ2R2dFQ3hqRUtNWTBzYjc5eHpMWHZiblZ3Uy80Ry85dktURThkaFBpK1k9OzI0OnR4MitZSDNDVlpkeUdBUmY5aGRtQmU1eTQvVlRjUTJhMFJYbWtHVUVwKzdIdDJqRDFIemdQSk1mbUJ2cVQyUlEycyttc3E5eDVNOXBxeGVnbHJ3ZU45MzRaWWE1YW9kMndieERvM0VrUkZvPTs3OmgyZVFzbGV1V2YxeFc3Y3ZyNkh4MTk4VzlpdXoycExSTkZaTkw5Z2RRa3dHbXY4QThGWTNoSzFiR0JpeFRMVWtkak15ZHYzemZEVHVUeWNZRkVXVzhQWDNHeHZpcS9lTC8xcjNGcHNCSjNFZmx6b0o4bFVlTE1rc2htSmYrWHNNd1djaFVxQjc3TzNSME5EZGJoU1NncFlJeFM4Rzd4YzdJWWhzd3Azb1ltcktVSHNtc3Jua1l3WDNveTNHN2RIalpvd1hkZkY1akVjTUg5cFZvR1BLS1pZaTBJRGQ5NlZ4VXM3ZHYzNEVlSXVxMUxzRTBSOWIzc1pXb2ZWUlFkaTUNCngtbXMtZXhjaGFuZ2UtYW50aXNwYW0tc3JmYS1kaWFnbm9zdGljczogU1NPUzsNCngtbXMtb2ZmaWNlMzY1LWZpbHRlcmluZy1jb3JyZWxhdGlvbi1pZDogOTE5ZWU3YzYtZTAyNi00MGZlLWIyOWMtMDhkNTM4NDg5YzUzDQp4LW1pY3Jvc29mdC1hbnRpc3BhbTogVXJpU2Nhbjo7QkNMOjA7UENMOjA7UlVMRUlEOig1NjAwMDI2KSg0NjA0MDc1KSg0NTM0MDIwKSg0NjAyMDc1KSg0NjAzMDc1KSg0NjI3MTE1KSgyMDE3MDIyODE1NDkwNzUpKDIwMTcwNTI2MDMyODYpKDQ5NTYzMDc0KTtTUlZSOkRNNVBSMDVNQjMzMjE7DQp4LW1zLXRyYWZmaWN0eXBlZGlhZ25vc3RpYzogRE01UFIwNU1CMzMyMToNCngtbWljcm9zb2Z0LWFudGlzcGFtLXBydnM6IDxETTVQUjA1TUIzMzIxRjdFRjhGNjdGMEFFOUI4MDYzQjA5NjM4MEBETTVQUjA1TUIzMzIxLm5hbXByZDA1LnByb2Qub3V0bG9vay5jb20-DQp4LWV4Y2hhbmdlLWFudGlzcGFtLXJlcG9ydC10ZXN0OiBVcmlTY2FuOjsNCngtZXhjaGFuZ2UtYW50aXNwYW0tcmVwb3J0LWNmYS10ZXN0OiBCQ0w6MDtQQ0w6MDtSVUxFSUQ6KDEwMjQxNTM5NSkoNjA0MDQ1MCkoMjQwMTA0NykoODEyMTUwMTA0NikoNTAwNTAwNikoOTMwMDYwOTUpKDkzMDAxMDk1KSgzMjMxMDIyKSgzMDAyMDAxKSgxMDIwMTUwMTA0NikoNjA0MTI0OCkoMjAxNjExMjM1NTgxMDApKDIwMTYxMTIzNTU1MDI1KSgyMDE2MTEyMzU2NDAyNSkoMjAxNjExMjM1NjIwMjUpKDIwMTYxMTIzNTYwMDI1KSgyMDE3MDMxMzE0MjMwNzUpKDIwMTcwMjI4MTUyODA3NSkoMjAxNzAzMDYxNDIxMDc1KSgyMDE3MDMwNjE0MDYxNTMpKDIwMTYxMTE4MDIwMjUpKDYwNzIxNDgpKDYwNDMwNDYpKDIwMTcwODA3MTc0MjAxMSk7U1JWUjpETTVQUjA1TUIzMzIxO0JDTDowO1BDTDowO1JVTEVJRDooMTAwMDAwODAzMTAxKSgxMDAxMTA0MDAwOTUpO1NSVlI6RE01UFIwNU1CMzMyMTsNCngtZm9yZWZyb250LXBydnM6IDA1MDc5RDg0NzANCngtZm9yZWZyb250LWFudGlzcGFtLXJlcG9ydDogU0ZWOk5TUE07U0ZTOigxMDAwOTAyMCkoNjAwOTAwMSkoMzk4MzA0MDAwMDIpKDM3NjAwMikoMzY2MDA0KSgzNDYwMDIpKDE5OTAwMykoMTg5MDAyKSgxMzYxMDAzKSgzMjgwNzAwMDAyKSg5OTkzNjAwMSkoMzY2MDcwMDAwMSkoNDc4NjAwMDAxKSg1MzkzNjAwMikoNjUwNjAwNikoNjQzNjAwMikoMjM1MTAwMSkoMTA1NTg2MDAyKSgxMDYzNTYwMDEpKDg2NzYwMDIpKDcxMTYwMDMpKDMxNjAwMikoODExNTYwMTQpKDgxMTY2MDA2KSgyNTAxMDAzKSg2MjEwNjUwMDIpKDI5MDYwMDIpKDE0NDU0MDA0KSgxMDE0MTYwMDEpKDY5MTYwMDkpKDU0MzU2MDExKSg5NzczNjAwNCkoNzQzMTYwMDIpKDMwNTk0NTAwNSkoNzczNjAwMikoOTY4NjAwMykoMzkwNjA0MDAwMDIpKDM4NDYwMDIpKDEwMjgzNjAwMykoNzY5NjAwNSkoNjExNjAwMikoODYzNjIwMDEpKDQyNzA2MDAwMDYpKDk5Mjg2MDA0KSg3Mzg5NDAwMykoMjU3ODYwMDkpKDU1MDE2MDAyKSgzMzY1NjAwMikoNTY0MDcwMDAwMykoNjYwNjYwMDEpKDM0ODA3MDAwMDQpKDI5MDAxMDAwMDEpKDc3MDk2MDA2KSg4OTM2MDAyKSg2ODczNjAwNyk7RElSOk9VVDtTRlA6MTEwMTtTQ0w6MTtTUlZSOkRNNVBSMDVNQjMzMjE7SDpETTVQUjA1TUIzMzI0Lm5hbXByZDA1LnByb2Qub3V0bG9vay5jb207RlBSOjtTUEY6Tm9uZTtQVFI6SW5mb05vUmVjb3JkcztBOjE7TVg6MTtMQU5HOmVuOw0KcmVjZWl2ZWQtc3BmOiBOb25lIChwcm90ZWN0aW9uLm91dGxvb2suY29tOiBzdHJlc2VhcmNoLmNvbSBkb2VzIG5vdCBkZXNpZ25hdGUNCiBwZXJtaXR0ZWQgc2VuZGVyIGhvc3RzKQ0Kc3BhbWRpYWdub3N0aWNvdXRwdXQ6IDE6OTkNCnNwYW1kaWFnbm9zdGljbWV0YWRhdGE6IE5TUE0NCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L2VuY3J5cHRlZDsgcHJvdG9jb2w9ImFwcGxpY2F0aW9uL3BncC1lbmNyeXB0ZWQiOw0KCWJvdW5kYXJ5PSI9LT1yMHFMUTJTRy9HSXVwaz0tPSINCk1JTUUtVmVyc2lvbjogMS4wDQpYLU9yaWdpbmF0b3JPcmc6IHN0cmVzZWFyY2guY29tDQpYLU1TLUV4Y2hhbmdlLUNyb3NzVGVuYW50LU5ldHdvcmstTWVzc2FnZS1JZDogOTE5ZWU3YzYtZTAyNi00MGZlLWIyOWMtMDhkNTM4NDg5YzUzDQpYLU1TLUV4Y2hhbmdlLUNyb3NzVGVuYW50LW9yaWdpbmFsYXJyaXZhbHRpbWU6IDMwIE5vdiAyMDE3IDIzOjE4OjA1LjI5MTgNCiAoVVRDKQ0KWC1NUy1FeGNoYW5nZS1Dcm9zc1RlbmFudC1mcm9tZW50aXR5aGVhZGVyOiBIb3N0ZWQNClgtTVMtRXhjaGFuZ2UtQ3Jvc3NUZW5hbnQtaWQ6IGVmNWI2MjUyLWI5YTgtNDY3Yi1hNTU3LTJkNzk4ZjQzOWFmZA0KWC1NUy1FeGNoYW5nZS1UcmFuc3BvcnQtQ3Jvc3NUZW5hbnRIZWFkZXJzU3RhbXBlZDogRE01UFIwNU1CMzMyMQ0KDQotLT0tPXIwcUxRMlNHL0dJdXBrPS09DQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3BncC1lbmNyeXB0ZWQNCg0KVmVyc2lvbjogMQ0KDQotLT0tPXIwcUxRMlNHL0dJdXBrPS09DQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbQ0KDQotLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS0NCg0KaFFFTUErYTV6Smx1Y1JPbkFRZitKYzNra1FQSWtvNWducTBiTjUxMGUxNnBrL0JOcTN3MDBCV1pabXFlOFFaMw0KMkNEaTFpOG1KQ1RmMGF4OXpDakptTkVvSzRzb25YODhadFEzbkRYODE5QVRldThnaTZjV1RhYVRyZHRmSTV3Rg0KR29EM0lnUml3T0dKZjNOQVVTYThZQjc3L3B4NkFMMzVqZTQ0dVhIdnN0bW1XcnQ0TE1RQlFhUlVHSEc1MXZ4Zg0KUUtOeDloQkhMT3Y4M3dHampLb0RPQnliMExmMnNHSWxFQ2dlT0hHZm93S0czZkg0Tk5PMGtXYmFMY1Z2TTlEaA0KZ1dqUVFXV0FXaFpDdUZtcFlkSWt0WXpDNENON0phVFJkR2J5dUsyc3lyc2lXeWMxdHR5L2xWMVhNMDZkd1lPOA0KN3hnZFhURGJtVnd1akV0UUpXMWJKdU9vSThEaXVSYllmRWdHU0dBRG1JVUNEQU5MV2kvODVpMlZBUUVQLzFxUg0KaVlMRzVJTVM2MEtKZjg5R0sxM1BOZW8xUXpiTk5Zck5qeFd5aUVaT3k3bjBxWjFYN0pXZkdyUlN4MldxdGVzaA0KdnpZNUR0L1dRV1ZFUy80c2w1NEdPOFBqbGhpNllqSW4zd0Z5WnJ5ZnRPRjRlWGpvUTdkYmJwb09zSGhPaXpjRA0KcDNsNHpYUFJuZzhoQzRnRi9aNlh4Q3NGUkhMWGdEUnNKS3U1Ylo4VkVKdksybTFzb0crQ0RsOXMvRGlmamYvVQ0KSlZjM0RXaDdsUVBHeSs4VHhrdkh0dmFEMVpiTlNqT0lmZG1zeWJCUzNIaytTb2FMYjNNSSt2MmNsSE1ZblNLcw0KMVoyekVuMjFTQnhyTGQrWUtXRDVtQkU5VVpHeWFyQU52dmJNa2lQR1ZrSHp6VXJmdTZOakY5c1ZLb05MREptdQ0KZWdqcjZSV052MkNySHIrUkVRV1JhUTQwMDRYZnUyV1Jaa2NaSDdETGFPdklNbHZpOG1ITlcxRXBsTDJTcnZGOQ0Kb0g3WU1ldjBqMngwQkxFa3JPV3RGZlJHN05wZ01VL08xYkR6M0REN3VESElnaTMyS0orVWhTWVhxaU1PbElQSw0KOHdCMzltQ3FnWTF2RDVia3c3bC9WSFgrZndVN1FUQUsyTGc3K1VHRDI5Vm1KaHNvNDZNcHoxcGJMMEhaaXVDWQ0KOUpScjFDeGkvWHdLV1hnbmc4aWpJVWhROC9zRGRVeHVSSXgveGdMQ24rTnk2OU1yalpuWEUyVDBXNStnQnB1WA0KYzdLVWRKd0NVRWtkaUIvV2x6NGl6ZFBVQ0JVbmMwUUFxQ3Q3SXh4NFM0SG4rVTFsTmZyRUNxSkkxNGtiZjI3cg0KTG1MaVpxRUI1V0pITEJ0VWtlZ3lGV3I2V3dIbXFRRnh0dXUyVGcvejB1a0JrWkR6T0ROejBlVlFBTkViL2tXbg0KeGFhSC9EaHZreCtEeEtleWhpNkxEZkF0VTdvT09vOEMzK2lURnprK1NzcjJUbDZNYjZmdVNTeHhWYy9pMVlaYg0KRU9XRXV3K1RMR2hIM256V0cxcmVNN04wcTdsTlZ5NW16M1Y5Y1hSY3ZSVWo3d1lCaHhmNEx5QlJ0Q3EzbE9VbA0KaGZIZjdVM3prNlpwSVVDcTE0NkNiV1ZBeTgzam5LYkp3em1sT0NXb3kxclZmYlJnNitlbVNobWwzdWdPQ2pmcA0KSlZWaXVXMzNaVUVHWUllREhhOENpaEduM2FpMGFONENIUWl1RGUvQTl0bGpGc2VZaStJZGZWaEl6MTBWUlBCTw0KYlJUVy9uRkRrVmpJOUUzQmQrSDUreWo0TEViR0ZZZmNTSE1qZ29NalM1NzhwNWRtYmwvVmVOdC93UzlkeFBGOA0KOGlSVjJ0Y1N1NUhiTGhXR1pKMWwrY242TjFQd1c2UnM5TnJkZnNNRDdRTnN5RFU3MWhPejEwYXNPZ2VieFlOTQ0KZ0ZoaHcvbHhIaWc5aXVOd084R0UwSEJEbVJ2K0hLeExYdWUwcEhQV3Q5VXQvbVk0ci8rcnVYbG94UnNVOGdqRw0KaHpTYW1WNUlkdmZReTB4Q29nMmJXRENMNHJDbmdoMUlrckZpMEN0Tk5sMW1Qc2tob1pxTVpqc28yOTB5TmFVYw0KSGVGSWR5UHl2amp4eW9IZDlLM0J1WHg2ZlB2WWJaekZSejlZaWtNcUh4ejZBeUhBaU1Kbmw4T1BGSDZYT1RraQ0KTzFsaVU5TEkrTXNMQ21lRHFHbGlOYXA5Vk12cEJrSks2bFdvQzBSRHRxSE00OHNJNEJxSEJnVzZuVXduR3Y1SA0KdEtiRFRnRmZNWnc1YytrbE9XSVVITUU0ZUZOeVJlajY5dW9vZkZ5YjJyTmpYQnF2S2xMMmcwZFVYYm0ybm1ZRw0KVVc0SlBIV3JpYTZkanY2emcwaDAzN2MvUDYrRGhWZG0yTzhpbjhiK0JncXNkcjdDaFlQcDJqVVg4cm91Rk53ZA0KVTR4QVhZbzdpTG9ETjdBWEhVYitHMTlxcngzYy9YQnJiNW1zVmxsZmpEZktzcFg5ZnRUQnVrbDEvSnYyUWRFMA0KRzBrRVZ6QVZCM2FtdDlLSE5YK2ZNQzI4ckJsYTYwZ2Z4bXBFSjlRN2ZaQ0FPcVRKUFBjUzFEOUFLVm0zd3BvaA0KTldOSlhZc3RibFZHTkJHdVllSnV2SHlqY0dmczIzUlBneTFQSS9BcUpKY3VtVUNjR2I4QWE0QnVmc3laTHc0TA0KQ2tONnlhQ3V3NURkbWVOa2xrbS9OVkRKSkpwdmtMWXJUUnI2VjVWSWVPMXVzdm1UWXdBZzUzMDFEakcvSTZxUA0KVlJKUTdHZVVYQjlHNnI2ZzE1S2JOZklBTHowU1V0NndLckZuNkgzOWFWbEJYekZPNVk2RW1tRCtZYXBmSkgwbw0KaE9IaUliV0hYcVU5clBUb0xDMlBuOVdEcTlGSVVNeCswd0wwRW4xNzJlMitVT2ZFb1ByY295a1ZGWGVtR0NWcA0KSWJCOUhzSVVWcnNZeXF2czdITFFmTWRSL1NqdytzRmlsS3pJSUJGamdOV0hpeU93c2hWTWtIQ1VIb2hjdzZtSg0KM2N4MDF4V2dKYUc0MmdnR1NZdmtiNEJ2WkVmZ0ttc2x3SVY3OXBid1F4dWF5S05OcUNwUHdIdXFBMWZkbFoyRQ0KaFI4RG4rU2hxMmVQNWxTdGxLMFYrR1lUOWZCY2Z1cUFwZFVLTm1KQTFQa3MrajloMEN6c2VXWUENCj1IUnVpDQotLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tDQoNCi0tPS09cjBxTFEyU0cvR0l1cGs9LT0tLQ0K", + "historyId": "1405857", + "internalDate": "1512083885000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-16180866d0ae26c3.json b/test/source/mock/google/exported-messages/message-export-16180866d0ae26c3.json new file mode 100644 index 00000000000..42071721848 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-16180866d0ae26c3.json @@ -0,0 +1,131 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "16180866d0ae26c3", + "threadId": "16180866d0ae26c3", + "labelIds": [ + "STARRED", + "Label_3", + "CATEGORY_PERSONAL", + "Label_12", + "Label_13" + ], + "snippet": "", + "payload": { + "partId": "", + "mimeType": "multipart/encrypted", + "filename": "", + "headers": [ + { + "name": "X-Facebook", + "value": "from 2401:db00:3020:711e:face:0:73:0 ([MTI3LjAuMC4x]) by async.twshared3533.11.lla2.facebook.com with HTTPS (ZuckMail);" + }, + { + "name": "Date", + "value": "Sat, 10 Feb 2018 08:22:25 -0800" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Subject", + "value": "Зашифрованное уведомление от Facebook [AROPDhu-27jIg2Gx]" + }, + { + "name": "X-Priority", + "value": "3" + }, + { + "name": "X-Mailer", + "value": "ZuckMail [version 1.00]" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Content-Type", + "value": "multipart/encrypted; boundary=\"b1_2e2bc7e41369e9360a472f5d8c0b2b4c\"; protocol=\"application/pgp-encrypted\";" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "application/pgp-encrypted", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "application/pgp-encrypted; charset=\"UTF-8\"" + }, + { + "name": "Content-Transfer-Encoding", + "value": "7bit" + } + ], + "body": { + "attachmentId": "ANGjdJ_MjDMtBZhTbeoOQN24sw9IV72HLqeem7NZ2zQsDdF99nYGvDjVrPpoOfUuUYTGQTgOyxYlxtHCflj-twndVugY6sZwunVyNAMpX6KbZD9d34PryucAtqdDiMMiEVOwZumY-VZlz2KM9fFwIgTVAVMbomlo2u4dzkEdzHh667JFpcjan1qk1bfL4PlpfqIyYMNT_gQx4heGZF-yrdIkH5R3yddX4-NiXOilBO1SFCf3BBRJpEDsH3R52rBJHVOF_JidvuwLRWLj2EertiMvv9BGW23j0cMR3eMpUqUprTTKSkbSmhLjEnqurZuG13oy4gyHqIm02kAO7uDyDR1F0dy8uQEzjNfYAkBHgxrIDV_PhDz5qL47KrQjjAI", + "size": 69 + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "encrypted.asc", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream; name=\"encrypted.asc\"" + }, + { + "name": "Content-Transfer-Encoding", + "value": "7bit" + }, + { + "name": "Content-ID", + "value": "<0>" + }, + { + "name": "Content-Disposition", + "value": "inline; filename=\"encrypted.asc\"" + } + ], + "body": { + "attachmentId": "ANGjdJ-PAjID8jtrg440tldl7XeGD8GrVkXIOkoqqh9KNxFA7vny6s1K2EeQauEKGXFoCRlcaGZIv-wDlYQ-JpMpOo-9TGMbHJd_iiU0i0MpsulGgn7RtjEDwI7Z1_e-OVg-bzk8s7kX_9jh1sfYEfPow1O-Af0L5g9jzy2UZJlTnFoqUzKjg7kiZoCJS_UiHv3ZbMO0KMmoS9jHS6v_kdxHeY78XPTTRdjb_oB1HP0HaPJWuT_1waMEMXve6sxofdU2SIT9PVSS8qZwzPMwU_AB4dzMEogmJcDnNCd8u2le37R7TVe7vN2cVfqMud8pV0hUTOa2JbVF7Zy4_y6xMqjyy62WpShe5SpiAFyKzOM7J69-CsRlmbgZzRKj-98", + "size": 9213 + } + } + ] + }, + "sizeEstimate": 13957, + "historyId": "1406156", + "internalDate": "1518279745000" + }, + "attachments": { + "ANGjdJ_MjDMtBZhTbeoOQN24sw9IV72HLqeem7NZ2zQsDdF99nYGvDjVrPpoOfUuUYTGQTgOyxYlxtHCflj-twndVugY6sZwunVyNAMpX6KbZD9d34PryucAtqdDiMMiEVOwZumY-VZlz2KM9fFwIgTVAVMbomlo2u4dzkEdzHh667JFpcjan1qk1bfL4PlpfqIyYMNT_gQx4heGZF-yrdIkH5R3yddX4-NiXOilBO1SFCf3BBRJpEDsH3R52rBJHVOF_JidvuwLRWLj2EertiMvv9BGW23j0cMR3eMpUqUprTTKSkbSmhLjEnqurZuG13oy4gyHqIm02kAO7uDyDR1F0dy8uQEzjNfYAkBHgxrIDV_PhDz5qL47KrQjjAI": { + "data": "Q29udGVudC1EZXNjcmlwdGlvbjogUEdQL01JTUUgVmVyc2lvbnMgSWRlbnRpZmljYXRpb24NCg0KVmVyc2lvbjogMQ0K", + "size": 69 + }, + "ANGjdJ-PAjID8jtrg440tldl7XeGD8GrVkXIOkoqqh9KNxFA7vny6s1K2EeQauEKGXFoCRlcaGZIv-wDlYQ-JpMpOo-9TGMbHJd_iiU0i0MpsulGgn7RtjEDwI7Z1_e-OVg-bzk8s7kX_9jh1sfYEfPow1O-Af0L5g9jzy2UZJlTnFoqUzKjg7kiZoCJS_UiHv3ZbMO0KMmoS9jHS6v_kdxHeY78XPTTRdjb_oB1HP0HaPJWuT_1waMEMXve6sxofdU2SIT9PVSS8qZwzPMwU_AB4dzMEogmJcDnNCd8u2le37R7TVe7vN2cVfqMud8pV0hUTOa2JbVF7Zy4_y6xMqjyy62WpShe5SpiAFyKzOM7J69-CsRlmbgZzRKj-98": { + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCmhRSU1BMHRhTC96bUxaVUJBUS85RkcvRFEwMVl2akU5akl6Q1JTUEozOTJxMjh5ZXhqcTVQSXlGbm1VYi9TT2sNCmJvZWg4WHMxek1tc2djVDJydE1OMkZ3NzlNUWRxaGhzU1M4R1NVNDdNSjdNZE1MYVdCZHJGOG9SMUNocHNDTXANCndNQXFkeTMxYi9SRTk1UHpwNzhWSm5tWnA1cURxcUNOYm5MVkQrWnpldjRFbEdhbjU4WWhwZm5NRnNkejB0aysNCmdUcjZDUVZES09wcnZic2thRmFuRytqcExXby85THpQdTFlV3JYL1E1U3dVVmNhVktTZGJMbTVEVlJTVTFxbnQNCi9JdFRpUnVlTWFPUHdaZ3FYSlMzR2VxVDBDL0NWeENEZDBaS3dmUC9CdWhWVEt2NzdsK3FueHVOajgzSS9hazENCjBDSncxSjVqVGUvTkV3VThaZGNKTzhoRFdvOTAwelU5MG9xVW9ZVXNIMXlmN1NLTDhxU0o4L0dNVzlHU3ozY1gNCkZoc2JFMUZpSlowQ0c2c1VBWXRNRldYMnJoTXd1ejh2UExYbGozcTZpWVE2cy9DeHFKdnVIU2JJSzI2WFlNV1gNCm5zQ2t1SmpLbTNjS2UzS09OZXl4T3lpemxRYUErZVFCMjFVMzNCYXAxRlNGZEowQVBLM0hWSjRCNlpJQ3NMaUYNClZYMGltbDAzZXp2aEM0cVJ2LzBYYjJBZFlabS8xSFNnVlV1Q3ZYNmJub0xEcFJZcSthaXkrSGVPNzkvdTJaMFQNCjlEdjBZVUFvcE81aXQ4Y0VBV0J6MWVRdktta05NUUMxVyszZFowNFo4YlpaOTVVd1FwY1ZaTExsdnhjOHVid0sNCi9oNTVCOGcyRXhsQUZLdGt1RWZUdHNEekFFL1BVa2d6Wi9tY3lUNmNsdlByR0c0TlpHcEh4RXZsL3NoV1JqelMNCjdBSGdFbHJGQmd5QkQvM0VoUUd5M0xiNHBmMGhlbEdIdU1GakVXSGIwTm9jeHlLaExMaTYzckxWWnJEUFNQV2INCk00Z3RFNDRiTXAwSFoxa0YxNTBYOEYvZlhYMjQzTTdFVmY4OHp2N3VGSmFLVGhiSzZ0cWhsK3l1ZWdVRmlEVU8NCkRYT3dEa2ozYVBLTTV0T3Bra1IyRUNPT3NOWmlIUVhrZnZFRDR5Tmh4NHNSR0FFaXc3aVh1SUpwOG1SWVFLeFcNCmZybWJsNHl4VVNnV2lpMHM4VlFPYWd3UmpjWXE5UEwxUW4yZ3VqZmVORGs2U1NmREhoMnZJRXI2YnkvOXk2TUcNCmVJdmJJOVZWa2UvVVd0WkU3NXluNFhsVlJPb3UvVW1mRVJ5UjYrenNRQm9NcCtQeTNiRy9aMXBTNDJqays2WU0NClRWb0d6NVNFcGNoMVJINDFLb2tnbjlnUnZsYlVONjRqd3NBSGJXaTNDREV0aWs4MVRYTmhFOUdiUGlkYkI0OU4NCmloeTE3Mm1QMFUwTW9lQWRGNVQ5WThHRWREdTIrVEJKWXp6cGpoR3N6aTZwSGp5aC9xRkUyc3R1TkNWNDRZRGMNCkpSbldXMzVnekQxUFUrZ1ZPV2N4L1BFQU1MbVkxVk4zUk11dUZXOTUxQmxOdGpnNkIxRTdHQmhNSG0rbjlsOFINCnc0Kyt6am5WOHQ2WnFJbzZPakpnaVFrRWg4NXBPcTR5cStxR3JRQUpZT3dwbko0aFo2NUlCM3JzcVVybENlZWgNClhVOW4rOERDZ3RmbXh1b2RRV3FjUkRqd0FEWGM4YldGWWlmSHZUZWhCbHkxcElyRkx2TnErQmZyRTg1dmJKbXYNCkRuL0dJYStjdTljZWxNOC91dTlwS041VW04c0svL0hSV280dkZ6VFhSa0JVRHVLNXAweFdNTS9ZVnRTVjlQTjQNCmY1MXdCTXlhWTIwWU9YTFlkeUF5MzEvTkdoNjF2U1JkKy96anV6cmVzWjJnaHZsZWNaZFF5OWZuU3FVU3ZiSXQNCkpMWWExdEs3SDdVam16YXVaY2NLY1FxS2dhWFhBUUp0K1hZWllZbHdHY0NCekh6TUNENjVmTXdjSGl0K0g1R3MNCmpNS2pCaC9pdHNRUDNGVjUwek8va0ZxNms0Znk5ajdpYitSRVFxRnllYjBKWnAzdG5xVHhwVVBQVjIxd2Evd3MNClo4N2t4V1BONGNrd1ZDbGNpWk1EWHRFU3hSWG0yeG1sd3ZRWTc2S2p3NXZ2dkdnaXp4RUJ2TWFmRDU5YkIvZE8NCkZ3YTh0bFBxbHdDbkkzU1NCNVdIRWRWMlJmdTVPOVNVMWFvNVgrekZwWkxTZU1NZ255c1k1VkJKekZhNkVkRVANCnB1MTZIbDk0UlgzYU9OT0Q0TXExREdaUWcwWlo1cUZaOVpYQ2dmL0o2bXFGbythSENuVDRFVE5Sb3RONGJJdk8NCmRRUk9GN3lpWnhLbCt1ZTc0cGZBZmdETFB5WUJTbU9CMDBJQTExZFBzbWwvZUkrVlU0TXBEZEtOV0hJNmE0bHcNCnJxb2VveGFLYVNnOGx4NThTZUxXNVZ1UmlFWjJQbE5uZjFhRnpmZXc1bGIvTUJtVHJOUUxpa1RrS2dSTlV6VWUNCnBhb2JGdFNuWERhYlYwWXFnNEEyQVlvQ0tFcmsvMFIwbHlyVWl0YVVnQWw2czNlNzZRUnpmNEFvN3I1SFRYRjMNCnNud0ZBRDRPNmlqdVFRejBGbnN6RjNWakh3TysrZnhaUm9VQVZob3ZQTU44c1V4QVhiUFVxNEx1aTl2SGJHSE8NCnhOMENBWStBajNxZ3RyWkU1blV0OHJUUndpVy9rVkN5RERMWTNrYlBkWndkT3Z5ZVdrU05PaWpSY2R5OTlaWkcNCjNPWG9UOGphNjB5TW10UnZiclN2WFEyS295TTErZUxhRk9xYXA2ZWxHR21rWmJLdnVEUjNiNEtaRWxaQ3ZCNjINCnJ5ZDR2K3RzRWNDTXNUVHBvN2VrWnF0bGNzOThMQStqQ0ZqVlVXR3hCejVTYXZVbWNWV0N5NlF6akcwUmFYTXgNCkltREdRV2lvbS9YRDhoQUNFKzQxSFl3R3JUdktzVzMzeU0vSkVzRGIyZFJOK3JiQ1E2UkdUalg3dGlSVjhCR2sNCjBNSVkzRWVqSWdRa1pNWlJBemg0WmJHYlpoQlVaZ2ZVVXpzVG1OdSsvZnBwWlBRdHdSc1h2dW5GK3FGQ3ZYV1QNCmc1WlZVY1plQnFkNmF3TEplMm5yNGkxc1lLZkhMenRLalNYbnhiTjFHb2Zudmg0TmJQUk4raDNRMXZCL2hDZ2cNCmZqUGpkb2pFaUhrMVFjVUc0VnczTjVJVVNXZGVZbkMrQ0dzTy9SWDlmMHUwMFRuVnBna2tRVGZqMkZQT0UwZnINCllkOTBUWWhlZ1h5a1l0emppZ0FrU01nbmFzZDd6ZzIzTUxIMGtaUXhRQ2RqNytFcTVKRjB6Qi9nYkdiS1BkSWQNCnh4V2hTUG9BVTN5MGkvbHlOMDU0MXVxbEh4WDRpK2NYZGxzVFNyQWcxUUJBcXVDZjN3ZTdiN0lNYWt1NzJhQnANClhJblNMajFiYm5XZVJtZXVLV2gvSURuazB4dlBON2VUSXppKzB3WWtZZnV3S0xkNVFTbjZDR0xnazlWUkh6c0MNClkyUHd3U1g1OFlvMEpLK1lFOURDdk1WTU5VZUpBeHBkSWtxK1YwandqZEVSL3pwdi9MVXk2TUtoNFg2MmRLTWgNCnlVOU1wdnFlTVlrZkZqYlZuRmxWOWJKbld1dFlLYnROcHpSZWdZNXdJR0VPWHRwUnh1RnVoUW9Ha0dINDIzckQNCmNXREV6TnVRM0NZcXhZK3lWQVRwRWxCaUVZYmZ4M0tLWjErRzhhTGFqdjB0STZObk45cWttQ0lianYxZStGbFMNCnVBNVd1dHJDcklnSHJNaFJFQzFSNndvVWgvdGxjd0dwbjlndW1OWnZtdnFVWTFHWTNqUTVVZ1k1VkZnd0J5Y3YNCnZNNGtiRWJrMjQxeHQxLzgvOUZaQnd2amZXOUx5dDBDU3crOWRxWXVSQUViWFNhQXZ2cVBMOG1VVWpHMi9ZdUQNCi9lU3R1Sll3T24xZTlnTllYL2lVWUpEOFNxUHg4OURnR1NPY1NQT2VmY1VSYnFMRjJ5UUdsNXNpMlBvblZOVzANCmpDc0xjNmlSRWZMTy8yOHFuOVdkMU9SQkk2VmRjUktIbUF4UmY1MTdJWkRBek80YWF5NDVUMDRoVTV4RkwyZUENClVaOVRDOGt4NTZyZE5GdnJMNjcwWGZPYTFlcjdNYXByVUJoV2ZkdGdiSVErWVRZanpWVmk1OTU0aXZNRVY3SisNCnlCTGdDS1VVSllJKyt2V0oraTdYMDdLenQwWkhYZWJMUkNDbGppTTEyNGRraG5jR1ZVTTZRWGIxcUs0aFFHNVENCkZoeHJPakdVck5xN3pFeEJQWUVpaG1kNHpmM2Uza1FYUGIxRG1sZFRyd1J6K3VzQlNCNGtTaStLalcvaUtydGUNCjArR1hnRGFKVUlMMjhYTFBUWVpIUHdFM21CN3R3NFlJbVN4ZVNmQzlGblJ3NjZKRisyRW9hZS9PNTJHN0JvRWwNCnFQVlJUdlZ1MkRnWHhiL0Rsam9yU3JXYTAwaUpTWktlYXNYRHJIU0NLY1VleGtaMjFEOEZtcitOaWIzS2hRUlkNCmEvemdOTzlsZytnNEpXdTJLYlZ5akVDY2pUb1Mxc1MxVE9YV0ZwR1VGTUo1V1hNVWdaR0QxS2s3bTA5ZlpGLzINClJiZ202bURXRnpHNGdOYnorcXBSbVpVQ2ZLd3ZFREVXdEN3N2xjMEF0QVppdGpaVzFPZkFUbzdvQ3VxU1lReWINCjRBK1BpYkFtZTdhM2tKM3BuNXB1R1ExMWhZWTMzaVl2MEprNS9NRVdWenR3a3dZYzRyd2VTNzFZeGF0SXJKaVQNCjZTYUQyalN6WndBdnlxZUVXWmJZT0J5SVphUm1tNnJUbUdwRTB5R0IrN3pXSjBacGJDdnFRY3lUckNaQk1scDkNCmtzZWxRZVJheERwa2NtbFA2MEhiMGIzZW1yYkR0UmxpVnJUcHczV0piYWZJNGtNU3Y5a3VvekJxQWF2UGtoam0NCktIL1I2YnZ1dVl6RzBmaHI5TzFDVDd3ZG44NWhJTGVwUW9JQWlMa2tqcHg5dDB4MkdTNGVsczJMUW0zZlJVOWgNCmFYUDRZS3NJb2UvSmpTbWR5dnM1b3JTSGJORUlzUzhNcExCUlRLenBsOXk3U09GYUdwODJWejgvTGg2eXJleTANClhWOE96MXRRWmd1VTIzL05rRWtnU0ZqV2VKd0VCNkxDS3pNbkJPWG1GUGkrRnF4NVM3SnBoaEFKZHU2c0NUWEsNClpqWWtrTlAvVUdzYldJRkNrcXpJZDlDUlB6UjJRNURiMTZia2pKbXhOelNuWVhVUC9SekkvSUxidkZUdEE1dVUNClM5L1lQVGNUWHlWUVd1VTB1UFVsNTA0TTZWejd1TXRqNlhGRmJVOXlBT2xCcmltWnBKUFlIeWdGdmtTN01vTnUNCnVWNXB3QUFEa05GeHpvVzlHeEJlWlc5ZndvdUwzS3JIdzUyTmwxQWtGV21vSXNoZFhxVE9wTmdpN1h4ajhYcUENCk1GNTZCSllNanhSYlF0bkdIWm9qOGpySXdVVERUSVl2bXM3eHhKSG01WU92K3R2QWxjQk1jYVJYL3BLWXRvejgNClFZck9aQVRVUXM2T2pYdVdXenlkbHR4NFozMzRpWnF0SlB3bEo0dHA5QWtMVlBqaEh3QjY0cEFkclZMT3dsRHoNCm9ZWGNjWUpzcVdQWmhwMnlna1EwNklNUFQvU1ZLczBwb0tkY2hhYUhUbzhCUkR2ekMxUG91ZGpvQjRTdXNMNUYNCldHMG1acnYzTjZ5UGs3Vi9DYWpVUndyZjJpMTRTVjU4c3d3aVMwNXhaRGhVWDRJT1ZCRkRRRUY0RUVIYmpXdlINCmJpWXlyNDhOWkNxUUtJVVVYN09sNWFPNG9ndjdaRlcvTHN2aUNoN2lZRU5SSGNGMFJLUlhDTG5wRk5kVUxYRkENCi9BSW0zVE9YMHZwK3RqcE0vMTkrSDd3bXFqMURMVEdXazh4WC9yQnNnVGJ1cWhQYVQ0b3RReGN3a0EvenBwTWgNCko5aVVZT2RXcm5IczRETFg3Y0hvS2p3Y0hrZW1GN0dUNkYwdWZ5UUk0TWltTHA5WUppb3kwVnM3c2VaaUdCbkENCnlCU0ZJRm44Mjd0Z0dOL2JFcU5UNUpBVWNSbjNWQ2xobWdBMjVtUGVIdEowUW0rckYyck9kZGZYSjl5TEdKY2QNCmNMUUs2eVBmM1Qxd3FkMXJXZGdKL0xDaitOcldXZk9ncC9MOXFEcnpkVEpvVE9RWnRTdzVLVm5RNjgzWS9KcjkNCndYM2o1QjJtZ013VDVFZkpiK1F6RGlELzAyUG5pdHpuNDJ2OUZNWmN0OTI2MEhJR1dzbmZWdTJkaFhQd2JFNjkNCmpoOGNjajZFMVB6K2ZSY2hlSkNueU1EN1lETk81cGFsT0dOUWdqdE1hRklvTU9SaVg0VVl5V3NnUVZrQjdnRHcNCi9IOFRkaHNZQ2kwNlo4TENqMVhGNHFraVRWc2Vpa3lpaDNSbzlzeXBVVWVsbjlRaE5yRWdscGoxMnhyVWNOWjMNCnJhcDRDNGluaWUvTXJ4WjNJYUVLUDkzMFFrYUdXbVA4SWRRM2d5a3o4K1dWQlh3dTFPeUpkWkVSamJzb1pWVHkNCmlPMWVFL28yalNwb2w5S2NCRDBzOURvYkhXY0ZsRGh6RXhkaytWYjlwUy82YTM3bHJRdmo1OWJCUTJhVnQ0MWINCmJUbmd3bkNyTWVPV1lDaGVjbnUwNzhZRWV5UlZsT0l0c0IvVGw1cWJxNEh5TFBZZk1qNTNuSnRHaDZJYkROK1QNCkJnYktKYm1yanBiaVhVRVdyeU5KWVZOdS9FMUNTOVgwQVhiM29yK0JCelZxZHdpb08wN20zR1VZeU1WMmhsbm0NCmtrMG82UWx4YjFWUjdDQjNQdUpPZ2VVSy9uM2NxelpjRzdxM0VkWW9iamZrTTFiR2l1WHB1SXprT1BzRDhHYm4NCkRZS2p2THRzMHlPM0NGNEVkWUVLQkduWjdNbzRJTDRHMHhaakFLcWc2alZiOURoaVd5VnA1UjNkY29PQlppazINCnFjUTNpWTVjRTQwU2RkSzBqUVlnV1JoUEZ5aTlWOG4wZkVsaGVmME9KTDJqTEtZUkhieHBMTTVsZ0twbm1IOVkNCjJ0aS92OGwybjV6N3dTVkJJcEhicFlxNUxyUmRsQXd5dlNJVGdsZjZJSEZYaWFneUpUY0wzbXg3ZUpTZnNjUVQNCmRIOVJZb0FPNjUwdkRmaFhaZC9yVmdiWnNVanI4dkhmNVNISVMxNnlaRTJtWHhJUFNCcEtKWnBUTVhKd2M5aDUNCllBeHd1a0ZYUDBrMlNVWk4vZ29LZytRN3J0TDVMYmdtT0FjUEluVnhRSUx2NUhxU3NnWkZ3dW5RM3Y4VFd0engNClJZbWRIREdRU3lmcEFtT0VKNUtwbnpxeG9uNTl0VWR1ZE5TZ3V0OUZMOFNDeTluQzBzQjhTeFBLTy9xdExNNWkNCjRuL1BxTXV0d1BzcVRXNHVnaUZ1Qkt2d0RRYkxoVXRscjZCdVZQNjFkaHY5NzBUQk5aZnJmTzVtcHR4ZHhqZXkNClByaitQNnVLaTZST0RISGRFOGpWdlpTcnhHUm93Qll5UE44R3BZN3BmY2hLZFUyN0FmR1A2cC85NW9ib1NuUU4NCjJNVE9tQ1lPK1cyYWFxVk83eGFCSEI2c2xZOE9aMGErYjlmazd3NW01ekUyOFJmSklwL0ZOUlpYelVtdlI1RWsNClhsbi94MTQxeUhFbDlnbzFSbldYK0t1UmpwdEZQTjI5M1NYUVpDdWJRcUo3TU1BV2l4VEdjeUtiOEw2VjJLb1oNCldNcXpQNTRVZC8rdDNkZEhDN0J4U1BrVkFnRFkvcldxdTVrQkpPVGJ1SEZDclRURlBFUUJFczRXWlJmaVIxRkgNCkMrS1pIM0dXQm9pNnRWR1ZDVmphcEdRUjlwd3pUVXBXUTl0eE43WEMzYTlBL0dVeENnQ1BEU0RLUGpqdW9Cd1kNCnJlSnZQMjdVaXlXbkhSMlFqY0NYQUM0bGJBQzQxR2M3UTZlalRmZDBIWjgwM1Y5YkRUcmN2c2I5MzNyTTQ1Ky8NCllNNW1icDJWa3VnWmJTUTlmVE5YUC9pU3NaUmpoazk2STM4bi93MlpIMG5wNm01WWNmQ2RqK2QxNXRZUUtlOU0NCnlqcVRzYXhFdm5jTFQ5TTlSY1JnemducThnbWV0RWY0bnRVQzBQNmRrNFRjU2ZocUNmZzAzS2dpeFJOcUpFT2sNCllUUjd0LytpVjdlZlM0MnBwUjFYd0pYQU9WeTdTOEVHWTVpS25vSnR4U0tNZ2NXQktVbmc5djdjUEx2dUpKN00NCi93Mzc5Qm80K3BnWHRSSktFUVg1d0J3YnMvK1Y2N3JaQXBwQ0pmeXJBLzBrM1V3cUY3czYvMXdHL1BIanBBbGYNCldjbzE3QTVVVy80UEFMNEFTVXpoU2lqY2RsNFAvdWxhbEN5TDd6ejBDRTlzekRUeHZHb1FjVWp5Rno0WDdrOWQNClE0aDZtRmRKR1huQWM2S3hYVW84aGdLemNvUDF1VVUrYitaek1WN2lhWDZKSUExYnEwbDF3Q3FvZ0Y2QTdYcW4NCk1YelpYZk9PM2szdzZGV3FTSXBTd0dNby9aZ2RBcHZRZHpzTGRjSTRXcEtRWWN2djFra05RSEpzTXpwMEF2M3ANCndmM2U1WWkzY1M5YzZENjhDUGlpblNLYXo1SGg0VFdoWWRFb2dLZWhXNGNCWWNoanN0OVE1UHBDNCtsQzRnUlANCnZCVDVRVzZpOVhURHByZFVoSFp4ZU50ZWZzWno1N2tnSlRyL2hhZjFrYmlIMVpUY0dPc00xUi9RdGwyUkI4NW4NCnIwUk5SeEZDKzZTMEI2SGJUUUZqRDBLZnkrY3VZSlk5L3R2ZXZMUkxTbEdGanFnT2pKbUJqcjdmbVVDQ0pTSVANClprcC9MRjdqQkJ0L3Rhb1VqTE5PR1FmU1lCb3Q5RmhpNkRNb1FZUTRTSlpMOUZYcFRBN1NzdWdqU3ZVTHhYUGgNCjZBQW1ldm9vYWpyWXZyYlFmVGxaMXVLb1V3WlhiNC96NmlHZ3REdVh0aWxteCswNFNPLzdqNTA3SERtNFdvb1ANCkgxOTFaaUgvUFlFVnQzQkxFUk56VnFnNUMxb3JyOHlNcGV1S3ZpYjZZUVJrMWhlWGlHUHBKRVdpU0FIS1l4NXINClNrUnRvd09TeW1MNFBmVWRjVXplV3ROcDdranBCRFg1NDhLV1pibVJPQk0yMzI2ZWN4S3pyMlVkYUxjWWk1VGcNCkJwbUpoeFAzcHlTb3dNT0JRT2c4UWdsczZMSlp3TGVQTEJwRFM2aDZrSTY3cFpsUjJQK01WcHpmTjhHL0RkNzcNCkc1eUMwck1OR2hDYUxHQWJOWllIaEhxOHo5RXFveEN6dlZLRXllcWg5T1RER1VtdXl0UkxuS1NpanVreEV1dnkNCkdIWFJwa08vSldUYzB6NklnTGg2dXZHYUh4Y3N3TFdkNysrUG9Vc1UvV3VGTHl0MFZ0emNqa01GZnJpUmhZV20NCkhtYlNWRGZac3ozSkVKR1BSRkpiMGVVNHFnYzBxait6Rm1wU0dTZURyb1pod0ZCcVZ3dS9YcC85ZFBZSlJlYmQNCmx3Rko5ZlRqRkpra3Yrc1dFMTd3QWpSY0hEcWRiV2sxK1hqaloxbG5MUkNQR0xhbEs5SUIvSUFUaWJrL21NZTANCm9RblZHdVlBQmh2cGExQ2xkU3k4QTkwN2p0MWdycXgyZm9RZkpMdkNNVXAweUNtVGpkdE8zYjNmTHd5U3JIaDgNCnd1RDRWMlJ4Umpqamt6aXZQeUJCQTZDcjdya3dyYS82TW9mb2tpVVhGTnJaWnE4UFFhb3hpZndjS01YbW1xdEENCmd2MThzWStjN2dDZVFKY0Z6M1ZUTENySTIyUllvS1l1UUhDWjBQcDh0UWxBa01qY3BreGZXUjB0UUx4cEROcWUNCmp2dHFmM2hOTlcycXU1YW1FVUdYczBNcSt2NXY2YVJmcjlYeStMYjBaTmh6OCtrczdlQWF4KzRJc2FEYnJHczcNCmVJenZwNDEzcEZ3Ty91bkFSY0JYbi8vRTlBVlhXWEFSVnFJV0ZIcllPL0gybGw5R1IwUGUvT0FQd3VFR0cwUUgNCjkwN3I3ZGJIZS9hV1F3K21NZEs1ajUzUGJEWWlubStGVmNURVVrbHpKNW4xcmMvdk1JeXFzZUdsNk1vVCtLWHUNCnVCbFNJZWRKL25Od3N1MU9hOWw1NWxrbEZ0VjhiSE9nNU5QajUzMEJJQUM0dEFuYlJoZHRvV2EwTyt6OFNZbWMNCmRYVWRmKzJ2RjZCQS82M1lqaW5ZVU9YOFByZUlKVm5EOHFGcEpDdEJUVDVIUkJoYUhZVjVMNkE2MGxxMSsxTWgNCk5XbU5ja0tWRzZwWkRack5BWWZrbTB0ZFlKOHdKT1I1WGpBc3RiSEZSd2JScVdXTkpVMjgzdjV3dVpRdHBNdDINCk5YV2JVQ2pNVnNPOElWaDJWWXdmdHJiMUhWMW1aWXJOMCt4ZEdjN21qUGxIR1U4RzEyY2k0SzBCcU1xTnY5QnENClh0dTdSTzNpWkhOYzFJcjJYeTlGSkJkOXlzcjNTb1pjNkMwTm1XekZPUThvTUt0ZytDNUhLNmpvTzJXY2VkOHYNCmQxNmdobHRuMFd4TGNrOC9sb3FVTWFKWjU4R0NhSndzL3hpcDQ1UFFlV0JBV0pSdlhscVdrUWZkaVBHcDFHMkkNCmN0MjlidElBaXhPR01wbFJlSXV3UGxDZzdSNVJhRm4yOE10N1FGazhOSzJrVkJkM3BXeld0Z29kZUd5bzZqRzUNClpHOHVacGc4NzJoRU5tVFpZS2c0VFFEZGxDU3pYL2pFQVg1VkJQRlROVVlLU3c3My9DQUhaZ3RIV0UvM0hkdjkNCjVyU29rVmlCcUlPcm1VNVhweStEZk9zUmFNRWt2K3BTekVsS1U3d0JZK1ZSRFYvQ0JpczdiT2VpNzBJQnNhVXcNCndLZm96OU5lbXhIUjdnVGk0NmwvNWZCald0dWJ4OFRPK2J0WldkMDg0NWh2dlNUcm9QNUUwS3RVV2lxQ3dxOWgNCldWK2tCbHB1MDZhSHVlNmFiUGNiUTJQK0VYTEVWZzhyMlN6S01xNmJyLzNPM05GMnVpVUl5Z002T1Y4MXlpcVINCmQvczdPcDhkblZYbG5RNUNZVmlPR01LanVGSFJlUU5DZUlVeDJURHRsS202MUYyL3pNcnFJT29wSnFiWnJRcnANCnBlWk5lMFlTVWxQR3p4bEFWOStsYkFDZjNaQ082cGlnb2dJZG9HRUxVcWcyYVN0UTg0ODJGSHVwU2VTdWJTRDgNCndJVlZKQzViWC9FQjJ4WTJFSW1KK3FTK3Y1VmpHUlR3Y1c4c3JFSkwzcXEyemduM0xsYyswazduYWJqWlRQVmcNClcrSTlZcGhURHBmQXZYRTByVUFvY3F1UDJieGpIYXZXM0ozdFZMUThIRkNReHhjV0ZHZzY4NkpORHhWcWxlSjINCklCbXJhb3U5bUxRTVUzM1lMSlAxWWM4Z1J2a095aFA5TmtLNTJtdlFEZXNoWWtiN1ErbWpHbkhBRC9NaUFFNVMNClJuY2l4bHpiR2tHV1hGWjJIazJOUXF2V25mbHQ5OHpVOFJESGVxVEdzczZLTC9lZmZtcE04Z3hLM1dJdnZuV1cNCmZOSHVTVlVnWWpFS2hudW91YUFZK0tTanZVaHhlRjFsL2VDSFljdnRXQUJsKzRRNnk0RWh6R2Z1YmdxYmNJYXYNClZORisyeUYxcTVtNGM5c3RvWWp6YWxnNG9FeGxlcEFkelE9PQ0KPXpIbFgNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg0K", + "size": 9213 + } + }, + "raw": { + "id": "16180866d0ae26c3", + "threadId": "16180866d0ae26c3", + "labelIds": ["STARRED", "Label_3", "CATEGORY_PERSONAL", "Label_12", "Label_13"], + "snippet": "", + "sizeEstimate": 13957, + "historyId": "1406156", + "internalDate": "1518279745000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-161b2ac5a73d4097.json b/test/source/mock/google/exported-messages/message-export-161b2ac5a73d4097.json new file mode 100644 index 00000000000..1727b3832f4 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-161b2ac5a73d4097.json @@ -0,0 +1,167 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "161b2ac5a73d4097", + "threadId": "161b2ac5a73d4097", + "labelIds": [ + "IMPORTANT", + "STARRED", + "Label_20", + "Label_3", + "CATEGORY_PERSONAL", + "Label_12" + ], + "snippet": "-- ------------------------------ 1io | Sales & Marketing 1io GmbH | Mozartstr. 5 | 87435 Kempten | Germany 1io | Development & Support kuhnert GmbH | Mozartstr. 5 | 87435 Kempten | Germany", + "payload": { + "partId": "", + "mimeType": "multipart/mixed", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "APf1xPCxciCfd6O0F+1olzt+I0cOOeHfFRnDKxwaEyuBo/4TUau/6j4N jt9UG35NptarCR+NGqxteQDDSrAIZD8PR2xa/IBn2xdfGNTacwjBbppv+wIBI8uqRJesF0FOFT5 8f1xl2yValBuWm2cDQG7WtHDnozgx1A==" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "Mime-Version", + "value": "1.0 (Mac OS X Mail 11.2 \\(3445.5.20\\))" + }, + { + "name": "Subject", + "value": "Encrypted email - sent with GPGTools" + }, + { + "name": "Date", + "value": "Tue, 20 Feb 2018 11:04:52 +0100" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "X-Mailer", + "value": "Apple Mail (2.3445.5.20)" + }, + { + "name": "Content-Type", + "value": "multipart/mixed; boundary=\"001a114b3ae8345d1b0565a1f1af\"" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/plain; charset=\"UTF-8\"" + }, + { + "name": "Content-Disposition", + "value": "inline" + } + ], + "body": { + "size": 273, + "data": "DQotLSANCiANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCjFpbyB8IFNhbGVzICYgTWFya2V0aW5nIA0KMWlvIEdtYkggfCBNb3phcnRzdHIuIDUgfCA4NzQzNSBLZW1wdGVuIHwgR2VybWFueQ0KDQoxaW8gfCBEZXZlbG9wbWVudCAmIFN1cHBvcnQNCmt1aG5lcnQgR21iSCB8IE1vemFydHN0ci4gNSB8IDg3NDM1IEtlbXB0ZW4gfCBHZXJtYW55DQoNClBob25lOiArNDkgODMxIDI1MSAzMTAwDQpFbWFpbDogc2FsZXNAMWlvLmNvbQ0Kd3d3LjFpby5jb20NCg0K" + } + }, + { + "partId": "1", + "mimeType": "multipart/encrypted", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "multipart/encrypted; boundary=\"Apple-Mail=_19110F11-27E3-4802-AEB0-70E542C2C0C6\"; protocol=\"application/pgp-encrypted\"" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "1.0", + "mimeType": "application/pgp-encrypted", + "filename": "", + "headers": [ + { + "name": "Content-Transfer-Encoding", + "value": "7bit" + }, + { + "name": "Content-Type", + "value": "application/pgp-encrypted" + }, + { + "name": "Content-Description", + "value": "PGP/MIME Versions Identification" + } + ], + "body": { + "attachmentId": "ANGjdJ8bsFiV_sB88rlsx5EzArsngSpwuckzEKevIhhfyW8KEH9yTe29g-SUJ7laBGggj04VAGzOobVkcg-1ear1i9XyLvYCnddUeeflZrwzgJDuos4ISBvcvoyZPaUwkldn5KFLF21YSvtzAb4waBTP6W-G3A4CFD2iA8TezHI_p3ybr375VlSrQfJONA6flEgwd239PFbJ50RCfa1vMhO26K3_qf1QB-ayHhR8e3CrTNoKnsukAPAKL0QLXq7I0mG3l7s5updKuT01PiPRT6l0J_sZJV4qZsEiVSgeibAJaHbDvftyKEA2aBaTHPc6xk1L8mQy8ZLtzNgfAN524fZsDjW1uzYh9vhXVbUVpTj9gpttFpB4QHp1xUL_Uio", + "size": 12 + } + }, + { + "partId": "1.1", + "mimeType": "application/octet-stream", + "filename": "encrypted.asc", + "headers": [ + { + "name": "Content-Transfer-Encoding", + "value": "7bit" + }, + { + "name": "Content-Disposition", + "value": "inline; filename=encrypted.asc" + }, + { + "name": "Content-Type", + "value": "application/octet-stream; name=encrypted.asc" + }, + { + "name": "Content-Description", + "value": "OpenPGP encrypted message" + } + ], + "body": { + "attachmentId": "ANGjdJ9FU1bpT2FkvAKH1lNX0PD6wW_rm7vR0ycZ0pdP_VcspoqtkmiugTEVs3XuxvO8D7bKuWo9HUEy_VhEKhQQGVpkgtqlrJH2rExNrnKX7L7dsE8jacNXTS6c4Pv_SyBdL8-cZ46mZd1L_hQqSQQqfNIP21ltKZLTBceWt58pOxGCBtxmd0bmuLjgBP6hRICrMk7hwhT4No0z_xxkhUI2gh9X9wq34VOXTxgjnUtM3TpmTyIvsKi9swI_pGMBvqaxHx75ftY9lVz4m-STUEb7uITLhmw6__IFbdhxbTZo0feKebGKZKVs6iVGiC5T4-WcwmHgL4mDFriV7TyJ-gN7pdQRQ09eUKtAQI9PH9Gfj8rFeVd8QTKdUvfK3t8", + "size": 3123 + } + } + ] + } + ] + }, + "sizeEstimate": 9242, + "historyId": "1406133", + "internalDate": "1519121092000" + }, + "attachments": { + "ANGjdJ8bsFiV_sB88rlsx5EzArsngSpwuckzEKevIhhfyW8KEH9yTe29g-SUJ7laBGggj04VAGzOobVkcg-1ear1i9XyLvYCnddUeeflZrwzgJDuos4ISBvcvoyZPaUwkldn5KFLF21YSvtzAb4waBTP6W-G3A4CFD2iA8TezHI_p3ybr375VlSrQfJONA6flEgwd239PFbJ50RCfa1vMhO26K3_qf1QB-ayHhR8e3CrTNoKnsukAPAKL0QLXq7I0mG3l7s5updKuT01PiPRT6l0J_sZJV4qZsEiVSgeibAJaHbDvftyKEA2aBaTHPc6xk1L8mQy8ZLtzNgfAN524fZsDjW1uzYh9vhXVbUVpTj9gpttFpB4QHp1xUL_Uio": { + "data": "VmVyc2lvbjogMQ0K", + "size": 12 + }, + "ANGjdJ9FU1bpT2FkvAKH1lNX0PD6wW_rm7vR0ycZ0pdP_VcspoqtkmiugTEVs3XuxvO8D7bKuWo9HUEy_VhEKhQQGVpkgtqlrJH2rExNrnKX7L7dsE8jacNXTS6c4Pv_SyBdL8-cZ46mZd1L_hQqSQQqfNIP21ltKZLTBceWt58pOxGCBtxmd0bmuLjgBP6hRICrMk7hwhT4No0z_xxkhUI2gh9X9wq34VOXTxgjnUtM3TpmTyIvsKi9swI_pGMBvqaxHx75ftY9lVz4m-STUEb7uITLhmw6__IFbdhxbTZo0feKebGKZKVs6iVGiC5T4-WcwmHgL4mDFriV7TyJ-gN7pdQRQ09eUKtAQI9PH9Gfj8rFeVd8QTKdUvfK3t8": { + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCmhRSU1BMHRhTC96bUxaVUJBUkFBcFNPRW9XWlNwdkJOTUZQZ3loYm5NZDNKZHYyK3NRUlNzM2lYMjh6NlRzT3ANCnhxN0dxbTF4aC8yN0VlSmZpc0NaSDlBZjFhQjlPU1FYRHpmWkc5TnF2WFhRY3NNc3A2R2NxeXpVaHhwMzNWRHENCjV4V1JBb1M4TTRXdkVNR09LeDJxNENob0JocGw4d2xvRFF0UHRuazdjRHYzWVJneEYwSlNrd1R5LytzNndBT0oNClgvVUx5QWF5SjhNZ0VUa1JwRmd6WXBXYVdUbXJKc2RzeTkxQVNKQVArS3VqR242Qk5zczBMZHVmV3J6T1pteHcNCkozc1gvU2FzdXJNd3dhZnRSY1FkOUNWemNrckFGZXV3bjRmQ3NyNGtGZFIrUkRTTTdHUlBNNXJ4V25UaXVsZ2gNCjlTUlR5ZWt2SmxwbndibjlLNnFQTzZvaVhWRFptQjVHcGwzT3VCbDVWL1BhelNIcG0relB6Tnhpd2xRT29iZ04NClAzNVBmYnBKQWkvcStwU0VyYTBkbVUxSnRlazdzL05oL3NSZWJKRWdBWHdadnVVaVRCdTJ6ZEl5Z1crSXRzYWENClFxdmZmeVpxY3JZODVRMEtGK3o1ajdNT1lYTDBFM2JraEV0cG91MHBqZE9FSlRzYk5sQXNGdTY0b3hSalVqa0QNCnMrZnBndjNoblcrdllIUXk5OEIxVkV6MVErMkczc3htQXJlcG5hRDdLeWxqNm1ORS9JMlFQWUNsL0RxeEJkWnYNCi9TS0w5RDV0NkRLcWowY3U2VHNpdFdOYlQ4U09xMW9KUDk3WlVjcitOZzlZSERZbmI2djNtWGRLWjJVeHRxVkcNCm1YekdVOXJjMlFXK2x0UUlOcGowdVl6S05RaVl4WG5WYU8wZVlGNHdKUTVFa0plaXhMbHRVUUtTVGxhclFLT0YNCkFnd0RCbEF4OTliMW10WUJELzl5QWNteXJ2bEFHRXZuNWJTY1FYVjBrNEtZMG4yZ3BYcDZBODF1eUpBdjRpRm8NClV5ZTRMZFJsWkVkeDlXT3hwdWpmTENpR0FLYU40dGZEb0R3NEcvQWxMZWxPd0c4N0FjdUswMUVZUU9tdFZXbU8NCjBqUGtRSmttUWU2OFo2OEtSVWxTN0Jwc0xyaUMrZlNqYlQ5d09saFZBNnhhQTBEUWZpZy9oTWt2WnAvQTJ2Q1QNCng3T0U0OXNpRzZseVdIaFRRWEVtWGZsR20yM2EzRXphMSsxNkxuOFREVUV0M3VGaVBGQWc4V2s0YXJiMk5NdGgNCmx6UE92THREak9tVmpwYlBEdEdqbVVlQ2psdDNtLzNJQjJIcklJOUtaclQvblhCYjI5WGVuWGE0ejNSdjh6aUYNCnRCTldPWHFLajRFMGFZelhKS05Edkd0SzdEZG40Z01nZExmc1NlSjR6TDl2d2FtK0wvSmk3V1BiM1NHU2V3NkgNClBLR25PSmoyZkJNWFVuV3h6TERmN0taczhaNk9ONjlQMjZrWXJ3ZCtNcEwyaGtoRWk1ZllrcEhEYW03dkJVVWINCll3QlVwR0YyTXN4MllIN3N1Q3dhTlZlWFgvYWtOemV1Nit4Z3lvY1BURGxJUE4zQytKc1pJZWdsdzdsc1dzK24NCjNFY1R2Uy9DNnpJT0xUSDBmWUFFUzVkemMxc1NJWVBKK0U4Nm5oQzhzbnhuU0lzSnlhQjhPSnhTZlZVcmVNbU8NCncxa2lCZE11QXRVUE9VczNNRTlYYXFpYzJ6UXJjWDFHL0tTTmpzWENORWYvait5L05wZVZQOGp0eUdGbUhkaTINCklhQkZlejZyTU9RV21FaW1UaHo4cjc4MDVqdmZZSGxDV1JOMUFEU3Z4dGQ2cGp6VWdyZG5tR3U4bXFmWjM5THENCkFUNVB3THp0YU9qYUkvaENPZFB6amI3LzVPTHZBaDh2b2M2RWJFWEVIUnZnMFV0N3ZpV25TbEx3MlZyZ0hYTTQNCnVCRUVNVXRSVGFGUXIxOUZLeXA2OThWK25Nb2k2aTAwYW94Vll4NUswZmhSMjhlVGl5WkZSQVlMcG80alY0cDcNCkc1d3VTMkJsL2V0TERaK0tsV2pOME9kWm4xM09JTVYwaE8xMlJpYkI3aXhLMGRSNmFGeHNyRHZMMDVSSWw2Q3gNCjlvTGFCVFFzK1FjSFRHTDg4K0owZHhZOVEwOS9Ca3o4VkpjSWRNOEJJSlNQRGoyWjk3RnNNUGdvMjFOTlI3RVcNCmFLWS8xNy96dEZIWFhzaDRMUFl4cjh4ZS9qejhpOVBZUENvM1ZUZTRFOGxXN3IwWGJYQ3NpbkZ0bW91Ty9hd1gNClpGMHBnTUNuU2ZUK0Zhamk2VEh4ZmVNQ1FFWEgvQTdITGUzMmw3Qi9uaGw5cTdIYjZ2RUlKcmF2N3lmU1NwcDQNClc5UDBRb3o1eFhSdHBoY3FFNzhUWEdObE1ZR09aalp0TUtrOXFQZVJBZkJsZjlvMEIxVEFQQVZiL2NhWWJwaDYNCkNlK2QybVJQU0h2L0ZabEh0azNhVmhMYkVWQmRmYndjdWxpOE9ZKzEzRWlVdXpHYWhyaldYSlU4L1ZqMzhVOFYNCkd0OGdsbVVrc2haRFgrMDIzWUo0ZS9CZzNtMUNsbmF2WG5XK29LRHNVZnZIT2pJQndIMVBHamtobmFFcXFYdzQNCmhITStxbjIxS1ZpeURlbWd4aGlmZjlydXZOcTB3MGZXaytkRDFiQ3VTOUpKTTNMcmdwcTdFZHVCaFAwOTI0RHANCmxRdkROSE1PWHFkbTV4NmNlYzRaREpVSlZLTnQwUk0yaGkrejFaV3VaS3NObm0yV2tWNVZNakU1bTRrVmtMS1cNClJ6Sk9wWis4Q3pNaTNvWU8yUjlCUllwY05qTkVUWE44Nm1ZYU1KT0J4WHlVTTFwK2NOVnRxakUyTDdFTWh5K1INCnM2c0tpRFBYMVZIWC9VcklvQmlzY0FKc1JPekZKMkRvTFMyMW9tTDZWMW9wQ3A1eWc2NnQ5UDRrc25aQy9QVFQNCjVqbmRxV2JORlZ6Q3N5YUdqSDlza0h3SGxGYmd3bnVvbnZod1NoSklmakVuRzlDSUtVbHNJc0hJSHh1VUtPMGoNCjRkbUNtZnBRVlVZZ1dOc3c2dTZGWjRtWGFUd3grZzhlNUJqUDB4Vy92UWttc09sdFpueHQ5MHpwOGF1anRHeUgNCk03NDFyektBcDQwd1I3bW1kOHFpQWltMzk5eXlMdGhOU3JKT0dJNExZYml4SU1FazBJZGlVN0JvSHZPa05qcUYNCkU2Y1pCZ0hJc3RDbE96NnJZSUptek1lSlNENWtuakhCTzNPNE9JbEZPdE9hNDdqT3JVNXlDVjJNYVV0TGNJOEENClMxWVo3NWJnem5WUVpFSFM2cU5IN2xmdUx3M0RQbTVvdHZZSlF3WDlOZjJFZk5oZHA0WEtpU3lOOUdzbHpweEwNCnRSNUZNQTIrOTdNQUM0clVnNklyRUYvc3ZNMEkzMDdnL0VLR0NKcDlLMU11dVZtclV2T3VSeERjYmR6d1RSTUENCllzN0JqZjlqYXNPMWd3OUNYRS9vV1BRQ0VSbFpNc2UrMzlEbUprZldwYzNqeFlMbzI5T3F3S056eWpvaHI5N3oNCi9mZk05OGR3bWtMSllyOEhoL1NWbEtydnE5OGtBNDAwLy9ZbzlaaE9xdlhoeEFDNTFkbjdJZGxQTDBoclJWRTINCjdFNGNIWlE2azVSQmk2bVJzMXY2czQ3cWdVZWtRQUZmaE93TlVFQ3ZLenVLQkZZRHRVcHdnUzMyUmt5dGRjUmYNCk13aHFhdTBGNXJiZ2hkV3BKQ1k5dmZmaXczcXBUaDNxMmJNVm0wWlJSMlNDVXRKOUwrUkM3OFBTdGJOdTl4cjINCm52Q2dxeVhKVWwwcDUvUWJxTFVkdExyNVpSc09zUG5LbzNDcW1lZHBrdjlwNzVVZGEwVkFTaXNPVmY2NEZjMzUNCk1hN016ZnFMVHJQU1FTcE5mTExjDQo9b0tyZA0KLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQ0K", + "size": 3123 + } + }, + "raw": { + "id": "161b2ac5a73d4097", + "threadId": "161b2ac5a73d4097", + "labelIds": ["IMPORTANT", "STARRED", "Label_20", "Label_3", "CATEGORY_PERSONAL", "Label_12"], + "snippet": "-- ------------------------------ 1io | Sales & Marketing 1io GmbH | Mozartstr. 5 | 87435 Kempten | Germany 1io | Development & Support kuhnert GmbH | Mozartstr. 5 | 87435 Kempten | Germany", + "sizeEstimate": 9242, + "historyId": "1406133", + "internalDate": "1519121092000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-1639b8ceb6c44a4c.json b/test/source/mock/google/exported-messages/message-export-1639b8ceb6c44a4c.json new file mode 100644 index 00000000000..86476c4a904 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-1639b8ceb6c44a4c.json @@ -0,0 +1,147 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "1639b8ceb6c44a4c", + "threadId": "1639b8ceb6c44a4c", + "labelIds": [ + "IMPORTANT", + "STARRED", + "Label_3", + "CATEGORY_PERSONAL", + "Label_12" + ], + "snippet": "", + "payload": { + "partId": "", + "mimeType": "multipart/encrypted", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "ALKqPwcx1oXzx19z5EjJncv36k+s6fxt+8pVuyeSe4qOem2re+syU5vo j60gxZGp+tedOa0BYXf1kIPUwg==" + }, + { + "name": "Reply-To", + "value": "roman.pavlovsky@gmail.com" + }, + { + "name": "Subject", + "value": "TEST: FlowCrypt Feedback from roman.pavlovsky@gmail.com" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "References", + "value": "<20180525211411.1.D3D12EE92DD69B59@cryptup.org> " + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "Openpgp", + "value": "preference=signencrypt" + }, + { + "name": "Autocrypt", + "value": "addr=roman.pavlovsky@gmail.com; keydata= xsFNBFsIbl0BEADhTf3ad+Qp0+oYP5lXspAlpjy6NROztYJV5zL7mgGm5FmPLQw6xNsjzuSK ojfx1W75dx2ZBga9hXsiAi+smSJZ6Qqt+O32eQ9emoz/DmPyfZfAlFlyUKJB0OFsr/tbp074 p+oU/glnKwBPrX4fRjcVU7vLm9g9J0+vO8j01j0JxmGwGRxwMuGxmVc+PtpnKLxhEveCBygh YrO1Y6lGGviowcdPEvdGQ863N35cSb6escIiEnffPONJhIzbhY3YU33N2LEhbCDzBTdkdSYi xe/0d8cwdpyaXcOTdptVD6hpXuatPB3otQBMVZ/GeELWYwO+wIw2XHodBAh645woZomq+q2O lpmgUfGVPNyzpPjm5LMMJHWoHNTsIQ7HZko1G3sfzm/lTUg7rVQa5XH3TAaE9L1z/Z1/OT4p k3/PH6M47/XJ7CoouXob2f/4tpm63RWccnyVKYUcy0Sp7IT+6AJjhatNY8BDzuXrbqQXlAAV F/bdh6vCXDnWiOvDrFEe0efR253fxznyO98+3Tjbtokkf89PWulKXkjoVNsFm3hjRsdOxCB+ swSzNX0I3ySJS5Tw2roZG9URsSQH0PbkYVmtjJDU7Zf7mi4tl2iBTPQLqBFlMAhOTzdtgScM j9N+W1hfTxgrYHiiYmfR+zR9mpf7BrtGwntB+iiJ6AYlXgC9wwARAQABzUzQn9Cw0LLQu9C+ 0LLRgdC60LjQuSDQoNC+0LzQsNC9INCe0LvQtdCz0L7QstC40YcgPHJvbWFuLnBhdmxvdnNr eUBnbWFpbC5jb20+wsGOBBMBCAA4FiEEw7NZ/6+9/kMk6WAVsJQNQpMBojwFAlsIbl0CGyMF CwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQsJQNQpMBojyyCg/+Lf+PiTwMPIkNiTB6FF36 9ML3O5X7mSXRUZZr8EFSqmO+ggn7LjCYEJvuzPeKhASHyUTuHQgoogaiRB8F4nLk8L72T5RQ AxTU/9sOZbGzwESX3kFNTM+CbueZlry1p0tpCKPsKtFaigxOIQGM5z01+VUh6iwou+6HobEy YQ/y+JXC5iA/KPc1fLPnDsRT1V3OUaI7z/y7P4kiD7WTb7vL8brRV3A7mMOf4kAHB6wLzRpL uWroHonM5SeRrzKfqivSK9fswnYUSuFRj0I3gxYUszRI33EZwTQkKCU6Sf56lqQHX+5Il6gY jo8SmfrOyNnHVP85apToD21jnShipGUUOkmIDocOZKnb5Fs/ahLmmdE8TRlMBpdXeAi55TSk 5O/W+xUYg6tYpMBytag9gHou/6FIckg2Hv6SyY0KzeHXfiKUCwcH903oaejlyNcD1FJU/E9X sJfzCodrYzY7fXjsex5XGPxqXbUWg83aOOiFcoKpRGm7KzL8Et7AVu2MsEZqF9UtBVhegL5a YKdegCgAR1WJO0EgGQD9/He3eb9Rcn2E0XDf4vxmxCyLi1O1V2V/tAjk79XLEA1D+ypraFBP AReX7Lh/BHHz5QObMkgga7sBGSj0gKec6bC9ZDm1+mzfP28MimYeYbbD5l4t//QrAiT3JXjj Ey6NMPDexcFRTGPOwU0EWwhuXQEQAMXNujPA8X3Pk8D+lFoPT9OQvR2EAC3bvKUrYIjzR4ds lstV6iM/4zSAvYYcTbrpNRacc3cHWpbVn2BI4mm8jN4LArB7YLsD/GKKxj/MmgDdI00JHGeO qfUvMePvoexSo2PNvzVDesUgt0W/whbixvPSh2TmsrBhbRSgMyUh4WSQJM7o9/pcrjAYV8aW ZmDTzx1RTlt8kSqw6rpTelWkG3rmxUgzSKtjt3wY21ZaP3/Awhk9OLWvWWanLci6qdC5Ehyb NuHbmKowgD7SKbVRri48P2ewsBj//gU+PvsnTkIZ1MxVkVzNUhCJOLRtO5iL/Naxfan4hmcj FmB98yYVXLmXmcmistHQwSciMqPbqJ3NOlOZogshHCZS5ov3W1oW4+Mf2TPVNNWuR7gMzhtM 7iwWKpBb+xbcMD+VjnRpWIpZ5Um694kBdrx6wUeAfObnSAvb2WEb5KVt2zZk7m1UTmKG9zQZ isaI44V2G8SJcuQ8EwzvQo/Qi/mfYOsQ/2GCM9uM8h4n+amD3V3icTYngOiDiSz2tHXXw/7w n5DGzWlqeFcvUv2LPDgyQXrWnyYIQV0krOPpPUSZMly/r8YzxFKvfS5ooSqDotvTrkBIM+Ef x8QrvDQDCmOdFVhs0RQbjsl/hjC9uhrhnWTSBnh/kpNrAc+KsGIaMJjjhWqVoOGrABEBAAHC wXYEGAEIACAWIQTDs1n/r73+QyTpYBWwlA1CkwGiPAUCWwhuXQIbDAAKCRCwlA1CkwGiPNjC EACU0S//2Q3KUCy9NEZo/1ybKa5ui451WXtw4lTxA1mcXJe0krZmuG9DzlzwaGcgIaT1dOo/ njlvSdj1jzajH1IWPT2klxOiAzNSvd8PLyWsTbdPEXb36qYHWxkvda917GOQtNFgeBdKIgdg VN0P9Q3ymgMoJ8t1yE1TSk639BLNR3TthIKpyFZF6aKKuwVjZk0fhRDhYAvyxULK+DR07Chr hAvFaoUDDfUaLPt+AUI8BW8RNRvbpGDOnzpi57t0bYDKl5yIEcH34ZO5R/4F8a+vHdss/nLj v1x/yf8lZLfRQYFl3VzLb/gky6AAo7LaOwnHc7BX4s9VEzIKOKuQSQG3P3/hMQD08q+sAl9k sO4TmqgAwxZ7BYglKGl7joQK3IgFPeeK5E6iFLxpqKrfUdDQ5ZACOw8kWWGP+R4s6kZNR2CE i/3C4Mk+c+kEQh/MZvtyclj3uAkf1TvH1gJIOfq315zhVjbuYZoGa3n1MrvKF0OEIBeOCXHH CXOmWzvgdgxcdWq1DtoBHDuNHsEicOSZukiEvzxB8cJEBMAchn6PuxeCuO9oBLJvOk9PyiVr YJn3d1303SDviRDkx1FV1Cu6odjBuf2kY0yFGQjkrPoyrpwk3Q01SCCSd/iDTWOn5NOPLtVb O9StKYFIU1Qd5AQlOSrrT+vdhv34Zq3tkqOIDQ==" + }, + { + "name": "Organization", + "value": "Персональный адрес" + }, + { + "name": "Date", + "value": "Sat, 26 May 2018 11:24:44 +0300" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "In-Reply-To", + "value": "" + }, + { + "name": "Content-Type", + "value": "multipart/encrypted; protocol=\"application/pgp-encrypted\"; boundary=\"aafyY6D5NubFNNLknwYOHu6rn8XVpZr1F\"" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "application/pgp-encrypted", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "application/pgp-encrypted" + }, + { + "name": "Content-Description", + "value": "PGP/MIME version identification" + } + ], + "body": { + "attachmentId": "ANGjdJ_BS5zM2kqj9xiVbALserSxB_gj3ZnpwfT-arMVjz_MTqQPAkdiQCseLVy5PnAVmnKyEnLhRRdheO6Fop5a2r3uRWLiKI9ON6JEapgo7kb6mk-97KNQBrOWJJE1Nfagwxq5PSK7XbRz1U_st8Cse984h--AKrEVatTci-t1SWtPMGBurk1MuzJ52MNke_mL5ChwSULoWaiZ3hBg1kDbkZFTR1G9NmoTKQpKiMGup_G48iBG1IJ07nzLR-X81b3yqgcJL9RMxwXEsptLpx56ViAdm6dRZF9tnTAF3D5bqRcn-oQBYeZNLXQyXfImtBZtz42OTsD3_igDeSwhhkWl9EKw_O0H6TGaQ4golwYCGnpJE2XVxaxJEYHSVvA", + "size": 12 + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "encrypted.asc", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream; name=\"encrypted.asc\"" + }, + { + "name": "Content-Description", + "value": "OpenPGP encrypted message" + }, + { + "name": "Content-Disposition", + "value": "inline; filename=\"encrypted.asc\"" + } + ], + "body": { + "attachmentId": "ANGjdJ92Gg4TbYWa036rwJiMmNqkzmEFqitlWlWQ2vlzuEOibaL4LbUv2Ia2mkHa_IKCDnj72Snq82-t4SYF9Ksk-9XZeR-SIo1qoKeXvPZltg3D6fX9DdW2tskp-JFnpIupKG7-CO8eBLklpMHCBOG-PsILZrjzWHZCNJ6IUROP7pDO8c4vAyaayvpPlw6QSbTyuEdPchvQp5pAeNv3heGeKUDuVNnkaDbs8Oyhu-UjIM4wRkCOjwrJpa2UmYSbTQ_zBhHR9jLqKoGc4q62L_nfDDrW_jHNCcrBSmuclH-O2a-W7gLDRVGK3WmoHRQHgcnrGaXQF_oV36R-qZlg_NXABmrBTbEs9HKtMrRYK8kEkn70rPkv8oUD-46hsb0", + "size": 7309 + } + } + ] + }, + "sizeEstimate": 16976, + "historyId": "1405978", + "internalDate": "1527323084000" + }, + "attachments": { + "ANGjdJ_BS5zM2kqj9xiVbALserSxB_gj3ZnpwfT-arMVjz_MTqQPAkdiQCseLVy5PnAVmnKyEnLhRRdheO6Fop5a2r3uRWLiKI9ON6JEapgo7kb6mk-97KNQBrOWJJE1Nfagwxq5PSK7XbRz1U_st8Cse984h--AKrEVatTci-t1SWtPMGBurk1MuzJ52MNke_mL5ChwSULoWaiZ3hBg1kDbkZFTR1G9NmoTKQpKiMGup_G48iBG1IJ07nzLR-X81b3yqgcJL9RMxwXEsptLpx56ViAdm6dRZF9tnTAF3D5bqRcn-oQBYeZNLXQyXfImtBZtz42OTsD3_igDeSwhhkWl9EKw_O0H6TGaQ4golwYCGnpJE2XVxaxJEYHSVvA": { + "data": "VmVyc2lvbjogMQ0K", + "size": 12 + }, + "ANGjdJ92Gg4TbYWa036rwJiMmNqkzmEFqitlWlWQ2vlzuEOibaL4LbUv2Ia2mkHa_IKCDnj72Snq82-t4SYF9Ksk-9XZeR-SIo1qoKeXvPZltg3D6fX9DdW2tskp-JFnpIupKG7-CO8eBLklpMHCBOG-PsILZrjzWHZCNJ6IUROP7pDO8c4vAyaayvpPlw6QSbTyuEdPchvQp5pAeNv3heGeKUDuVNnkaDbs8Oyhu-UjIM4wRkCOjwrJpa2UmYSbTQ_zBhHR9jLqKoGc4q62L_nfDDrW_jHNCcrBSmuclH-O2a-W7gLDRVGK3WmoHRQHgcnrGaXQF_oV36R-qZlg_NXABmrBTbEs9HKtMrRYK8kEkn70rPkv8oUD-46hsb0": { + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCmhRSU1BMHRhTC96bUxaVUJBUS82QTdnNXZ0OWppL3AxN1RFdEorTjBTTEtqMy9TVkNCR3NVQjFPUG9HNWpYS2QNClVSZktQRFoxd3dsQU5vcGlhcW5QT0ZtWFFhM21mTG5vbnZvSGxSNG9LN0xCQkpucXhhRFIrMWFweFhlS0pkOU0NCjl6YjFRVEhtR2lvT0dlZ0ppY2M5Yi9PdEwrWEsra0I4a2J5MC95WVZXSXR3Z2hmMzJWakZCNzZVVmZUbk12aDUNCkkvKzA0enhMSjh5ZWx0OW0yYzZURXBqUDhsWWpuNThPRFFnZFhyN29ZR2ZxTnJvOXVOS0RGSmY5bXdvZzdXM0wNCkdhQTFmR2VQV3ZhVG53cHU5VVo3MnFzUm44T044dm1JMjdncVAreVcxZHJsVVlsMGdQamhsV3k5eFI2TDFyaTENCmtPRDU2Z0xoTCtpeTk3RWFlcjZqVEt0dXk5M2VzdmVoS3FSbGRCbUlCK2lzUUZUUjFUVjhVZ2YzRXpUbFRXNVENCjBqV2d4OStnbDk4QitrNVR6aDhWb0NvaytYYVF4ZmtLSzcxTEVxTlR0QWpGSUhwekV6MVFmU1dQNDlrWUJNaVoNClE4SDM5TktZUGpMYzh2Zk9XZ2REa0s0dHdOVUFwYmpDNnBsSWExaGZRb2lrdEZOTjdpUk5wMHNEaVNoMkJZM3YNCmtEaW1hM1BsMUlCbExTWnlqWlJWbHNsZWJ6eHRYb3JKU2dESGRvWkxpeVBMREV1enVBSFQ1dkQzMkhVbUJWQk0NCmpzQjBOMk5sdlB1OUFJWnZMdFliU2V2aVREeHJpNWJpeTFuN2dCTmFPNnVkcWwvRjBIT2JJaW5tNlcvQWRLK0oNCm5oOHptVytXRWg4eEppVHVvY3JtQ0lvYnE3K055ZGhBT05WNDA2WDUrdkxXTmJFcTROT3AvZ084M3ZyUGVGYUYNCkFnd0R1TCt5YnI5R2JXUUJELzllV0lvbStvcENUT1lzM2VtZFF0cDNTekpnVEdnWWVjVXBkYzA5dnJaUkdEbDUNClVEb3pqN3hldWxYa1Q2QTdoSmxnN3NlNTA1Q1lFdFpOR2RvWlZCSEtReFFzcXlEQlhWUmVORFMvRE9mMUJJUDMNCjVnVUltOVNET0ZjMnNybzdVNzRIVGhTUGVQRlBzbEljbDlXQ0Y3L1piaHdJUS9YMWdrN0ViZFJFY3Q3ZjFueGgNCkVzSDlFbGRyTkZUNzlMdDZnWlo1am1lRTJZZGdTQ3VGb2Y2NGNJbVJlTVUvczh5NUpJNng2NUlFd3hUTkhpUEcNCkp3L1I4NUJoM2JsME44Vmx4SktnQlcwWk55SmlGOC83SnVCdnNaM3U4U2g5akg5cVNFMGYvSVhZdlpFZk1tMDANCkh6TWF4N2pGL3ZjL3RXOHJUZlp6SEx4Z1lDSmFJSkhBZXFua3NtZjJtZmdpaUNyeVZVK2tPWU1OT1ZZdjRQWW4NCkVhUUxYL1kzNERrb2VGRFFKbkNuQzJWbnk5Q0dXNnF6MVV1YUNLZXMvbmJRcjhzcGhwZnZGNytPMWRWRnFpYjENClN6MjV0VFdRcWZuVnFvaVphVm5RcDlSYlJOMkxsUTZqNlltVmFwOGhMTVhQdHUyZW5JdnJhSDl0U0trRWladTENCjQ2MTVPeWJuSVZoWWpQU2d6clpqaWhZejhoZ3hsOUV6bkNLbkordkRUVU1sNHN4eEJud0YrcjRyRHRBcy8vV1UNCmVHN1FmcnVUeUxaLzQwdFRnMTZXZHJqSzRBV0h3Y1FOdWYveTIyWUhQMTNHM091aFdhRkxZTHFwZ3dPNUN3RisNCmxrUk90WGRJWmNtRDhkVi9qRnkvbXVyTUl1bHlSQ0FIS0RHVUpjamtsQTAzQ1cvVVRlMUEvWDVzSUE1R0xkTHMNCkFYZmtsMWxOVkhRRnlHb1ZxU1hXMHpVS0lpNTNFa1VBQzNmYkVJSys0bGpmM093ajlJNE0xNFliRjYyRG4xZnoNCm1rNktHUE95QXBPOGpIM3E1cFNUMmNXR25sQWwySnJ3bW0ybU1QdFlLV01TYklIYXVmTURYNjhzdVdTMVpOMysNCjF0OUxlaHhHOXJ1VENyZzgwdDFIOUxsYXo0ckhwaG85dlhPbUlGeFBIbVJFTitxbzZkcTBjd1ZiNVRrTEFhbFQNClU3OTV0bW1taUk0bitTUUE4b3VQYnUvdm5kRlFHWDFJSkM2WjFibG4yaCt4UzJIWHpTOFdUMTdzV3hHS1pZaXENCnZpTCs4NVFNSDVvTTdtUUdXMmcrbTZMeG1BaWJqbWN2WUlFUGNzT0pwNVdCTXR2KzZVMC9ITVhKa0xXUzROVFUNCmcyYmVLam1SSTl3eVQwVEhrUUVCV0owbGNZMUNtYnYzazF5N1R1aE84MEZTQmg2TVVsZkZLUk9zYmJnSjUwRzENCms2K3VDdzJVT0gzeFdpdmozMC92QlU3M2YrRkx0OTlmWDhsMnhmSXhSdXQzdWQ2OHRqVllFdHE3ajJtNWlKNEUNClptWmRqUGJmV2E4enBKclNpTCtUbUpVVHRySXpwM3Z1RDJZSS92WjcwK3R3L2NpUlVuQ2s4K3ZzTnovTEtHOG0NCndLejlubW5jNHFXbVJHazNUcUVqQzQ3bzNOOXIwTExUblloNW5wZW5hMG5zMEFJWDMzdzQ1YWZqa2IwUThDc2INCkJ3enVlZGdPanJ1VXZPYWNVbzA3bU5yZ2pVVkRtc0dPWkpMdVFBNEtwWUE5bzJvYlp3NEZoR1hyZE1nWW1wNHANCm5EZlRyOW5QYXNmZzdMdytxbi94a3djcGMwOTBCQkpBL0F6dUNyell0aUtURUgrN0ZvakJSNkFVYU9mc0pTdmINClZ2WXY4TjNUaWtxWVQyZ1RrUWdyd2QvRnRDU2tHVTQvckNJUFF6Y05kTmF1TCt3dmF5QUZWU0pFMWwwQUNsUmgNCm0xL1VOdnZKK2t6U3l1UlRqV1pVSFoxME8vWGRsZHRMYnc1RkVSdUxUSStOVjJqdTFVaCt5YitQQlQzVytXWlANCjBrY0RGcjlNRnUwTnoxeGczSDl1cjFkVStRYU5JUjB2aEV2Q2JRd3N0aGRkSXUwaXJYMzhHcC9LYkwxZjBMaEcNClcvQ2l6UnVVM0lIY25FNkZHcUFpcmJNVTNNMHowYkY3dWYxMGJkQ3g3UTVvYkVyNlVjdkhaYldFcDB6dUhTem8NClZsN014bkVKT1phcXM3OWZhVFAyTjNaWFBydVpLNU8vVThzL0Z2bTBRT0Fobk5NR3pDUnczdEtPUEZKWWkrb0cNCjJqcGZseWFBN1BXNWFQSFJNWmpYUHFOOXBjVk5yK29DRUNORk5uMWJ0QkNMbHFRajRhSjYwWFFQWlBLcTRsSDkNCkVpY0ttaG5VMjUvUDlVN2hXcExqU1Zxbkd0SldMc0pVcXl3K1FuTGg3NVp0K2ErVTE2cTZHOU1hWUlCMmJFa3ANCmpMUHRVeEEwUllWZlhuOWR2d3JxNnJMR1JYbzZkZzVWY2tSa0FWTi9EeGk1WlNGZmh3L3BtTFJ3RCt3VEFRMlcNCkNtUmtvTXdFcHZTQUIxdHJaZVowaUtUUDd2bC93TDVkYUNnZy9tcHFFajVGc2wzdWZYWmNXckErcXFnVEtpSysNCktzaFM1WkZuUG5rQzZTV0I3WEVSaXplS1VEeDhWK1hNR0QvNzRGQlhsQ3p3MC83d0xVMldhbDVlUlJTYUtlQ2YNCk03ZW1pN2lXUjdYMHBCUW9RQ0hLNlNEN3BRc1JOb3dqQzU0ekZta3NOTTB1OXRjd1FtT1I3aHduNjVuS21NYlINCklWMkRMSHV3Yi9DNS9ZQ3FnTlNjRU52bnE1V1JPNVRXVUtkYzV2aHBEZC91THNyU0tCOERncXdUbndLeExpeVINCjdaOGFiVXMybWRvYUVCU0ZRajRNbVpIUDg3dms3d204TURrWitaOHlDNVBOQzlhRXFGdk5WYXZvVHZmU3pPKzgNCkhJaktyQ3FaNTZRbkVGbE0ycUNmRVJFUnp2bFZWL1dZYWo5NUtFVjlOMm5lSnJDaDhrcHdIbWFCaXMyMUk2S0oNCnBac2JRVjlZS0VqMnNFQnRuZEVUWFdyOWRzYU56eStsYVVVblJ6YnJIN09jT3ExSlEwR3hXNHNHSG1va3kwR0UNCm1udW8vWVRCTHpQcWhUcm5BV2FTTW9SaFVEbFFiSGR6OGx5TnlRRW1TTkFFYm1COHpmSXpWOVF3MzFOSWE2UXoNCkZJU29ZUjFUZW8ra2JYUnZBQkdxdmxhRDBWblMyZ2RnU29DVzkyUHZFd2dCdmZkS05tT2FuODBQRUxGYXF1akcNCmg3NlJ0MDhnMFVHY1ArR25VMGlDeWRqYm1UT3RYQnlwRk9wWFFoN3BoZDBSbGtubExocm83ZmhNbE50SE82SmYNCjZvMnkwemNFRXUyQ3ptTmlOUzdHNGs0T3Awbzh0eFpqQmZDUmswSlJtemw4SUJpV0VrMWVhVXMxMUFIbFZ1bjINCmhQOWlWeUYxUEFhRC94MnNpRWk3WTZQK01VbUxJcFpVSFF0U2FydEFJc3VkaHF0a2J5aDlyVFdUNE4rMXlhOG8NClFoYTlPNDA5SExDZFZrMUorRGo5Uk1EaHc0bzVvVlowSHJ5SHZ3MjlsLzdDVWUzNC93UnowZnAvOTdTbHJ5YzINClY4NXd6UmlVRWpXTkRxT2xyZ3J1U2h5d2lrMWkxWURLMFpvVUR5MlY1b3RncldSTitGblYxZXpiYmtwOFY0Y1oNCmxPUGJuUlRyMFFRUWNvSHliNWxIb2xSbGhoakhOeThGd0VpNXk3cnRZdWVkMWxCQmMzdGppTnQxQVcyUXJxSDINCjNRSENhVVJRVmtuUytXM2t2VWxmRkJTa1dIVlhldUwyTXRLWjIwNCtqeWs3dDRoejV6Skk3UDBaTXNJVFBDZloNClZnbDdWVEVZeVRCVkRJMTNUNWJBeFh6eUJMYWZjN0tPcVdtbzdSbXdoaDVrc29tRUtBM3M5OENiU0FUY1JlbTcNCkgvZDBDV3BCSVdZRFFoNkdoUVV3QWZxb3FGTWIrMnBhSm95U0QzSTdvdWtRN01qZjYxTjlaVXN2Yjg1eGZEb2cNCjZFMFg3b2N5UE1zT09KdVpVVCtJTzEzV0R4SU9BSWVkSjlBWjErZHFRU0RTZFlkM1I3YmZCSmFKODMxRVNSODANClBlcjJSbGtPbTVLd0htUEJqK2lieTJxWDFORnRmVXdGYUlpWnZpbERpcGl3TzN2ZGlRTjh0cXdDUUdVWFV3Yy8NCmNnaklVZndzUUlaSUQvQzA1YUZoNFRPSHB4RUhHaDF6aWh3L2pPS21nbnRaQU01QkJ4RktSb0xSYi9pem14WGcNCjdXcG5Qd1lQcWgzTlpvZ0IvTHpUMXY0R240TGZEWEI0OS8rUHBXaXltcXlpdGVwamZDQ0xJNEllemdwejRETkkNCmZ0SXA3MWdJMEdDRUhIMlpWMmZXa1p0aU1tQ3VYNEJScTJDazRFNGQ1NUFVYW1sajBPcC9IL3p5SmVhY0laenINCmdNazRnZUtPNTExMTJ4R3c1aENXRjBWUnUwSHlvcUg0NGZvT3NCN0pEdGgyazhXb1MvejRhV1hHaTEyYVQwMzYNCmd0cHF3dzNaRFhqYjltVzVRZHNSUS8wMEh5ZTEvNGlDRUo5N3JCMksyWHJXQkRxejJBWlFEQzl1WGZkeU9GRHgNCk1HVHF3ZGNRQ044dkR0SURPWkdYb0lqMzlIS0QwS2pDd054ekZNYmRRbmdvNXk5Y0JYckJoQStBeUtPUUNOb1cNCjFIcTdPUk9vbFBmcmVxaGVJSXF2MnpaS05CemtKeXNFdUpiTWdIZ1BKS3JlQkphLzdtSzZ5T1JhUzkxT29mTTYNCnpVT2luZ2NOalIwUW1MV2R4UFg5UGNvSUhzSXBRUEE4azhLRWUvdElXaFFTY2l5MVp5eXFXckw5UHQ4TGV1cEINCitabytBU2d3b1BTdVFwSUtkQk9jbm1xWmZtL1IwVjZjYVEyZjgwYklLd2FmQSs3S2dBaVltaTBVUmlyYUlUU2sNCnpBVjZCUjQ0SWpuNmRCUjRNSkZyeFkzVldYd2FKcjA3RWZHdU9ra1k3WU1uZFFOb3ZIdGxaTld0RlBtSDZrQmgNClRIQmhOdUhSZHBMM1ozMWdZU0V2NGJLYVhqZmtYekc1Zm90VUw1d0RVVG5pdDlqdEF6Z3IvazNpMUpsR0FIbXANCjBBUVFxdUVRUWY4YUtZMGdDTHhCMTN0NmpoT1NHQXJpTUFtKzVCWWtFSVBUZGl0bks3dkNHMXk0K2hPN3NIWUwNClhLS2ttNHlvT2FydDMvVVV0alpTeHJJano5N0hkNjFWN0hlODV6YkZtZXZhblhRN0JMQlUrQWg3cHB5SzRpTVYNCjJ2V2NaR01zVTExaU8vU2ZzYnVxb3RaWVFMUXRhY3BUUDdJWXROZmxXZXZTK1BJTGIvaDEzRG1MM09XKzllYlMNCnJ3UnNQNTloTkZMZXNKS1ZoL1BXYTFPcnozcnliT2hza000VC83alQ5T0gyRHlHZ2FNbkdFTDlFSVNrWjVtOXENCk5UVkQrSG1lanRhMXlmLzNBTWhnWVMycnpHcUpyakJJZlkreGNpT0VSYVRtVjRvOHg4cmFucmkvc1VQRURkVXINCnprK2NuVHNmdnVyd2paTnlyZlJwQjVKY2c3di9UdEFrbWZ0Q1FLWldQWENRRkx3QU85SHNMTGFRNVBzVlBaNk8NCjhPS1hLcXJBUnlodUg5ME9CL2FlUkJxWmVpc2ZNcEYzQ2dQMStoVWtzbmNNR211ZmhEdFRXL3MvWnlJcEtOMUUNCjg3UmQzNEVHOCt6Y0ltN1l0bEVxSmpKS3N4b2hmbTRieDZPcUdiYVVWck9panFLMEc0M1pXZFhadEYxK200bjQNCmI5TlpXYkc4bDQ2L0lSZzBMcmxOQWFOd3lKVmNtekxoRjBET3YxSjgvbXJWczdmWEpXS2dSdzZ1NUJseG12QzcNCjB6SnNhcnd5cVFOaGNJTkYrMnN4b1ZOTWkwc3RjTjNoNmNVbGFtZlg4US9yclJ4SkxJa1UxR3pUcjFKdEVRemYNClVIeEwyK2wrY1RpWVRLT0ZVK2k1cElQTG8zSzBlSCtXZGlHNG4xanVVVU45dWZoQXp3MWoxZUR5eFo4UG1LYk0NCm1ISXBacmFvOHIxbGdobmk4ZUZUSnduaDhLMEtMUWNwMkRFWUdIYS94K3F6Wk9aV1dyZ1FUd0ZSWjR3ZHAyREgNCnNNNVhYOU1HdTV3bDFIR0YzYnpLTlFDL1NveVdGc3JwQ0VTRmRUT09NQWpCQzBCTDFBcDZwTHRrMkFzTWxuV1QNClBveG1sWi9iZWpDa0xSRENKTWdjREtYSkwxdUhmMTZjanlqVGJzdERQRE54emNWTUlTc2ZCeHVZaGNQRElDc2UNCitYSjRyeFFMOENXeW0wNUpFRzlPc3BlbmpIdXVESzA3bUxOa3lEY3YwanJ1Rmh5L1ZmdEpuR25td2hlTUdrMmINClNGQzJMTXFZRWR1WUlsYzV2U1FZYWpGWm5XanpPdHhoNkNtQ0R5S1BEaGhQM2piRkVLSml4MG04amVGbHhsbU8NCnFzWE5WQU83NUZLWnhUcXBCeFBwaU4zK0xqN0FhOWsySlBHWjBCQ1Q1VGRxeExtSVV6eUtXeUlWQjdEL2cxYy8NCmE3cUxMdFZod1FWM2wwY2tjN3R4SFZYWE1QeWh2SksvVEMzRThRbm1od2I5dDBBamRjUXBXMG1oZFFxQjZkNEkNCjZOZm9XRVRqdXl4aUN4bkpHZG5nMS9KaHhsUkFrR255T2N1V0l5Y3YxNG5mWHl5WlRSM1dHc2lDTnJ2OG1yTEINCmRZUmk5ak1CSC9TTmg3d080eHhZSkw1SXpwYTl1Q0dQQkpDRVI2TGFkVi9yalduMExPUFNxMUhUMlpxemdaR1ENCk50WkJ1UXUvQjcxNFNVM004eUwxeVNFUEFxbXdBdHZrZTZ5NG9NZEpvZ1NTVU1pWUdOajh3MVNuQzU4S2luNWoNCjNOVCsvMU81OEViWjd1L2thdWJnbWdReDZrTXM3YVJPOVJpN0xjYWxndCtBNkZrQWVDbnlpdVEyeGJlaFgyb3oNClBaLzZESWVqWDVkUTM2MnJGRDFSTWVtTGhpN2JoNW1Jb3lRZ0R6NUR6aVZqNFNGSWlvTnY1K242SW02QTNpWWINCjh4c2d4bEtCT2IyUkVkcmljNlJmVVB1SVg4dHE3eWhUR1ZIN2EvSVhMeGhhSkhVWUpRVVFWbWhRbUxWYVF2QjQNCnU4enB3Vm1kcjBZSjZCOElhZ3VEd29GN1pyNW0zZlVWWkg4L3UrcVZFK2huOFhHeldOY3h1VXdiVThhTkU0RzkNCmRBS1ovVHhDcmgrQmlic1RBN0xrVCtPRGFMM1Q0aW5KWXJGMHhjSmE4aDFTU290NDdtYzc0SXh6NmlVb1pJZVgNCkpJUmJJOXdjd29KZmxRdlNPeTU1dkhFR0JWY1lvb3dhYjhWMVdZNCtQbVFmcFpLa1NxUHVocVRvcTdQdnBTcFINClJHZUhMMXYxSDNmNXNRSWJaQ0tmN2ErQ3ZvV3djRWRzTGhLVThtVnlyRGhMYlZqNmtMeStpM3hBREJMWjB5NjgNCjlrTWRlZ2I0YnBwQU1KbkZMZ0h2b2dxTUtyWFJUelJMR0MwOWNsbEs5MGk0R3AwNWV6L2FjY2lYRDNvVmVjdm8NCjBpY1E3Znozc2pwcWhnaHhvdFM3V3FYSFlKdW9nWGRlRmpTVUZLZzJiaU1SUFpORWh0b04yeWJncFpjV0w1WWkNCmVURnpDdklQMEpBN1UzZU11QnBGYlpyNmhFenpGYnFvUGNTL2VPa3MxaDlOaU1MZ2dMY1pVV3JyYjVaU3MwNUkNCktnS0ZOTHFrUU5UZUswcjJYL1AwM3FGYjdZRDRTYi9ReEdxWmFhbjBjTmo4bUw1QmNsd0JaS00zUW91RXNiZU4NCnFVUTBtZFBmN2RxUnU3S083ckNRRllXWVU3bklET3JzcHBiSjhtNHIyc09LWFAvN1lTeG9pSzVndFg5bFREcHkNCmxVR21rUjFQM3l1U3VwcDAvSS9mUGRSUVptVlY2eWl6Rk5QbHVEa1dDODNUVGprMzlXZDQ0UVYyWkZ3QUdJMngNClJuMytUWm94dW54WVdQYU95OHdiTWlPMGk5T0lBeEFQVm5HRmpRQjRXM2VKTFZka3dqQkd1amRYL2sxTXNidEcNCmw3NWxXNUhBYm41RUd2bXlSb1M0TzNKN0xGN01GaVZ4RVdicW5iRzUzMnc4Wi9JSllKMkRjNDJxOG5SMnAyZFENCmx4UTgvSTRJMTY2VEhoK1RtVVlBKzZ3aThVZVRCdEh4NjlmWUszWHQ4eDJaSlFoK2ZqV0dHZVZOUnlMWDZqMWoNCklqTXpzRVIvTGlpaDkxQnFrZWtXQ0MxZVJtUEprQzJBWlZhV2xXYnV0WmdiWmxNPQ0KPVYzWFQNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg", + "size": 7309 + } + }, + "raw": { + "id": "1639b8ceb6c44a4c", + "threadId": "1639b8ceb6c44a4c", + "labelIds": ["IMPORTANT", "STARRED", "Label_3", "CATEGORY_PERSONAL", "Label_12"], + "snippet": "", + "sizeEstimate": 16976, + "historyId": "1405978", + "internalDate": "1527323084000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-163dee87a4bfed45.json b/test/source/mock/google/exported-messages/message-export-163dee87a4bfed45.json new file mode 100644 index 00000000000..ee4b5172cb8 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-163dee87a4bfed45.json @@ -0,0 +1,82 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "163dee87a4bfed45", + "threadId": "163dee87a4bfed45", + "labelIds": [ + "STARRED", + "Label_14", + "SENT", + "INBOX" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 5.5.9 Gmail Encryption flowcrypt.com Comment: Seamlessly send, receive and search encrypted email wcFMA0taL/zmLZUBAQ/+", + "payload": { + "partId": "", + "mimeType": "multipart/mixed", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "multipart/mixed; boundary=\"----sinikael-?=_1-15284531674610.9527266626955255\"" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Subject", + "value": "encrypted - MDC hash mismatch - modification detected - should fail" + }, + { + "name": "Date", + "value": "Fri, 8 Jun 2018 03:19:27 -0700" + }, + { + "name": "MIME-Version", + "value": "1.0" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/plain" + }, + { + "name": "Content-Transfer-Encoding", + "value": "quoted-printable" + } + ], + "body": { + "size": 1822, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgNS41LjkgR21haWwgRW5jcnlwdGlvbiBmbG93Y3J5cHQuY29tDQpDb21tZW50OiBTZWFtbGVzc2x5IHNlbmQsIHJlY2VpdmUgYW5kIHNlYXJjaCBlbmNyeXB0ZWQgZW1haWwNCg0Kd2NGTUEwdGFML3ptTFpVQkFRLytLdlNFRDJ2YjlmSk1RZDZsUlRoMGlkQzdzcmhnNEVTU2Y0Z2dDWEZFDQpkZU9xMklrVjVkTmhnV0dHYXdGVlZVVGV3TWgzTDNKa2xEb09ObGF0QnRoYzJPR051K0Z5dTVObzdoaEcNCjNKcTFHa053Q3FleDArRytHVmhsWmZOMkxPQXg4NTVIOW0vQUd4WW82S0xVK1JPbVBaVjhQWm81WUpQcg0KcjhUcmhoZkhGL1BHNFptUUljdXZQSTFlMGl2Z0Y3NHdQNGNHMHFhUEVhY3ZTeFExWnVEd3pkcUMxa0d2DQpzZU9USkVocEJHL0Q4WWZielVYVnJYNEdpT3pJdTJPaG5sS2ZVNmMwQkpDVHorcW1RUnFZT1pYTHZLZ2QNCm5VMFJ6ZkxnTXNkN1N5MWxDcGxkMXN5WTNiVDRsMEZJUldVdFZ4MU5ySjdjbHVpY0VQRGlxSnNFWm50Uw0KWXkxVmlpUlpsbmsyWHZ4MVFwc2g3ZmlmVVM4ZTlnZndQZXZZRmhaL2I2U2VxcFJGUkRGR2EwdVA5TDVDDQovQ2NXcWlVYUxVTDhuRjUxQ1l6ZklNZUlFR0JrMFRpVlVBbjE5bWtRVEZidGJJQjlLM3VRSGpGemduckwNCm5MYUowOEVtZTVOdWd0Sk1VSVc3YmdvNENBZGRSamowaXNGc29lc1V2NzUvbUVzSEo3SlJQSUNuV3g0Yg0KTFBLT3lQMGFuTjZUWURnVEM2SXF2TU9vTmkwWlBFSXBtR21mN1pPV2pSNGVVVCs5dUJtQkhFUHdHYkxRDQo4NU1jankxQzdYKzB1VWtJUHNxWGdGN1lhL3B3VHVaOG1EdEYvRlUza1I4N3kzamxEWiszbHRxK1krNUENCkJKeU1HWEdmMjQrU3F1RTFRK09OSXpCd0Jxd1h1WXZSSndxQTl2T3RaMVBCd1V3RFMxb3YvT1l0bFFFQg0KRC8wUjZMTVdGUUhaUUNJRmt2WGNCNXI0WDNKNjh0Y0xmZkFJVnMrSm5veVI2SkVDVXVDWkpkS0xjNEFhDQpGK0ExNUdLaU9uZjVaOFJJZzNGbjNuWHV5TjVybFdPdTB5T08vWHJuQ1NNSGlZRXJUTFVPNis2VjYrYnkNCmkrUE9BdEFXcHRuSjdyR1NBeTE3WmdJWUQ5V05QZFg4QnYxZldFT0pJSTJyais1Q1Z5QnNPWldybmxuUA0KSGpIT1E2Z0hvcDdiblFscnBtcEE5NVBMaHlvVzFMa0VJb0MwamdyR0YrMFFYUnFFZmR3cFFCQ2tsWnlMDQovV0FzRzJHSkxySFVnUUFMZ3BUeXM2LzVQN1ZQK1ZTT2FFbk9KSkV4SVpQa1JWUkZ6V2xZcTFhdmdKV3cNCkVGR21LZWczMzUvaVRoS0JGUThKc0g5VTIyRzVERDFCY2ZYK3F0bTRuNjQwekM1cEhScExKTzZnZ2lDSg0KWkExU0N0cTZUQlNGMUZUYTE1OFpOZ2praUdaZlMrb1p2ck1XK1MxNjkxdk1tSnJ3cWlSbFBnOVBYQ0ErDQpvdUdyVS8xRlZ5UktHeDEvVWtpL2g5U2F4RFgvM3VIT093Snp5dE54R01KUC80WTFZNmhiRHdEemNyQ00NCkZsRkhYaU5iZkIzdXhpSEQ5d1dIRTQ0ejkxTWtxT2I3L2Fqb0xYQThKOFUzS0pHRmErOEprWmxlUlZucQ0Kci9VVDhwcHYwL296V3pWNTltVHVsWXpSZElQU3k2cjRWMGJIMTZYR3dadEhWcmxqT2k0VHJrRXhCOWNTDQpUZGNYOTZSTU1ZcEo3cDdkR2N4b0hhUkJZMTIwQkQrc0o1MWpHaS9ZdXBvWkJkYmc3S2NPQUVlbEQyL0YNCkxNMUx6UjlmM0hVYVl5S3ZkUEwrQzBPd0lOS0NBWkJQU2hmRUNaT2lxck5XZ0hMV2RkQWRYcWV4WkZMSA0KMHk3dGQxMUU3VU5jQ1plZ0lsd09Za3NXN3l1dUNaMlpMTG5meC91MUcxOG5LQkNlYWxxTmthb3cvUGo3DQo0cSswVVl4ZlpuQWwvckZ1VEs5bmRkOHRXTVNtLzZ4eldFYnFlLzhOS0pyQ3drL251K3B2RitNdVJ2ZjUNCjlEdXpaRmlOUlFTalN4U1l2a3lMdXc9PQ0KPXZ4T2oNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg==" + } + } + ] + }, + "sizeEstimate": 2527, + "historyId": "1406311", + "internalDate": "1528453167000" + }, + "attachments": {}, + "raw": { + "id": "163dee87a4bfed45", + "threadId": "163dee87a4bfed45", + "labelIds": ["STARRED", "Label_14", "SENT", "INBOX"], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 5.5.9 Gmail Encryption flowcrypt.com Comment: Seamlessly send, receive and search encrypted email wcFMA0taL/zmLZUBAQ/+", + "sizeEstimate": 2527, + "historyId": "1406311", + "internalDate": "1528453167000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-163df1bf12034b9d.json b/test/source/mock/google/exported-messages/message-export-163df1bf12034b9d.json new file mode 100644 index 00000000000..9e87117adc6 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-163df1bf12034b9d.json @@ -0,0 +1,82 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "163df1bf12034b9d", + "threadId": "163df1bf12034b9d", + "labelIds": [ + "STARRED", + "Label_14", + "SENT", + "INBOX" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 5.5.9 Gmail Encryption flowcrypt.com Comment: Seamlessly send, receive and search encrypted email wcFMA0taL/zmLZUBAQ/7Bwida5vvhXv5Zi+qJbG/", + "payload": { + "partId": "", + "mimeType": "multipart/mixed", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "multipart/mixed; boundary=\"----sinikael-?=_1-15284565398080.6365395020974245\"" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Subject", + "value": "not integrity protected - should show a warning and not decrypt automatically" + }, + { + "name": "Date", + "value": "Fri, 8 Jun 2018 04:15:40 -0700" + }, + { + "name": "MIME-Version", + "value": "1.0" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/plain" + }, + { + "name": "Content-Transfer-Encoding", + "value": "quoted-printable" + } + ], + "body": { + "size": 1802, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgNS41LjkgR21haWwgRW5jcnlwdGlvbiBmbG93Y3J5cHQuY29tDQpDb21tZW50OiBTZWFtbGVzc2x5IHNlbmQsIHJlY2VpdmUgYW5kIHNlYXJjaCBlbmNyeXB0ZWQgZW1haWwNCg0Kd2NGTUEwdGFML3ptTFpVQkFRLzdCd2lkYTV2dmhYdjVaaStxSmJHL1FQc3QxMWpXZmxqRFFsdzFWTHpGDQpvdThvZm9JRUhwdm9GZ1hlZ1pVbm9RWEJtbEhHRCtYTHM5akcvVFYxbXRFMlJXcTRoRHRxaVRRNnJFSWENCmJyTjNOeDc3WXIrNEVOMWFLSTIwYVRMRVBUSWpWVTJHSDJpOURBbWpIdGVCVTNua0w5WjN5ZWNCOFBuOA0KRWRocENSWTZjajJ5cmhKNU1Qd21YcnVzOU9GdjM5d0EyRHFZcHFXNUJlK0tEOG1pcFoyQ3RKbzV4dGluDQphZUVocFdTRHNkZzI2cmp4MW56NGRBME5jRnpaSzJwL0JQZlBJRnpSdm1vWG9XRmlncFVud3J5RW9DcVgNCi90Z21jcnY3UHFpWVQ1b3ppUG1NdUJjMWxiN2ljSS9BcTY5dVh6Mno2KzRNSkhPbGNURUZ5Z1YzNkorMQ0KMW9wY2pvWCtKS0pObjFudkhvdkJ4dWVtY013cmlKZG1EajRIbWZvNHprZDZyeVV0R1ZyTVZuOERiUnA2DQpUV0IvME1TRThjbWZ1aUE1RGd6ZEdicmV2ZEw2UnhuUURtYWxUSEo1b3h1ckZRVm9Md3BtYmdkMzZDNFENCnhNZkcxeEVxRm41enZyQ1RHSGcyT2ZTMmN5bmFsOENRREcwWlFDb1d3ZGIwa1Q1RDZieDdRS2N1eXkxLw0KMVRYS25wMU5hbUQ1VWh1MStYdXhEN0VidkRZVVdZaDNia3Fnc2xzb1grT1VsK09OZHRNRDVQc3dBcmQ1DQpLaXNEOVVKdWRkSlNoTDRjbEJVUG9YZU5yUnhyVTZIcWpQNVQ0ZmFwSzY4NE1laXppY0hJUnBBd3c3ZnUNClo4WXRheVNaL2hvT0FLV3N4MHJWNGdyZ0pWN3ByeWo0QVJCUmExcExMOXJCd1V3RFMxb3YvT1l0bFFFQg0KRC80N2Z5RC82QnZlcHFXbVpYajdWTGwyeTYzZUUwYi82aGY1SytJenY1QS8rNWwvRW5qRngwcnErcWVYDQo2aGZ0WVpCVUFiYkJ2S2Z4cTlENXhzV2czdG5oRnYyc1lJRTNZcGtDU3pacFdKbWFoSHdRT1ZOVDBBU3cNCmdiTzI1T2lUUGxZUHFmU2tHWWUwcGFsYkwrNFQ1ZExPd1ZpbG1yWjJiUWYvckxlUHdBNFJRcFdEUFlpbw0KTkRVMFhmaTdUUWNIUXJaVHB3RmJWek5QWGdDSG5Ra3FGK3MwdjhSREpIbnQ5dlZzMktFcGk0OVYvWWdODQorZ1puWk9lQURMMHJicmUvUHJJY2sxWVNqWkxicld0UVZrNCtzQ2YwVGp2aXhKN01OakE0TmdkWlBvME0NCkhrZS85WEJGaWUzTmlaYVcvY0VJVlo3V25qQjNJYmhrbU9NSmQ0TGdkSEtnbXN3SndDWW0rWHZwT0kxOQ0KRnpVMXZ6Wm1mT0ExbkVKU3V1Q0ROVlVvS1lJUUE1VUVZSnJWSmVHblZONXNVNWprZGxYOXhQdFljZXd3DQpZRm1MaXN1ZjlFdjBIQzd2MjdLd1lRUkRQTllSQThHZUsvalk2YVpkZytWY2NzbnpFaWdkWUw1VG00SkkNClpyeHAvRzgwN2JadnQweVp3V2gwZ3BXT0ZnYlZncm00SHBqaTVpbER5dWxaU1crOG5KeEI1dERvUHpMNA0KajR3OW1hbGplMGM2MEdXTnRpeUNQTFVSeU42M0MycTE0NFVwUWpTVTVyNjZvUDF5RjJBOTdhWEtiZjRwDQpxTzdjU05XRU9UcHFKa0pyTkZWS1FkV3ZYWittdlcxUFFGbWtrd2lzaDJIaVFJWG1XYjA0dVYxcEk4aFINCjZZV2syb3g5YVppSjY2NE1wbmNneUo1dUlNbHpWZllyWCtBWlJ0QlczNlJnQ1Rwckl2NmwxTTVOY0hNeQ0KekVzY1RhU1kvZStwTTVIelFLU3pYK3pITGE1a2s1TDd2ZVgrMUczM3NhaXFTSi9mSzEzK2s3cUROWlFEDQpuYnRhZWJmaDJKUzBQZGJ1YjZGVUZqUEhSNVB5ZFU5bHR1cHBHRWVZck9lMVN4d2laNkJaZklYTzIvOE0NCmhBPT0NCj1CL05FDQotLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tDQo=" + } + } + ] + }, + "sizeEstimate": 2517, + "historyId": "1406330", + "internalDate": "1528456540000" + }, + "attachments": {}, + "raw": { + "id": "163df1bf12034b9d", + "threadId": "163df1bf12034b9d", + "labelIds": ["STARRED", "Label_14", "SENT", "INBOX"], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 5.5.9 Gmail Encryption flowcrypt.com Comment: Seamlessly send, receive and search encrypted email wcFMA0taL/zmLZUBAQ/7Bwida5vvhXv5Zi+qJbG/", + "sizeEstimate": 2517, + "historyId": "1406330", + "internalDate": "1528456540000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-1645e37647db32f8.json b/test/source/mock/google/exported-messages/message-export-1645e37647db32f8.json new file mode 100644 index 00000000000..e4d8a7a9b5c --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-1645e37647db32f8.json @@ -0,0 +1,67 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "1645e37647db32f8", + "threadId": "1645e37647db32f8", + "labelIds": [ + "IMPORTANT", + "STARRED", + "Label_3", + "CATEGORY_PERSONAL", + "Label_12" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 5.7.1 Gmail Encryption flowcrypt.com Comment: Seamlessly send, receive and search encrypted email wcFMA1DaD5CEIgc5ARAAoUfZ+9NZCeiIQKQK25+", + "payload": { + "partId": "", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "APt69E1dv+Y5u4dl0c4q9tp60bP9y4PewnMgBqBIRC+tItwK+KYOaunM osQgEC/azGqWDaAiF3htxCgt+sB7qyoyQS/gTz93HgNU" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Date", + "value": "Mon, 2 Jul 2018 20:37:24 -0700" + }, + { + "name": "Subject", + "value": "Encrypted Thai text" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Content-Type", + "value": "text/plain; charset=\"UTF-8\"" + } + ], + "body": { + "size": 1950, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgNS43LjEgR21haWwgRW5jcnlwdGlvbiBmbG93Y3J5cHQuY29tDQpDb21tZW50OiBTZWFtbGVzc2x5IHNlbmQsIHJlY2VpdmUgYW5kIHNlYXJjaCBlbmNyeXB0ZWQgZW1haWwNCg0Kd2NGTUExRGFENUNFSWdjNUFSQUFvVWZaKzlOWkNlaUlRS1FLMjUrZFN2eEIwODVnT1R2MFhub0FscVBFDQpqZGhLcDdYWG9qcTdjY1VTYWVFVzhEcVRlbDVQNzRGWjhHd3VoRk5qKzZHOFpFY09heG8rVktnb09rZlgNCnpoKzVCc0FCdUNEUnhvRVVpdlZWTTMrQzJTQkJHa3FnYmo0N1JKVUZPV1lrUUlsd0JoU0ErNGJWWGFJQw0KN1RFWUx4Tnk4ODQ1L3RUTERvU2pReU1BMnFYeDVLZ0ZhaUQvWk5EUWVXTTZ3Y1llSENjemJSQkxCSjl6DQpPdkh5NmhEZG8rczBQMU40anFHQ1VLcE9ScnJDeXF1cEtrVmlXSVl3aGtyTkU3NEJHelNHdFdwNFBENGQNCnUwYlNnQ2NLTkpJNEQ1NnZPbDdWUHBObHF1bU5hTTFERmdXQ1JkR2NRZGZlSHl3MTBQdUxyV0I4UW1TSQ0KdHpodjdTTHhHUUJjMG8wdHZlVEtmdWdWWmxEcTNGaTNlbzZHRHpLSFcrMk5rT2pNb1I3bU5Ddkk4WnJnDQpjWlZGd21TRUNsTlRuQlY1UXdEU2V2RWtPWWRoYzZURWk4cDNHbmd2K09NTFptUE8xVFNBUTE1S2d6ZUgNCks2QnpUZmYvZVRKZ2dYdlI0Z2JZT3Z5U0lyb3cyZVVROEYrTEpWMmpLZm1PSklKQk9VS0VoK1JRQ3VJVw0KYzFUVXhyQU5ETTZRMFpNUHJROXV2S1VRdURqT1JtaXpCcVhvMVl2akRFYkdIaDIrZHdhVFNOcjYwMy9mDQo0UkRPZ2FTTWhNV052VHgyTVhrKzVWOHVxb0FxWlFaM3RTTGtQR3RHVHVtbENuTGl2Ui9jS1RlTDB3SWINCnVlRVZURFcvZjduUWZodVBYTCtmVkw0aTJISXRRZ2w2OFlRUWcxUHh1Q0hCd1V3RFMxb3YvT1l0bFFFQg0KRC85NjV3K1RZNmhxRXR6Z1FhSHIwUzJBeU5kZ0xVMkhrS0kyNi8waVo2bTVWOVM2S2QzOXI1SG1WT2NZDQp1TkxEbE53bFhqSzNvaGJtRWczVm1MaXJMdDR0aXE4bWVONndwQ0tMdjI5R0wxcWtOWHNyZkEwMWRkOE0NCml6WUZYbWYwYzdkN0hrVjlKUW1VcjB4YmwzSXkxbU5sM3FjWG9vUjJPb2NpV3lrSzBaNEVTTEtOVjJEbw0KVUFQNno3WDdqVkhMc3RyaTVCT3FNS1RSaWh2RkIyck1HZEpUSXpINlh1TWxTbkpYU2E4TEJIRTNGWlpyDQovU3F4U1Y0cHNlZzJWWG91c2NkRGtNcTk1OFpBYUx0ZXB0clFUN3JxTzJxY0pvRTNYb29uNVJKYUZ2L2wNCk0vVlN6ZmdmY1hDZkpGMzRITXJaR2pySGRkZUFHRys3azlFL2lFR2NaK2t4eDRUb3J1emR4R2RlbkFOdg0KUThXNWwzQWtUMXFsdlY1R1NCMHV3cEptMUZhdm9BdGl3UWZMWDBmK0RDMWpJL3dMNjU4K256TnA3MEJZDQpsTDdNWE45UGdMTFkyMndTSVlYRzdaSGxiV0FiczhXRDY3Z0J3N1c5NDNydzAvbUN6dWhRR0g2c0pTTGMNCkVNaG9DQS9lUGszb0wyTHFVOUYxSW0wNHR6KzBGQlArdFBaRGV5K285NlRsLzBXOHdCVXhMQ3EwU0Fkdg0KUm9HK3RtL3FmRnBKbkN2S01PbFcyVU1UMmRZeEZHQXNUZGdIVTJ4V0JQN3YvbnNVc1JCTStGMm1HY3hoDQoxT09WenhzMDFTdllxemE3alBoZlczTllCVzVRaHRuSXg2dzRiNmg4YUZyd093Z0gwQitodUd2RHJwcFINCkw1VGd0SzMvSnFvbU90Yms1bjdUMllJRDhkTEFJQUZ6dUJtZEZ3TXR5elUzTkZ1Y2M0ZWtmK1pZTGlSMw0KMGVkbXNQaHpBRmhIeGJhYVVpbUNmZTBpcFhpdVdNeU9UZ0dyL2VRSEtUNVRheDlRYkdxNmo1WFZ6QXIzDQpzQUorWWhvMlh2QS8rajBYZFZIRHczbTY4SEpjSnpjSmZFU0lIb2Q4YXNpa0pTcHI2bC8yYTdlN1A3eWsNCm81c1E3b3doaS83RFhUUGRTeWpCN3JJTzM4OVdyUnkzQUhCeTJUNzBxRWNYTC9aY1JYMUhnMDBkcU5aMQ0KejZyOE4xZENwNkVuNzFtaWU5anhOMzdpZWpHSmdEN3lneXIrUm00UThyMGRzTDgrOHdmRGNieFdwSlp1DQoyWm12N2E0TWRQWUo2YkZpVkpZcEZhdTI2elAzDQo9YWFxRQ0KLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQ0K" + } + }, + "sizeEstimate": 6480, + "historyId": "1406184", + "internalDate": "1530589044000" + }, + "attachments": {}, + "raw": { + "id": "1645e37647db32f8", + "threadId": "1645e37647db32f8", + "labelIds": ["IMPORTANT", "STARRED", "Label_3", "CATEGORY_PERSONAL", "Label_12"], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 5.7.1 Gmail Encryption flowcrypt.com Comment: Seamlessly send, receive and search encrypted email wcFMA1DaD5CEIgc5ARAAoUfZ+9NZCeiIQKQK25+", + "sizeEstimate": 6480, + "historyId": "1406184", + "internalDate": "1530589044000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-1663ac8b70e22517.json b/test/source/mock/google/exported-messages/message-export-1663ac8b70e22517.json new file mode 100644 index 00000000000..4cfc83fa1b0 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-1663ac8b70e22517.json @@ -0,0 +1,86 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "1663ac8b70e22517", + "threadId": "1663ac8b70e22517", + "labelIds": [ + "STARRED", + "Label_3", + "SENT", + "INBOX" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 6.0.2 Gmail Encryption Comment: Seamlessly send and receive encrypted email wcFMA0taL/zmLZUBAQ/+MC4kEIaAIdbuApd3CIf72DSEy9+A9+KlcXbhbFiP", + "payload": { + "partId": "", + "mimeType": "multipart/mixed", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "multipart/mixed; boundary=\"----sinikael-?=_1-15385845241750.7333033959651614\"" + }, + { + "name": "Openpgp", + "value": "id=E8F0517BA6D7DAB6081C96E4ADAC279C95093207" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Subject", + "value": "wrongly removed < and > contents as if it was a tag" + }, + { + "name": "Date", + "value": "Wed, 3 Oct 2018 09:35:24 -0700" + }, + { + "name": "MIME-Version", + "value": "1.0" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/plain" + }, + { + "name": "Content-Transfer-Encoding", + "value": "quoted-printable" + } + ], + "body": { + "size": 1738, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgNi4wLjIgR21haWwgRW5jcnlwdGlvbg0KQ29tbWVudDogU2VhbWxlc3NseSBzZW5kIGFuZCByZWNlaXZlIGVuY3J5cHRlZCBlbWFpbA0KDQp3Y0ZNQTB0YUwvem1MWlVCQVEvK01DNGtFSWFBSWRidUFwZDNDSWY3MkRTRXk5K0E5K0tsY1hiaGJGaVANCmg2YlQweDdQU3pLTUFyYUFnSVJhVW11WDNXb2p5WW1lQTNzWk90Rnc1STFUWG8yd1gwV1VZbFdHdFhBOA0Kc2dzUXZmM3ZveTQ2REVoRllLanBrMzhPcUs3N0dXblUxdDRRck5VcWpRSjZwQmpzbG85OXl4OVJ2WXB2DQp0MVgrTjBPTGNJZXZUaDBSN3RqaWRQc2pReDhQUmVqaHVJQWdNNm1JMzluNVlVQi9WQ01xRFJycVF6cmoNCmNENy8vNFgwZUpoVFlqREd6clNkTHRLL24yekRjYTJYZUhlM2plNE90TEdxWVAxOW40WWdtamNFVnZpdA0KUXNEb3JUZFh3b0RLcDNnWjI3Vm1qa0w0dWErQTRqK2VONzhIWEFiS0NmM0hrMHh4T2xPYURtQWRLdlphDQpYVmIxS1pOTGFBZUU2MkdpRW9tYnZGaHlpaHZLQmZYeG1CQ3ZYQno1eDZnODNyNWlkTGQ3VTZOZGFmeXgNCm5aTVB2eHM3dXV0eGVKM0hHMm9NdldQT2hyMDBGeWlKdk1HOG1mSEpoNkNvaDRSa0svZThveGVaaW9TOQ0KTDBaWU5wbXVrZmZjeFR5RCt3bTEzZCtmZXUvNURGQThTYkJmbmhFT1c4MGR6cEE3Q09xeDQySGtPbFJ0DQpiQVBuOUFvK3Y5aHpoRG1PckhUWWlHQkdCelJPNTNiNVd5cDU1cHlZQ1k2cjRMeVIyK3M2K1JyQ1ZCbzANCkQ3eWplejlBcVB3NjVzWWkxcWVUNFVIdEJ6VGJpLzdsbDNFanRwaHpMeFR2MUR5eXRNanFEVUhjZzdRaQ0KdnJxTFkybWZGbSt1ZHFiZFI5OVdYMld6SmlqSlJCd3Q1aEV4Sk1NQTgrYkJ3VXdEdmIxMllQYVpqY1FCDQpFQUNkVzcrSUszUmd0TGpKbW8zVjk2NEpSOENRa1hxNTBYemdpQStjSk9YVE45SnNjNzJXM1ZzMXhaRTINCnA1RCtJM2I5cVFPTWd6V05wWUY2TjVOaXlXRkR0S2hHeWVYTDJ6b0c4eDRDT3laYjI1YWwrK1BNdFRrVA0KS29vVlNicFlhUmlmNlEzdldWWjlDMjlhZURxeGEvTXd4b0k4OXErQjBtTzFvQXdlTmdrNytabWpPZVlHDQpmd3hrWW0rT0dldmFiRFdacnhLTHIzTGhoV0lGZWV3UHhmenlpM1RxQVpqRW5Fd2tEMEZZc3NSK0x0U1gNCklzYlhUZGtWNmozL2N1REhMZEo0eDluRXIwbWVmcFNOZnpJd3E0aURZZFdSN2h1R2pFL1Rrdy9TRjd0Ng0KTHQ3T3dzTytEVnI0MGZZT2kwdm5GNWg2R014Q2dzSHBNeTdMQzlpQ3BkMGpMOXdXdlI2SXVrSE9WRXdqDQpXUG1aMzRNNjI3SUMvT2dpdUZsbFZtWGRKL2J0QlZFbkxPeXI2aHZzTUt0S3FEMGNTODNGb2FZMmgrbjUNCi9HOVd6U1dqQUJJWmdzUWlqb0FJSmMxQzkrd3dOM3VVRm9jcmdkRjU0WjlwYndaSFVybkJ2Q1lyTC9UUQ0KQU43aUJ2UU5ra29GQVdlUzFKTW1HS3ltUjN0cWlCOHBTUVU5U1A4cllKaE9NY2owb2V6dVp4RVpHOGdlDQoveVVpamFGOFgvN05nZnFMb0J5bTJtZm9MeGsycEVHRnVoazJCYnR4aTJMZVJsNW56cEN2TzZvRVlkWWkNCkkxRVJ5T0EzOUJlemFOMWt3K1FybXBxRVRLbStJbnByQ3hHQTF2VU9WbU9ITy8wWUhaQmFZT0l2azJYag0KamtxNmtWRm1ReGpGRTlMMUlmeGJhR2tRNzlKVkFVVjl3NjZ3Y1N6MHlVTHIyL1U2a25RUEJuRU5vYmw0DQo2ZndpQmtpU0dBdktkOSt1dTZ3SmFaNXRZUFdVUDBIQXVLY2Nhd3l0Tm1HUkVXQXNmZnorbnJNc0VEVUcNCkppMDlKaUxUUVU0QUNDYWNNM2hQVnc9PQ0KPWUrOHoNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg==" + } + } + ] + }, + "sizeEstimate": 2479, + "historyId": "1406092", + "internalDate": "1538584524000" + }, + "attachments": {}, + "raw": { + "id": "1663ac8b70e22517", + "threadId": "1663ac8b70e22517", + "labelIds": ["STARRED", "Label_3", "SENT", "INBOX"], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 6.0.2 Gmail Encryption Comment: Seamlessly send and receive encrypted email wcFMA0taL/zmLZUBAQ/+MC4kEIaAIdbuApd3CIf72DSEy9+A9+KlcXbhbFiP", + "sizeEstimate": 2479, + "historyId": "1406092", + "internalDate": "1538584524000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-16a9c0fe4e034bc2.json b/test/source/mock/google/exported-messages/message-export-16a9c0fe4e034bc2.json index 7cc3cb6a45b..7df13b9923a 100644 --- a/test/source/mock/google/exported-messages/message-export-16a9c0fe4e034bc2.json +++ b/test/source/mock/google/exported-messages/message-export-16a9c0fe4e034bc2.json @@ -68,11 +68,11 @@ }, { "name": "From", - "value": "FlowCrypt Compatibility " + "value": "some.alias@protonmail.com" }, { "name": "Reply-To", - "value": "FlowCrypt Compatibility " + "value": "some.alias@protonmail.com" }, { "name": "Subject", diff --git a/test/source/mock/google/exported-messages/message-export-16a9c109bc51687d.json b/test/source/mock/google/exported-messages/message-export-16a9c109bc51687d.json index 3694e3f7d74..b349ee532e0 100644 --- a/test/source/mock/google/exported-messages/message-export-16a9c109bc51687d.json +++ b/test/source/mock/google/exported-messages/message-export-16a9c109bc51687d.json @@ -68,11 +68,11 @@ }, { "name": "From", - "value": "FlowCrypt Compatibility " + "value": "some.alias@protonmail.com" }, { "name": "Reply-To", - "value": "FlowCrypt Compatibility " + "value": "some.alias@protonmail.com" }, { "name": "Subject", diff --git a/test/source/mock/google/exported-messages/message-export-16b7fce1c1589c0a.json b/test/source/mock/google/exported-messages/message-export-16b7fce1c1589c0a.json new file mode 100644 index 00000000000..533d0b02096 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-16b7fce1c1589c0a.json @@ -0,0 +1,70 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "16b7fce1c1589c0a", + "threadId": "16b7fce1c1589c0a", + "labelIds": [ + "IMPORTANT", + "STARRED", + "Label_3", + "CATEGORY_PERSONAL" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 6.8.5 Gmail Encryption Comment: Seamlessly send and receive encrypted email wcFMAzBfgamu0SA1ARAAuHXRxM9k+XfQ8iPNconAE62s5pP1PdO5iS01/OB+ 3+", + "payload": { + "partId": "", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "APjAAAV2VQGZ/GnkRwlfU7wqlXjnSbYRV3j+fOC3xwgvpC4eW0yB8WZ3 x5OqG2MC0UiCvhP+pzK1NdTWiEvnuAamIw==" + }, + { + "name": "Openpgp", + "value": "id=6BF16EE1ECE7A66C4B6636DF0C9C2E6A4D273C6F" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Date", + "value": "Sat, 22 Jun 2019 11:28:58 -0400" + }, + { + "name": "Subject", + "value": "quoted content should not crash the extension" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Content-Type", + "value": "text/plain; charset=\"UTF-8\"" + } + ], + "body": { + "size": 6160, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgNi44LjUgR21haWwgRW5jcnlwdGlvbg0KQ29tbWVudDogU2VhbWxlc3NseSBzZW5kIGFuZCByZWNlaXZlIGVuY3J5cHRlZCBlbWFpbA0KDQp3Y0ZNQXpCZmdhbXUwU0ExQVJBQXVIWFJ4TTlrK1hmUThpUE5jb25BRTYyczVwUDFQZE81aVMwMS9PQisNCjMrNnhVWDVvV2VtaXdYam1LZXR6TXZZdlNBNGx0UTdmV3h3WS9Sem5mVXF4aVdRQU1RZmxXSU5NbG1ycQ0KcHYxaXpudVZya2RYaXloU0x2SHVoTjNGNlpyV0ZCbjNVTDV4REhQSFlhRnNnMmF6dnFnRjZRWEs5aTM3DQp3WWJaWnpKOU9VNXlxQWR6ZFRBazJJbDVWL0c3ZGgwU3U5cXJZN05BYTQ2RElxYmdkbGJMWXk2cUxjdngNCmlJMXlhbGlVZy9tQ2JpVmorNmtnYi9Gczg3cGVhSGcwei9wY25nT0IwYTd4MW9mYklXL3JjVGJoc0VqSA0KZzZJKzdYU1QzUm1LY092MFBnQ3RFRFU2SG5SSU5iYktyd3I5TS83eGpqQktOOGl5RHMwWi9kT1hES0tDDQpGdVVtRDEwdXQ4LzNkNGpKZlRJYjVGRWlQVU5zQ2hNN2xpZEhhZEtqTW9FZzU1aVFnVVRwMkZlV1h5SWwNCkYwVWxtV1JaemlsalVVUmREVTAyejBGK05nOXdKa0NOcmRhQ0haZVVMV2ZVNCt6aHZvYmIvYVRRZlM5Qw0KSURDOVFvMWpQdzFVMW5vakZNUWRCTVFROFA5eHNEOHZIa2VHMGYzRk96dmo4eFdtMm9KRXZCRHBzUDZaDQozdEdmNXZWMHVSRld1VEUyeFdiVjNjTWR2c0wyclZKYW5tR25zZGRKUDRwMldTNWF0N1VEZG03RHh5S1INCnpVSm51dklUbHlkZDc4cFNYbXFVcnc5Vyt5MG9PZElmd1d6MUEyVjlwZGFZd0JvbFBHdDdVS1VlU0s2QQ0KTVlFTHY2QWM2WXQ5VEJKMkI3cEx1L3cwV3R2anc4SUdHQS9ZeEtYMnQ0ckJ3VXdEdmIxMllQYVpqY1FCDQpFQURSclNKaVh6RFhWZE0rR2JIQlcvcmRLY0RvSHE2bjNmMG1VU2J3dW1pejUxcFFydEttTmdXRlFadU0NCnJrVjJPNzZmb0VEcFVuOG0zR3djb28wTXZDeEpLV1FOM1U3ZHpyTXpLZDc5ZWdEUXI4bUNRSVVxUERiSg0KNGd4VkN5OXBNQUk1MW9JRk00Yk9ENTFNZE9nclUxdUlUWkR0YWFwc3dpSU15d21qeFlHUkdMRHNRK2dCDQpWYUdGODZRZ0hTZ0gyTTdLZFd0TjlNU3FEczI4ejdOOWtkcjBiVldBbVZhdVNjaHFCZUdFWkFPcTkwZCsNCnBYRVQvYkVtMFkwbCtxcE9GRWZrYldHb0Fzak9kT2EwclNtQmNmWm9TaC90WVdEcFB3SkRUK0lwNFhMcA0KQzNDL0ZTUTExZ1B0MCtBYjgvWW91R1ltSUNUek1WVWtpSHhIR3MyNG42VHd3MjZxQndRRkR6WFVBd3hMDQo3TEVOc2dzZWJMRE9XOFJqQ24zRVV1SDB2WklEN1QxM1hhOVIxWVFRSG1JZWJWTjQvZ3J6L3FHRFlhWjANCjRVYitwTVdwTllJaERXaVFSa2ozdTM5bTRoQ1dhMkxvOWQyYXZnVXFtZGdoQ0RLWmtmTXROUkFNeUx0NQ0KTFNEbmgxNnlybDFwNFA0ZTdJTURGcDZZdCtlU0NqSDU1SGFER2VxNVovM1BobGJEK1ZGWTE3djcyY0JODQp1eXFzZWNKcFRhY0VTeFgwUTRQc2dhaHI3aHRHNzFLdklqYVJCZU4wNUk4MElYanJNY1RZNmM4cjBxaHoNCjcyclcycmZOUnV3aklHdEpPVWZGSzZ2QW92Ui82a01KTVRNNGVsSjRRL0VaSU43emQwT1k1ei96WitrUA0Kb3lDOGh3Rkhnd2hoeDEvdStqOElyYTdEWHRMTUlBRlQyUHJpRFRpNGFHVWpmb3JUVktDaDlEaWZVOEJwDQpVdnBFVUpsNzFFZEZaNWljKys2cGtHS2h5QUZiTnZKUzNkdlpXRTUwL0NmK204aVV2WkNzNjNhaWtUT04NCmRqQk9wUWdFMzJpZzM5b005Z2dIaXQweklaUHRabDZYVEpIeXR4Tm95ZG5UMWJwMnFKTmo4MVp5VGxRQg0KTlR1c2JNY1kzdXNETXpJYmdGZGlORkxyUlRhWjZLUHVYSXpsalA3WHcyTG0rVGNWRkdSVW1Ea2FkRkY5DQpZNFJDN3EzaXNKejloOGk1UTZzYmFXSnU2WWxjMzA1RkRLSDlYZW5zeVIwbFhHRVg3aXNoZTVNZzhNQnANCk9lU3l3MjBHRWVqcnhVSE9wNWRhVUExWEtGWDYrdlpiZWtxWjU3WitKRnJCK1UzY1dOMmI3QURIa3hvbA0KaGZuQ3ltdXBxTG1vT2orVThzeDJvbVdFNUtCZWhSaVNwV0lGMDFNeDNqMEtLd1ZwSm84d2lzQjlXWGc0DQpHM1YyTGR1RStCVFp2ZXMvMEEwRlRVZzBtNVpXZXFVbTFNQU9Va1FPZGYzK0M4c0tWRVVVVWVXNi9jaEwNCnlRWGhLQ2ZncERIRm1ZS2lUVXI3eWJQbVFaLzJobGw0OWEweGtuZEdQaTkya21uZTVkejNYN3RIdFBIMg0KY2dSQWx1QXQyR1U3blBZeHUzanFXVVJmZUladkdSTFBkNFR5M0NmUURBeW1FUXIrbU12a2dGZGZuMnBqDQpsaERHbnRKZ1VtTnpnd21wRDYweTRlRVpoWUNuREZRVWRFQUNIYjhPVEZaN3NaaEtPNDFwby9DVjdTaXANCnB2OXJ5bi81UUpKa29EUEQxWXk1Nk5xem9hQVp4U2ZtNVVoMG1yMXdxQ2prNHlCSHJ2dThuYVlwblFNdw0KZiswTk0wQmZmbnRQeDZqVXI1OHVVaDRHRjlid1RoTFl0Rlk4U1JWTVJiejJSMlZmZ241bnhuRDNFd3JWDQpHWm80WW56WFhrcnlyRDJWMnV3VGM4aU9oSWM0N2g4TGNON1JpejRtdmc2d2xjMkIwNHNrWktrblJnQk4NCnd0UFhCMGNqS3k1dmk1L21CVG55SEduQ1Z4aEdBdGFDc0dGQkxObUlBb1Z1dThUZTBvMHdoRHlBK05seQ0KOWFCSnVuQmprZkxXb2wxWGM0d08xUEtPRTF4UUFTOUV6RTNCLy9HdWp5em9MNjMxMUhnQUJDak1RZUNMDQozTnY3WVFTZ3A1bWVvQlhYMytDcUtpUERFYUtZKytmdHI4WW9tY0lZUUp5RFV1UmhYb0h5bnY3TGNlcEkNCi9RVWRZS3hlbTdYRUNnOXJWc2preitQMHh0UHRUQ1cxLzl3V0ZCa1pKUCtsNlY1elYyOVE0Uk9BSUtoTg0KdU5tY2VrSTdnVVlLaHBNcDJBR3Q2TWFsc3dVb3FoVjBhTUlwUlBkVnpOMnhyeWdHdHYzTEVmT1hWL2xSDQpCZFczSjVJL2gwQWNiUjFjdGVNVlpmRlgwREluRHRKK2VPVWoyMzZIRld1SjcrYzUrYWorZk4rSUF1YlENCkVpbkdOMW43S1BSdGQ3czFXL1QvdDdtM0VDVEN0MmJqT0d1NEU3a2NldE51Uk9WMGNScElTQzQwS3lsQw0KV0RoQ1kwVDBqUmhleVAwbjBRQTQ2VUhDTXZXc0ZQYzh3aDAzTUk5ZHZEdUJmNG9sekZYM1VmQ2QvSkMwDQpwOUtsenhSRzZDTWxKWmFEeWtQM3JiQ01hdFVzaW9NY0N1Ym1hNjNaR1VKMC9zOHphT2hoNXdNOGZMTGcNClZKSjB6MGN4WkpPT2FOeXVsSXJDY01vblE0MklBaXFOcjNsUU85ZFE0VGVSMnFDcmFpOTBVSytEYnlILw0KcHR1eEczWjFEN1JXbjNLVE1vTDRseWJiY0Q4MkhzUXZ6YXlOS3FGS3MzZVBScEoyYkh5cmIxZWhoZnVSDQpEMXRCdUxZM3FqazlBaC9iUHZjay93V3B6dWkvK3dhbmZMUkhrbDBuN1R0WklxQTZVODdPU1FDSUdRcE4NCk9aZmhOU3p5RllId2ZkSFRYb24ybHl5Qlh3UkFtNFdWdmI0aFlVLzNadFZoZVVldnFqRFcwZ2F1NEtTbw0KYStuYlhZWXppT3JXWjFIdFlKWXV1RFM0M0kyZi9mbU5wdjhQQzAxT080YjJGT3Q5UU51SG5GelRQbkk4DQpnRnk0ZFhqNVc5V1Uvd1M2ZUxUQlpxZnRTYTV6TThseEVNMVpMUUhPdGdIM0ZVd3ZOSk9kZHVqSHRKNVYNCjVyc1h4Rk5OWVY5V0tQeFZhMWZCOXRXdm10WEhWTHIzOWRqc0w5MnJRVEdUZ25pVmlITkpSQUdrMmVDQw0KTW9oZU1xVm5CSHd2KzFmSXk0WW9lV1ptbWJXbnBJcS9sN1ppMGFLbWhzZ3U1RWVKNjZSN2czekwyc3JDDQpJdTlPVnlWQ2lDemIxaittNHdTVGlMekxsYzhpUFJFZHNUdCtGMWNwYkIxYjlldUVEQTFsNE9JSUVjTGENCjBveFpJQ3B2QmNyclprVnhheVBqc1B6ejF5LzMrbSsyeWxFWmJldzMwa2FIRnhldDBhYmQzTldSWXp4Tw0KRFJTTmwrWkdHNlRoQXFLY214UHJITnYyZ1VJcXQrdm84TzhmNlJFYVBNcVJwWlJkQ2VzQmMxWEQ1Rk1pDQpKUkV6b09DTHJGZE1PL2Y2U09lNnc3US90elFxVlIvN1lRSko0YWFmcUNnY2xja0Y3RFcvL0pLa0FvMngNCm5WNjMvbkhydjd6Q2V1cmRGTHM3aVl1N1pyamQ5L1pFWjBEV3pJN01LQ2Y3cnVsd0xyOVoxTTRzK3pKeQ0KTmVWMlF4NUhJWjdEQnhReGo3UEU1QVZLZ1FudFZ5UzRmWUlmYzRnaVVEdkZiMysrYVRKKy9QeEVXOG8wDQpXN2tkL2I5WS9Vb0l3bzFnVEExdkw4T1F0QW1ONS9pek8yM0FQajIrazFZeGE2c2VhVmJHVWZndGVoZGUNClBrbzl0Z2NSQlByK25RTUZ1aVd4emdVYjVIRkgvaWliZzFzWFozMnJlK3JLSmtENmVVUUJaRjVnRmRDUw0KTzRVYk85R0NFdk9DTm9BRmxhdGtZRU9oQTRpMjVjUlc5Rm1CZm1KeUNaL290NHZxUjViSFl2a2RkWkxwDQp2VUNZeDlYUW42K1RzWndhUkI2TURQRkFCcUFxRnJzSm5qek9mak8vd2NobjEwdm85emYzeDNkUWNLYzENCkd3SkVDYjR2L2F3QWF5TnpxUWdtQWptVDhKcWtjSERHcmJVdmpWSll2ZlZBNTdWM0w3T2hkNWljZWljTw0KUGI0VkVQaDJYNi8yeFFLc1hncERxRjRhQytUOW1KOTZvbHFUbkZzcUt3aWIrbTUrZEphOVBDQUtFS3hCDQp1UHpVOGo3bGxYQkNoSnQ3cXd6UE5TaFZWNWtZVFdwbnJVSkx5dmpDUDlxQlorSC85VUFDSFF2c3JQNloNCkpFUnZqcTVzVXVMcFNPdnFkVWNUQUNIeUVaV0haalhBckdMbXBDZFRzeWVIdjJVRjYvRzJSVlhyd0RWaw0KbDh4TDRwQlFrZ0cxSFNBK0NoMmREVGFGeU5aY1p1RjZFdHdqZkdPeUowYTJkWDdzT1RTWFZnZ0lwWHdmDQpIeExCN0taZzhHT1RyN0xSZ2pNbDNoMmJDT1FKOEs0Zk9DWUx3OHlBSytNdzhkUUh3dnRZVUtjQjhqQ2wNCjJlZzNOQWdEZnFxdUtTMFYwNnVzUG1TYlhqZ1l5WFR3WUZNOE5rT2dsQWlkbk1LRSttekpSUHNtSW54cw0KQjkwU0wydnU3K1I1K1g4dGJMZkNmMkFNRGQ5NmNnQ0RCM1RDeGdhVWJvM1NVK202ZDk3QUxwaUYvWTZJDQpBVWtsKzVmY1VkazhwUFhrV3pzL0d5eS96cFNtU0YzSS82TzAvUzVSa0NHVlo3MElnNStmZVU4OVJaQ1cNCmQranowcjhwbE1VbjdsREJtb3VVa0hHSWttWFlITSt6ZjZxOUMxN1ZXQndKQ3gvWGRkR21ZVHNQSG1uTA0KOXVIT0lWTnBEbHVmNmNVdnAvSmxaN3QyOGY0ZkNxTUZMRjFFYmk4N3pWSkJYbXl2Z3VlNFdFY0hWbkFEDQo4Wk5UcFZ2YzAzWkdiYTlVY2hHZFd0NVkza2F1bGRTRlBOLzR6aUNQT2VDK0w1ME04NGlyWFVldk81RXMNCndBRkp0bStSSTZGeWNCejdDTGxaS2p4ejhJOTcrWHhzakE3Wnl1dlVOUmhPUnd2OUhaeDJCSjBPRk0wMQ0Kei82MEtlcStRVFhQenB6TDB4QUpOZHJyWWkzQ3RXZjdnQzVoVFVsTzhvY254NHFud0dPUHlvK1JtTUdrDQpxS1hMQ2VlYjZPa1MrL1Bmb0dYbSs5bUJwUGlza2RNaGhERDZnRWZQNlo2b1gvaGYvbmxJOUpFTUtFQ04NClFwUHpPY0ZxRFB5Qmp5QmhUbzNWU1FDbHFCVjJLMWRRTkw1R0xnWGE4dGtIYVhsUHRWSlI0UzBXSENWaA0KYTN2Y1Qvb3NzSmlqTUlSMDFIck0xamhiaittRm82d2MwbzJYVEcwMDNJWmloOVQ2Wlp2Q25HVjZ2MzEvDQpKWjJMT1dmQlJlU3RjU3JGWjVaaW5TN2ZXY0cvNUpidW9rS1pWVXhXcUpxM2pvbEQ2bktwZkVjQlBhZ2ENCi9jNlN1amxYS1EyR3I1OGNtZENyTjdKVHR5NUY3bEZ0WmxaUmNHN1FIdHIwMVJYcnJxQ0dVKysyOS9CNw0KY1M0anBQdlg4b2YzendhUGlCc2k2OFlma2ZBbHloUWhiV0lZWW1XRmp0eUMyYWR1aUdHY1B1ZG5SelZrDQpZRzNsaTEzMHlSdkQreGVTNGY0b2ZpY1hVZEI3U3Zsb1JiWXZOdVQrdGFDUEoxNW5jU1VYd0xMT0ZXazINCjdQWTVyNWg2UHdQVnhoeEV0bVVnY2loYkJQNTlXV1ZpTCtpanhQQ0JvUHhEa25SRWplSk9nS3hvc3d5Sw0KTHVPajVSMkQ2U1UwWnMvdjRrV3dYQ3ozd1RUZFUrcGgwMTlaNlN2TG5tNFhGYkpUeDFNSTkwWFl6eWREDQoySEZZZ011QUVhZTcySG12OHFETzhTT2F0KzNFa053OWU0REFUL1JHT213dVBSOTVnTXVjcUpMY1AvdTINCkp4TE5RTFNVbmxmQUJTR2lBQTY4R3ltNnlrREtZTXJ0NHYySk9GTkU3ajQ1N0lxMFU2ZktLUnhWR05kYw0KbkY0S21JeUEwOFFJYzFZS29SNzk0Ky9nTlltYjc4UENzQlFiWE9tZ2xkT0FLUVFsOCs1Q3o2WTJNdTFVDQpkdVhXVW1jQWkvSUViMXc4MTVqVHplZHRvSVEyR2RXNWdHSWNXU0xpTHp0Vi96MzVnRFB4WGIwSFVHdU8NCko2VEhBUjRtYzg3ZXVXemNCaFVCeGRmTmFFaVRkVWdjZng1TS9oOVlGdWhTNVZKaksxcmpYOUkyandQLw0KZ1VCbFdWd21HM21FMHRob1Z4cFNGSElDSTd1dzAwUGpUTlJBM3FpWGUxc0VCNkQ5L1dSdXFVdktma2FrDQo2dWt6SkJISkEyYnVLeVpxT0dFMVI5WkpuaVJJbXBKTjlzUFZGMmpvU3ZIUEIzY1NiMUpXRU5lRjJUNUgNCmdYTWhGWTJqYmdwY1h1Y01IYXBxRExKM1dNWENDUjZSMHBDR3hXblljWTBPOGtsdjJyL1RQZmRwdFZKTw0KYUVpYjhYUkFneFI3RmZjdFJLbWZyZjBkLzlVUVFSWXNCbk43Zm4zYmFIRkcxVVVWVUVZSFRyK2lYcE1NDQpDRm9udEJWNHBLK0dsMWJZQXZZV0xWWGVMMDFkcnBWVGdVMjRGWnA0eVRQQw0KPXFMWGENCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg==" + } + }, + "sizeEstimate": 11577, + "historyId": "1405919", + "internalDate": "1561217338000" + }, + "attachments": {}, + "raw": { + "id": "16b7fce1c1589c0a", + "threadId": "16b7fce1c1589c0a", + "labelIds": ["IMPORTANT", "STARRED", "Label_3", "CATEGORY_PERSONAL"], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt 6.8.5 Gmail Encryption Comment: Seamlessly send and receive encrypted email wcFMAzBfgamu0SA1ARAAuHXRxM9k+XfQ8iPNconAE62s5pP1PdO5iS01/OB+ 3+", + "sizeEstimate": 11577, + "historyId": "1405919", + "internalDate": "1561217338000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-16d558cb71e8d510.json b/test/source/mock/google/exported-messages/message-export-16d558cb71e8d510.json new file mode 100644 index 00000000000..186484ea06a --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-16d558cb71e8d510.json @@ -0,0 +1,118 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "16d558cb71e8d510", + "threadId": "16d558cb71e8d510", + "labelIds": [ + "IMPORTANT", + "STARRED", + "Label_3", + "CATEGORY_PERSONAL" + ], + "snippet": "", + "payload": { + "partId": "", + "mimeType": "multipart/encrypted", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "APjAAAUb15chLaGd9+iPy/5kyuzk0uvDvHUSiCnfo//1m9xKY+PIuvRU AGrPyRjvHl46DBkwQtZn5vssrzCELOc=" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "Date", + "value": "Sat, 21 Sep 2019 13:39:02 -0700" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Subject", + "value": "encrypted message sample from EverDesk" + }, + { + "name": "References", + "value": "EDSK201909161405190000048B" + }, + { + "name": "X-Mailer", + "value": "EverDesk 5.8.6" + }, + { + "name": "Mime-Version", + "value": "1.0" + }, + { + "name": "Content-Type", + "value": "multipart/encrypted; boundary=\"=ENCR201909161405190000048D\"; protocol=\"application/pgp-encrypted\"" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "application/pgp-encrypted", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "application/pgp-encrypted" + } + ], + "body": { + "attachmentId": "ANGjdJ-LpRu6X4T3_0sc6w75k2ue7zu-GmlYGSw3NN4J3mw-t2iBu6PbCcofWxMypG-E1uzZJZDPBMGL05aUnRPsxstoTxctnTo5iebpaVO1aOJDVmlyoZsATpNHwKT7rl9eJiXmiLqr1gtnXIf1hoBdP-C0DDztVcKW3cpzDNH_RIn7KnMigJHIk9n_saMf-JbOkvx_UkzLdmJpgUJJ70b4QZ_Cu8Rs6-DYxbYJz6a1Xm6syxwpLafdUXZbKdoUnWC52LsM2u7nmMWkoEQCiphXghW3opq359hsGXW6K9YU0SA60YDyNrqEkW2n80GmGZwH9sxhfA-x0h0pWNwZu2lvAlFKg5oTRzmt1CDN-HOIYetXDmbtahVgsA-EQFA", + "size": 12 + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "encrypted.asc", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream; name=\"encrypted.asc\"" + }, + { + "name": "Content-Disposition", + "value": "inline; filename=\"encrypted.asc\"" + } + ], + "body": { + "attachmentId": "ANGjdJ-lyVfCmgIskxdLKmIegNuvv14Gk66bGGTw4Pwdphd62Iw_AV59LJPL6S2zv7Qc8za1fhtJo1WtNJncnqpO8rpe9QpS_LxMXZBJ5gIxLkPf8XvzBtB7P_w9qCrxKX8kYZWGWm4SRKo_N2OKk6LLCvrL7HqU07DZcivykaZYNzgt9PKb0aKb2wzoDV7ZgE6BH7HLwDgfFBq0VoFzKYoI33W0amaqC1_MZaMYd1x1Q0Onpsq9YHnkCHXSUPFni1Cv07u9oH4vhKRYgaolbZ9JxKmVNu7hrHD8z5Xt5TFue7r6yKx49VhoVB3R6uMM7nisHNTx9qFD9YK0qqX184VpQSsfJIU-SskEdkE3bdacefa9rqZaRLxjut4dyYw", + "size": 1777 + } + } + ] + }, + "sizeEstimate": 7157, + "historyId": "1406352", + "internalDate": "1569098342000" + }, + "attachments": { + "ANGjdJ-LpRu6X4T3_0sc6w75k2ue7zu-GmlYGSw3NN4J3mw-t2iBu6PbCcofWxMypG-E1uzZJZDPBMGL05aUnRPsxstoTxctnTo5iebpaVO1aOJDVmlyoZsATpNHwKT7rl9eJiXmiLqr1gtnXIf1hoBdP-C0DDztVcKW3cpzDNH_RIn7KnMigJHIk9n_saMf-JbOkvx_UkzLdmJpgUJJ70b4QZ_Cu8Rs6-DYxbYJz6a1Xm6syxwpLafdUXZbKdoUnWC52LsM2u7nmMWkoEQCiphXghW3opq359hsGXW6K9YU0SA60YDyNrqEkW2n80GmGZwH9sxhfA-x0h0pWNwZu2lvAlFKg5oTRzmt1CDN-HOIYetXDmbtahVgsA-EQFA": { + "data": "VmVyc2lvbjogMQ0K", + "size": 12 + }, + "ANGjdJ-lyVfCmgIskxdLKmIegNuvv14Gk66bGGTw4Pwdphd62Iw_AV59LJPL6S2zv7Qc8za1fhtJo1WtNJncnqpO8rpe9QpS_LxMXZBJ5gIxLkPf8XvzBtB7P_w9qCrxKX8kYZWGWm4SRKo_N2OKk6LLCvrL7HqU07DZcivykaZYNzgt9PKb0aKb2wzoDV7ZgE6BH7HLwDgfFBq0VoFzKYoI33W0amaqC1_MZaMYd1x1Q0Onpsq9YHnkCHXSUPFni1Cv07u9oH4vhKRYgaolbZ9JxKmVNu7hrHD8z5Xt5TFue7r6yKx49VhoVB3R6uMM7nisHNTx9qFD9YK0qqX184VpQSsfJIU-SskEdkE3bdacefa9rqZaRLxjut4dyYw": { + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCndjRk1BNjJzSjV5VkNUSUhBUS84Q2tjV2VMbUN5OGx2QU5sbDBLYkE5eW1UaE5PbVpqYmxCTlJadmdUOERxYUwNCmhhR1h6SGFNR0h2aTBkNjZQMzhSWGZEYytIOWwvakd0ZFMxemdpTUpNcENVRnREYzNPUGdPdUE5M3NSZXFCc3ENCjdmdjVhK0xTZGZGWlVQZ1VrWE0ydXIwZUErbmlORStHM21iRGNyL2N1SUxZSTh4VHM2eGJIUklLVmwyRzA5ZVMNCkJaTUV5cUgzZHVJQWkwTTQycjRML3V2QUJUY0V5Vkt2WS9RSEZtRlRqMXRTenFTRDVQRHYrbk4waWhOUjE2UjkNCk41NlBNY1phenZUZENoaFh1QTNNTmNpS29KdGJaNzg1Yy9kd1JMOGJ6OHJyN1dqNmlGKzNRbTZrZ2JrZWYvbzQNCjZEOHU4RzFlRGZTV3V3dFhWcUlPdW9rZC9tWWdOSVZad3Qxc0p1a3VHdjNlTDc2YjdNaGszbENFakU4dVNPZjkNCk45bWJMRXJlbDVWVVR6TlRWcEEzMzZhQm5NS2pFc0pVSU9nMHNVMHE4WEFLZVNqY3JJdUJyc2FLcGpxN1dEWHANCkZBMmVRa3BIcHdabmxXalZNT1lSUkVkamkzRy90MzJBVFRjaE5YbDl6aFFzaW9xUWJmVXRXa2oyV3ZsdEU1b3oNCk84NWRkVlVuaXFwUVBkUWFvalo1K2RQWjhTQkMvNGVVcDN6NEo0L2IwZldTVFBsL3RMYmxGeTFISnMwbEtHNVoNCjhBYW9DR0Y1VExQb3lnWGpCazBJbWlrZUlHbFlJU2hWT3FHMzZSSmxNaDR4T1FDbVkwZzluejlMZENFSEordUMNCmtXaC9vUkVCaFNNbnFsbW4xaWMvREcxNmgxN0UvdGlPdU94c3FUZklHbGtMU1NoWERvaVRqeGdtNTI3RkE1SEINCndVd0RTMW92L09ZdGxRRUJELzlmNmp3SnhZamRCbzJwVXk1YytnQTQ3QnRXL3p6MTJNS2hSQUhkKy9iVmJUdjYNCjVKaGxCdzFKb3cwY2tqY2JuRFJxQlA5RUwrRXJBbGMyVXpHYSs0MkFocmMySGxEdnlNSkNjeEx0MEZhMm5oWEcNCllXR0hzUWJIeGdiZVBXSG96d3VuMlJYYUF2dkJvbmhCYVl0Y24wUVBORXRBckI5dXlPNFlxWFhvSDEvbDAvZ2gNCklBenVSK0xOeW13ZE9CWHB5aVZGTUpiNnh5UUY0MGFUMzFrSThHZStVa0Jia1dEcGhjRVBvZ2Q1OWtyQkVwd3oNCmZCZlBkbEdvVHJTd2ZiS2JzaE0wa2lFYlBoK0VTTVZ2eXBnK1BabzFRcDBlWFl0N2dqbFlZcU56UUhXb2JUVHINCklRalkzVDh2bWw3WGxjUHp4TEZxdlFsaXVJWnlSTGN6dm0rd0RoVGorSi9kWEFLMFNIRS85WGRxS1kwMTRqNXQNCldqVWZ5OWlENnNlWjg1bnRBV2R4SG1Pa3l0QU5lM1FmeVZ4Yk8zTjMxbkZlNHVxSm1XMFJhRUR4MGVtM2s5WU0NCllMZTVPd0svNDlJcFVqNWdWMVIzd25OMHVOT1pOT2Roa3lWSnluTERKWFY1RExvV08zeUdNUE0zaU0rWkd1amsNCjRRcnBYalZGc2NmVEh5LzUrYk5GR0huYXBsanpsaTljYktxdDNqNjEwd0xRYTFwSGo2SzN4Sk9BTndyMFZkankNCkJGR3dwUkVRRFBjZVNOUkVGQSs3RmRQaDdXUWU3UDVOYmZZdUJYR1paZUl2Ulo2UjBFSGk4QWd4bjE0MjZxWUoNCkVKTnIrcU8ycjQ5RWhmQ2R3Yml6UkxoQnNxTUpRSWlya2Y1c0k0dzVSSWdwSTlnZ2t2L2dRaXF4dnFGY0RkSzcNCkFWSytlWmlCMmJ2WTNTVmFINDloV2FDRTFPWjI4Z0RZUGxjZTZBUnh6bnExZXFRaHZnVXlPZmZqcERqUGdTa0YNClFoUUNqNi9sZTlsdW5Qa05LRVlVaEZyMmVCQmFiQmVqUkFzZExUT3NsRzN5bHRJQ3BCakhHcU9CMkNhRGxIZ0wNCmE1ZW9lcUh1c0JBeDlmbVl0ZDBaaTQ3NGNHYXk4UmpHdHEvRSs4d0RUc3VwbllHYnNIRjVwRFhDN2VyVzlneVoNCk16SUU4d0FaK0l4YmhHN0pYVnRIYVBXQWJ2bDFhYzdZQlY3cnBCWVJLdXZadkRROUJML3RZeTU5SEE9PQ0KPXQxQ1kNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg", + "size": 1777 + } + }, + "raw": { + "id": "16d558cb71e8d510", + "threadId": "16d558cb71e8d510", + "labelIds": ["IMPORTANT", "STARRED", "Label_3", "CATEGORY_PERSONAL"], + "snippet": "", + "sizeEstimate": 7157, + "historyId": "1406352", + "internalDate": "1569098342000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-16e8b01f136c3d28.json b/test/source/mock/google/exported-messages/message-export-16e8b01f136c3d28.json index ff2eb48d474..209457e1fde 100644 --- a/test/source/mock/google/exported-messages/message-export-16e8b01f136c3d28.json +++ b/test/source/mock/google/exported-messages/message-export-16e8b01f136c3d28.json @@ -78,7 +78,7 @@ } ], "body": { - "attachmentId": "ANGjdJ-45vBleV9HteDOioeYSuhxwlHCD8trEB5vet7JYw-nbw9T3GnGk0zhoJ8VIQTVNSCNY8qCu75UPRr13d6A8CtB4wxZFYMsgBgw3cizodRak5SvOBymX3vKTqRoZ-MpuuvzW6_y1Dc276vUgJTCrWKRXKNdDUdullUZO95x-NfGa_4SoUpfrDfcPVrAVLOaebITtTBuiSRRl5GUeRdU8nEPdZcq5TrvdBhsxqhNIgXrauTfDmQsTwEZxgANrUD7dKPbnBopmQezh8Sc84Q6N24vhzJifVykeu3ETAMlRuVrA4mttka7NMt9ocxRKseo0OgAvw2ycnOqi1AW2mMx45EOpEgJh1g6En2OEXROEpAhBt9DeHOcWEs9rXj6hLI184S5k6AF9UgSEM3N", + "attachmentId": "ANG-att-1", "size": 10 } }, @@ -109,7 +109,7 @@ } ], "body": { - "attachmentId": "ANGjdJ_ox_J7EzfZv_2mZXXnWBn2BKUGGjTQWGI8HMWfVpLMckOhXuqi0QHQVte16xtF7eYVAmTUAmOlwDMkYAz3IVGkeIAG3JhNoLT2WRwjkzl7JzeIkY3_4-QzbHdQXY0McH6kXMTOG8kk9Cs9OEokEEVNFSwGKJu3c7gm9rq_vAstFKQhAOaYLLiJsHkVLOQ7bK5p7zRfJvqqZrbDswwChmHRbXZ0nF9d9pKx2yCXZiO8yhW8KcDtSh7N-CwT3UN6ry-D2g6mFn-cv3WNnEpzTXcypxOvTqk5bjIzCXZdaCoEtmWg893v1Yr7MDQlelvRQNa9ryq_7QZzmjVy7WeJ6z1tdaT-qe9DluRL4lkqDrwoTSj6cqVv7YOUDfdtMn3kg9qLhVBZleYP7X6J", + "attachmentId": "ANG-att-2", "size": 165884 } } @@ -119,10 +119,19 @@ "historyId": "1095349", "internalDate": "1574290190000" }, + "attachments": { + "ANG-att-1": { + "data": "VmVyc2lvbjogMQ", + "size": 10 + }, + "ANG-att-2": { + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgNy4wLjkgR21haWwgRW5jcnlwdGlvbg0KQ29tbWVudDogU2VhbWxlc3NseSBzZW5kIGFuZCByZWNlaXZlIGVuY3J5cHRlZCBlbWFpbA0KDQp3Y0ZNQTB0YUwvem1MWlVCQVJBQWkvelNsUXVnbUhYVjNTbXcxRzZyU040Q0FMd3dxTndxc2M3dDMyNEwNCit6OWZlVkxGVjEzcXVhdG11V3dhTjZla3FlbHhFaXZudnZaQzhVVlBmbFBqQVVmR2JneW4wVCtpNHVMeA0KK2ZlZ1p6cjAwTlV3akxoaW5QQW1xVzVqZHNmRVF1S2JZaEJJV3l5ODBIMEVlcmIzZXl3dmt5c2gyTmNBDQpLd2lwWWdxcGUyZk95UHloZjN5amgxZ05ML3NJWWxMRGZhajdUcDZvK2dkRHNoZnladXN5Uk1pdWlnWkYNClBKUzBMaUx6UnVHVGl1K2ZHcHY4Y0NOUWxUOWpoeVhmWm1UcmZkVmpkY2IrSHR3ZTMzOVJkVmYwRjg1OA0KcTNEekhHcnFYWmFraVhIak9zVjdVVTc2MzFUVHZuOWN0dzhsMXZKUGovazRXTXQyRDhCY3lDWDZ0WDBsDQpBOVkzR3lvSTBMMC9kVnFpZ2pWN2JKTWR1aEJmUUpNdFR3bENDUDVsYkdEOFFQdWVUbmpWdzk4eUNZWXMNClNiSlhaaXNLS3pJTjJmUVhtUHVNeWd1UXdLTGJ5Qjl2QytjU1VBOW5YblVXK3lHL1k0a0ZxMTJEKzB2eg0KUDU1L1JEOXFvbW5RaUJBbmRxYVJkNEhrd3R4eFdVeGpLS09jaEFmeGdXLy9LaDZNZDBlWUgvY1hRSWExDQpQVjNBemRxa1dkQmNNMnlpZUFTTWRVZEZidVNaejR6NGFXd2ZqLzIxNUFhbk1RbmxFZzZoajk2QVozcjUNClpya1J5TFNDZjdhTTU5MEF6ekgrT1hDZ2lkU0prbkp2QXU4UU1uQjkzSnNnbElqUXJGMDRpY2JNWFRrQQ0KOWwzanpjMzdkNEdlWGJlZHlsYmV1bStXZ1ZXak1TeTFLWHdlSVc0cWhWekJ3VXdETUYrQnFhN1JJRFVCDQpELzRra0JIWHpaSjZoTnlmeUtuLzFkZ3gwSGx0WXRCUldvR2VTYVhOaTVqTzR1WnhqUzRPb05leUhqWWwNCkRjVzZPaTF2ajVJSWZMak5tcW5ZYlh2akJQRFRxS2ZuZTd3c2VzRlUzcHBnQzFpQlZVQndKMGVGRkV0dw0KYzdpVUh0VGxtaGNRQmJMWTRuZWlVSEg4aHJ6REJ3dnhYVFZmMU5KTVBLMzlNQmNBaFF0S3JPbmhpWjRuDQplL1MwaUoxUFVCbGZwTnBMQ2FCNHJpbWNmNnpqc0R6R0JpRXI5M3prOFpwN000OWZvRG1BVG1NQzBRMngNCnY4cjBuL1RIbENDMHRNTFdDbi9YcSt3RFh6d1lBSlVOUm5HYjJ3ZzB4RXFOWXIrZnhMZjFLSjZTS09GSw0KMEl0RVQ1SlJ6YXVId3grODNzYkhsYzN5TzVhNkIyQ3F0ekpOSzNIOXcxSStwN0hKT2xBNkNhcUJBVlZuDQpyMUdSSWtwRmFmejMxc1Arcll4QUFOMFhybHBzeDAvSHgzUzg0a2E2a25yMmlxMjhSMEgxOGhVdWlITnoNCm5nL25hMnNhZFljeDhpY2d1S1BhOU5PanZDVE5HanRJbXZsb0pQQzYwZXZETlZ2SFR2Y2pJM2Y1TnRZOA0KRlIyN3pld25oZWdFNTVIdlg5dWhGK0V6WnVwMXFHdkd0ckdBTzNCc1BrYkNWT24rVkxRWlZYM053NXdqDQpqVE9KajhRR0QwSHN4ZDZ5QkdSK21SY1JqYzJyRVFxdmUxOWNqQlJsVWZyNHgvZm9JRkJQYmQwVDlIb0gNCk1KMFFEcXE4L1Z3R1RqU1VXVFFHU2hsRG9nUFVmNVJrQ3cvVjhiTzNOQ0luMldBM3M1blNTa1JWRm9kMQ0KeUJlMG5Td1lWWGFSTjh4MXpieWlJMCtZVWRML0FBSFJ0UUh6QzdYRGRNM1ozWjFqSjBFWGVQQ3VSNkI1DQpmVDdvYzVWbnI3QVc0TUdhZDJHdmVxVldIaHV2VmVOTGxrYmdsNEFkWHJGQzFhVHpoN2lEbTlnUmJRdSsNCnRQUllRVnlub2ExcDF4VGhMb2xJUXNHRnRTbC94SitkZDBrbUVpL3N1UXZQMCtucE1NZ1czNkFKQWttWg0KdGpPTUFtbjNMSzNwbENGZjlDWmhaMGNBL3c0L3NDRnJIZzlHU2FvcHM4SVV3NU5tTkJZM00vamlubjFiDQpWaGI0MUtuTVRUVCtDVWIvaUhUNXM0dXg5NHJ4MFcxcDlpWnhOemFlRnVvOTlkRkE2SmVYbVM3M0JXY3ENClFERW9QeWNVNndNa3FmOE1Ua0dBb1JEbGpWQmYyVUF0ZDhmUmJCZStRU0c0ck1WZG00dW9YeURrbENpYQ0KcUNDT3c1dlF4WjI2WTJ0SXhzL083aGkvRE16TnlvcGVkeHZYSjUyV1dVRzl0V2pkL0Ezek5pYUhwRXA5DQowaXcwTTVidmJzeFZIb0xNT0x5NzRGQzVHZmRFNlJQamJLRzF4dWVjbWFycENJWWFrMFhGZVRoa0tTdVANCmIyTWF4b0dYVlZmTG9yQ2RYUlMzSUVlWnFUblJNOWQxTEozRkNVSnR1WC9Kc1RObkRIQjFNemY5b0RlTg0KSCtMVCtpcERRcjZvTEFPdVJ1UWFVbDRXYkxrdTJLN0JiUEg1Mlpydjc1c29ycjVERmpzbStkSkdYdXBEDQpzb3B3a0c2L0duTVJIMG9zd0ZUTkd4UVNtWHgwU3o5Z0NZRnU2OUZNejFHMGljclQ3NFJuY2JCaFB2VlANCnJRN1pEaFhiSCtoQnRrOHJ5ZFNhZUgwYzRuVC8wY0svUGg0VHdJenNtZTR1VG1hOWdWVVJ3eVJMV21CVQ0KQVRtdVRXMnZXa28wcUoxUHpGVnI3N3NwaXdkOW96eEljOW56ZW9ObUZBRXNKYjE4R1hBaXNncWxIQ3o4DQpYbmY1N1NkY2F0anlVbnhJQ3o3VjlQdFhMQktjajBlMDMxMDB1eGhwTWJJb1U5TUNUcWJKTUtVY3dtb3gNClJZTmVYakxyRHdiQ01EREtlVy9QMnUwRy9tWk85aWlNN0dWYmR1bGY5ZWZaY3FkKzRmK2lmQjVSekt4Qw0KNzRxdUloWTRRZHRIUGVvcWtsNnZBVW5nMlJ5RUxTS3pVY2dWQitlb3FmOFRXNlhPY05GODJ0eE5CbHB6DQptNzc4aWt4Nm5ueWtZWUFSb1cxZFpPOXJEa2FpRFJscHFKQ3QvZzQxeXJPbmVHcVVWakk5VUFBYUdFSDQNCnYvZEhiTmFDS3dDWWtRekFRbnJnSVBuQTdLKzh2NGZPN2FlWGtRY25ZQVd0UG1RYmIzNzRtanJ3YzVvSw0KN1dQUk5ibGx3SHkrQVBEbGlyMmNPaXVZMGkrbUZSL3RQZ2x2aVJUV05LeU1wMDBVU3V2UFdMdWFxd3prDQpPYnJQMWZTSVNOaVFtTnhzRlhuMER0UjMwRHBBeFEwRE5HVytXTDVxQzhhNUNsUVFndnVRZ3orZkk1UWINCjNoM3FNWTJjUXRXdlVuVDVucW9nck5SdWIrYkdXTUtZWnBCTTJnY3JkbDhqR0pCdWNsL3YycHlpV04rMg0KVThNZWFmQzVpYUI0WndKemdweXhTRkpRRlQ2UWIxT2g1Z1NJYlRWekpiOGlvdERGY3RhT1VUZEgvYjZxDQp0VElDczMrajZQZ0trb0d2VFBTMjZXN0FWSE9XZHduSWllb2NFU2hNMXgxQy9sekw5cXVvU2JZNVNpR1ANCjBmVTl4RE1tRzBFbU52WVluRUNSTXZvQWQvMDFWMXFzMkExcmlUdFVqVDArdWNLN1NCZlZwd0d6eTkzZA0KckxrQUNOdVQ4VitibUkvNWZITDJ3RzBWMzlwbm9CSk1pWWVmSThVQTh6V0RJQ3Y3VGJ5dWFoN05lbHV6DQo3Z242cEdtZFVLWUJCWTdST05qTERLL1d2Z1hqTS8rbjdEejBpRHpNaTRGZGFrQ2IrVWpiK0xYRnFUNWINCmIwaytoLzBKUGFOclloWk96dE05U1owZ21UdnhHNEI1L2VQYXZiZ29YT0UxM2lkQnJHZCtWUkVZYjM5Tw0KSkVIbDBwenE1UHNVendMMTdMYWRLK3VDRjY3RFh5aXpKSjVFZzdOZXBoK2ZyblJzcGp3dld6SmVLNDBlDQpxeTMxSUxhWXFERlRsTlY0Qno5YjBUTDBFRjdYeGRUNUQxcktwZTMyMUFYd0NCZVF3UGdZQkxwdU1ycUQNCmRWVXVNZXhOVndKanpWbURZTUhuaTE4cWNkRGJxbExjaWd5bEFqaVpoaHhjeEFXZEdYZCtiek5YRk15bw0KMDFsZTM5T2NuVi9TK0NOQkpNbHRScldLS0ZkdkpXUnFjc1FCT0NNR3ZZN3Nsbkk4ZThZM3drcDI3UTVEDQp0cWpMTGtqT05Iek5sa29oNHgyaE9Va2tiN2JWenlVSWpUYXEvQnZ6cEFCZDdNSURaeEJ3ZlhySW1VcWQNClpOV05QZ0FDR3VoSzVwMW1pb25hd0E0RUVqeUl3TEs2WUFDaTFjS2krOC9BU3hVNWN6ZTZvWnhneVU4QQ0KQzZmSW1SNGN3MU0zcmw4YnFXS2NFaW1aMW0wM2JGV0pxbkl6T1ZCaWgraHI3R0VSUCsybUU5WUQzNHgyDQpnSHZWcTlSNi96dUE1dlpBYkFMV1pSTjdwc0MrYVcwcUFMSEFZMGxUTDZWc1FQN2hWSVIzdHo3ZVRtRVgNCjEzUkpmcERib3ZnZ1FRSVo4MFd6Mk1KaHA3Sm5LOGZKamtST0k4TFBqRVQ2eXB4dHdCQmROZ25nS3A5bg0KbEZOdGlrTUVZTlRvaWdCUEdPbjM0N1JhRStmdkg4YXBQelBXa203YmZQWnJrZ1YyS2RCWC80UGRBQmxWDQpOUmxSZW1rQ2w1T3RjOC9JRkVOSlV5ODFRakNNK0ZPQ2J3b3Z6UnZnSmdDYlpaNC80YUVQRFE1RmZValINCnlCUWp0bnFGZkFYWXdNK2c0bWFzem4zRlJqQWIxcEl3L2dwbWNtckRuaUlqd3JtQXVacFFWbFVaamEzRg0KeE5kbU5TNW9wdlFONXd4OXFyNGlMUzd4anBxYmV0QzcyWXduOGlUaDgxdGt2RFB0UmpkUC9oNWV1Vm5IDQpTc0ZEM2FVbEdmdUJJZmpMb3J5N2lxRUtSeUNuQXpTaEN1a1VFVUFtc0RVRCtJSHZNbm03aWJOQ0N0SGMNCmp0eXpQc3I1VHcyNm9RY2FTVWtNSlNJS253S2ZBTFBRenNia3Z4V21oL1QyMzV2QjRIdzZwSWYzQXhuNA0KeEIwMm9tN0cyanBWejgvYVRiYTYxYzRhNUdzeVkzZU03Qis4WUtmRFc0MGQwOVZxemhseFhmVXFwSDMvDQpPZFFPNC8zUko1ay9oUEtYNWpnaEZGRWdXWCtUNk83Ni9yYTNzNzZZcU1McGpPZXFGZ1lMWjVPQnZ5MjgNCmFTZDk1QThHcEJFbU5FeCt1bVhJbkdYa01tU2VodTJpMWxyWDdLbjVuQ0tGeWpPZFR0Y3VFMll6VmcxTA0KclNBSXZSMFdBSWVVUlkrZDJ6cDk3clVKMkxqckJGMEd2VVFaS016UmI0WFpubkJTZVhkZVRWaWkwKzFzDQpBYzJpNVd4WUtkUnZxY0hCTCtvaWc3TklRZG5TVGtsYXVGR2tZZnhMa0xpYzN4b1ppRVd4ckJFa3BJYzgNCjlRbldpRk9mMkNXekY5NFpRdWpDYmlCaXZMemh4blhWTDZ4bUk4dHlSZ2dZMm5aR2RkNnFCaFBwNjZ6Vg0KZ2xVamxONDhjdWhINXQ4aEJIcUhOaFRVODdSUmtZblk4TXFZd3UzQjdBTGU1V2dsTk5SK2lVemZWOC8zDQpnY1M1dmVLdG94cWk5NWl1azB3elVWOUZLNCtqOU5mWU5yWHdUNHJKUjFWM1BOZ3ZFNDRiYkc5SjArZGkNCkRpZ25FL3pXQXpkS1RpOHNTNEt5MWYwUXMxYVZXT3l1R2w2eUMvaHRqWExpbWxncGo4NXZXenlpZlNQNg0KWVRqNmU4MnB2ZXhDamtiMDk5ajJzNm0zRnNiZFVPTi9ibXp4SDdXQ3VDR1RXWGQrSjFSR1NULzlpTHpPDQpJSWREK1FKWFo3M3lwajdPMkt6c05aWlRQUHdUVFYzQWxhV1FtNlBFN2RjSTFpdTJFMDdoM2Y0c0IwWEMNCmZ2Z3Y5ZDFWL3NsTzgxQW82ODVXbDZ0QWQ0MytwKzZtZTVabzdwekRPeUF1MGNEcGRLQ2pFM1h2VlUzbg0KT3lqOHBjd2NOTElpWXRocXBkMU5pZmxiRFZBZ01TYmJ0QVFOWkkrcXRoUmxIcUhmbE9FUUlOcmRSM21iDQo5NENJbGpCTExJOENITlhTUHc4Lzd1WHVQNGtnL3VYQWFlYVNldjQxTWxQT3MvQjdnblZIZ2pkcDUyS2oNClkraHZYU0dTeXVMRGpRZ1MyM0pPclZtdFo2OU0xSUtUZEFPTVV4bEhGV0RWcWhuWjl5cUJZcXZIb1N6QQ0KdDE1NWdmaUNEanhTUmxIVUpLWnVBU3BPd2VVcy93QjdkTU1rTlRXVzdmY0NEWG93NUFzR0hPR2llWmNCDQpDbGZpWXowUDd0bDA2bmxJL2dSWjVoNzVxajZyV0pOdGNDOVF2cC9KellQOTNleXBvN1NwWGlGd01sUUYNCjFjVkV0djd1bVVXNzRPb0RES0l5UG12QUZyWEVOblI4ODMxUy84UTF4STZFczFyd0owUk5CSURBbmRTWA0KcS9vMm1rQkhkN09zS01xZDJZUkptbS9BaFhuUTh1UzdXclNJOVdCZDJOQ0FnVFNjUFR2RmFhb2RKY244DQpqTjNoMGdua2w2RHQ0ZmJOSzdaaEFPdzdXTHdoK29EWVd6YW0rM2ZIb1Z3MFkrMm84TmxNRHo4Nk9BaXYNCmVnUnF4OTZleHRtSFNRRGpOVlR3d2Y4dDF6RmV5Vzg2WFcxUml1SlRGMkRleHlBMDNhdlJwQmZtTHd2MQ0KOGZadW1KRkpGNk5uUWVvR2c2T1krMjRjclJmRWd5c0QxZE5XZU1ob0NPREIxZkxvTXlLOFNNR0I5a3ZjDQp4cHNnTXZFOHVwakpyRjF1MnNwVFZJbGoyYUhxa2VSKzhyQW5pei9CbzF0a1F3M1RlZS9DVEM2TFhTaTQNCi82ZTcwN2NxOEJsUm50d0Y3aFhQcnQvZFZEQjNjdFpIaUc0OVRHdEU2VHlSdGtSNVZ3NzkzYkxseHFhVg0KN3c3bjdxME14ZjlIVzZleGljeStpc3dvbTFSM25ldFhveEFQa01XNDVyOVc4K1hPRkRDVHVYeGZUWFpRDQp1M1kxc2RqM2hnbWxJWGc1SmYvbndBbG1vVm9sbHVIek9mUDljcU1ycFhUZGI0eHRNZHU4VWpUZi9KUngNCnJrZEV0MGs2SDBJK1hYRldsVFFRaXc4UmF6Mk0rQTZkV3JITkhGVGlSelhhYm9UMFk0U2VFbGEyMWR6WA0KUHNsczNpSFBNQkdKQ1BhQVVmS3JDNzhFR2E0ckNiVlRXcjVCdFdLVkl1RmUxQ3ZINUVyVDNpcnlFam9ZDQozbVM4RVFaRHJmLzlFYUpVV3lGdXZlYUJVd1BrdTZjT2lEYWFWRGZzZGVNKzYxcUJKOSs0a3U2Z1hnSE4NCmo3MFJJNVRNWkFJQ05tcEFNV0kzZ1ZxRjgzbGxsaS93OWNQWkhVRDVsSHR4TmJTZVI1djBacnc0Z3lIMQ0KZmJpaXRreFVHSWU3L3MwT3JJVVdpMVZKQ3IreTdNMDFvZjhkSmh2NFllZSsxOU5sb0J4ZmZaVGNZS1liDQo3dXpMaG85OGFuNVdSMlBQYyt2UUlYZm51UTYrSEVFU1NJR1hSWmJxQm1rY1NCZDNvdU5SUXgzZXZIc3gNCm90UTdMMmZiWTVHTlUyZjM2S1pQc3lETGRqeVRZMnMrQkxrd3E3dGdpUlNYQjVjeEJleklHS0dzVVZiKw0KY3l5QVpoaG5xMnJOS0VFNTVMdjJKanBQK1BFZStkQ2h4MDEwSnNhNmlXOHh4a3ZyQitPaDhHeTNzclhQDQo4MmJnZ1ZnbUFONkNJM1BEdnNFSFl2TDdhVXVoOVhzN1EwekttNEEzREJ2bTA2RU1BZWhkMEY0bzV5bUwNCjMyd1FWWEJZWHpydFZHWHEwVGJWRWhRY204UWswdkFDUTN1dlhZaGp2dEM2Wk1NUERNMHIrTkliNlhmQg0KNDhON2lFZTFIeFJpaXh4R2tzN1l5TERJaUdSQmJIeWZqbWRta2FlVUZLM1JNT3NvOGtHdWJFRUk2VzhQDQp1UDN2VnQvTEZnMER3dGZoS3FJbEZJcWxOM3QxUVFpUjdLSmFZM1dLaHNSbW1neGxIR290NENkRS9lK1cNClpoRnRWbWN3WUEyWSt2UGVsTTQzaytRMnN3elQ4MmUrK2FEczMxM1NPRnlWaERvZTlJYWxtbUlCTHVEdQ0KKzhuRGl5YzNpY1kxSXFUczlxMjVSUlJCbE5mKzFYWEtRTTl2c2JIUzk3bXFzV2thUkJSMXZBNzE3ZWxyDQpySXBwQUlXSTNWRzB6U3I3WFduQld1c2ZpRkMrcjB1K3ZiSHpJTmdWTFdBRFFDTU9mNWNaZVM1UGJ2WUMNCmhpc0VqNE9weVRaQ2xSVGdWQmlRSVFFandhZ1B6cVBLdHJTaUlIVHp3UmFoM2g1ZWZxVW9SY1dNSTlqUw0KNFlBWFVzUCtaN0FsQlpTdGV1b3dvNDNtRUJJWjlUQnB0eTFQU2YyUkpuQkFGM1N1QUpJTWJHYzJod3lWDQpGV1F6YXpqMmthSWJDMUgxUTJZQW5sdUNlZG1hYUMrblVVWUNSYjhzMDdFWXp3SXV2M0RPYWRRZXg1SjMNCjhUdzZrRFJDdnB0aWtUcHp2SlJIOFJwRmdLU1QwVnM0eDU1ZjRVV1FMR2lLazBkNnlnOEY4NytldGxGRw0KbHhiVkRyT08xWkIyREQrMFlSY2Zya3p5TUNkQVVLTU5RUVA5VWs0dWlRbTl5bWZaM1J2a1ZSWnhycU1xDQpTRXMxRDZuT2J1Y3B2T1pBSzZpVS9EcUJ0RFdEdEs5WmFIZW90OFh3cDA3M1FONGt6amRaYnkvOEhrQi8NCjQyRDlxNTU0Wm5QdTEvRWM4TDloakhIOG16QWVyWlY4bG5mNXpueGhVN1RRT1phT0Jvb2JnVEtTNEVhZQ0KcTBBTUNMc0RGUDVYUnpiMTVCK0RyM3ZBb1lpenVCUXFUWEw3bGwvT3gyNDJQaGVYT0ZBNzBBK0IxK3h0DQpUbVI0Y1luM3NSY3B4aVoyTDlsU05NT1NuVzhCRFlXUVVMbjJMaWtzMCtYaWdlS3ZIaTBkOHhsZ1M3ZUoNCkJ1ZHM5U2Yrb0laL1JsUE1NZFRWaktqOVhRZDdsbUZwODZIL3JOZE1YTlE3b1l6S2dxbEtEc1lvOXdYaw0KWW01aDBScXo5Y2FNYTVDT2NpZEFVQUJFY1Q1MG1aWHZ1UkxTL0FQME1haW5TSGhZbU81d0l1MG5kY2lhDQp4N3YwcFVmcEhLc3NmS3Q4QlU0b1UvYm5aY0tRU0JnYzZzVEJWdnp5S0s0SUJNWFFHZVNEK25BL3Q2d1UNClRKdTBmeEdXTFh2OTBZOGVWR2VYTU41K0hwMjV5RjNsaHQ2Z05JNVBPRFRGYWw2RWdJRkF0eW9uRnZMYQ0KMGNMRnhNMFg5UjdiR0tWUXd5UGpZNTRKS3Y5VE1PQUNIZTVzcGhLVGZ1enZ5U2NaVWljMy9WaVlaMzhqDQpPZTh1d3lmL3d5MklhTjR2WktBUDl2Z25KcVlmNjN0akUra1cyRUFGRkg2eWlESTZPNmwycjRqRXUyUTMNCjFIQ21SNmhwTDN3NzYvamw4T2RhUmhrMHpuZnN5VkVQbzJ5a1RTSS9kK2ZsMndETDliQmk1TFROUWlPLw0KbnIzMTVxRjNGQ1VKZ20xMzc5bGsrZ0lvNmUrYU5zY0hKOHFPWEc2dXlPYzlGOVhPVnBJWG56T21OQjFFDQpVL3hQVlRmM3JSOVVjMmFlMS9ZM0grS2VUb1pQOERlRjlvY2JldUo2MEVBWXkvZS9HODIwY29qV2QxWlYNCjJnOXV6dW1BY1VrKzUzZXhRa1RjMEZ1dWlFaWFyQzZJeDBlR29mWkF1ekxMZEZmOFpoV0UvOVpXT2ZYSg0KckExSlV2TEpEeE5OWGZOdkN2QitadG9kOUQ5dldJU0hEbHRmaGhSOVU3QUxodkVhb2ZRcjJCT2laQ21vDQpqaXNHbmVHVUxxdGU2dUhyRzdjMnNobDVRRVUraGpqd1Rhc3JjOXJwNE5lMkpsZ3hLditRejAySjJseWsNCnFra2RxWHRyakdRUXpxUW5WdXlyeDNaemVSRVFYd1haQkVxcnNaN2lkUktCQXR6Rk9nR0MzeDRqYVZ1Tg0KS0hTbTVRKytNQlkzb3NEUWlUK042ekx4cTFxYjgyNUhJRGF3UUhFeGpQa2NxRllPKzRKTklGdFhpV2ZWDQpTTU0rSEdvZEF4Z1ZIaFZPSUZFMDRJQXdyKzI1U0Q2eEJpdnhZVURwTnBIM3dOMkQ1VWtiNWMxUVkxVDENCm5GV3VGT1BLaU5BRmxCa1cwV1FGMnJjKzFEanNiaGpjd2dPV2dqTEpUd2hiSnptbGZZWTl1bU12RGpmdQ0KRGlJZlNQVmUvTEsrSFExYUdPSHVLQmFhclZkNjFWbGRNNmJLc2xEeVNqNGNaaUZoWVByNnlkQ09OcEk0DQp1THNZUHRqNUxSQ1RmaURNT0lOcGYzck1Md3p4SjBONVpIM2JWMWtjaDRWMmVLME9IVTJFUitQZEVGQm8NCnNGTHlnek5KVGQvd3Y2UURoa25yUFNuTVQ2bDQ1RkppbCtybGloSXlxa0g5T3F6anB4dEN6Z1hxR2srNg0KamFOdTllVVFIY1NLelUxN0k1emRtb2ttVE5IdkhZU3hyOHN0QXRTbGJQMmxkQldMUmdmVkljVDJEdWhFDQozRU54M2g2cGZuTFlhd3JDeExYT2c3VEhjZWFGUDJwZEdUaTZJYndGcWVzRW5pL3hjQ1VkMUR6U2NoQWYNCjJlMXRQRVlhUGVlMDB1TWZOYTgxcnVVd2wzZU40Tjl4dXgrazR2UzJORTBFazNCaEJKeVZEWGd4VlAyUw0KNC9vRXZPWFlKaGhJOGdPL2h2LzJGY1ZlQ003MVJWOEdOWkErTE14SnFCckE4Ykt5T09OTmJjTkpMUWJmDQp1MkkzRGE4OGtVOEN6cmpHd2tkM0NJVjlHVVVXblplT0l0OVdGSzhKT2dDd1NnTkVkR0txK0pOYThTc3ANCkw0NXBvWXlIbVdHRnIxU3BDM2lGSkFBdUpnVmxIc2FPdEZIclREVUFPTWs0S0hvL2lzL1N6R3kybk1PNA0KbjZWcWlrbG5LL0pydXJOMGhkOGFqSFNaS2x2dkRqbVg2azNJdnhZQ3EyM1hzbnBWUlFPSm9ucWM4aTRYDQoxYW5hU1BLL0k2a1dDR05RaGZnQ01XWXpWT2IvMGYxUjJ5Y3ppT01VbkVJQktQdk5xa1RXci8yaFA2dXgNCnRUUTRNYk83V1ZlMXd3dkJVOHdVVW5CT3lMRWxQODlTZFB3c0lUSGVpd2lGT2Irdm1Ic2dYYlcvbDNjdw0KQmtWWTJWV0VWZkRXWU92eGZ3Y0JCa0Fzc2JMS25wKzFtRFQ5TEdkUHhKckdHT1ZZRndVQnZDZVd5UjZwDQorK0VZNjRwQS9QaUlDRnRXVmlHT1NTL0FEM2EzTUVYcmR4YjdKQ0dGRXFjNzJSMGVidjhiYmV0QWhUUEINCnNvMU9XYis1aHNXaDAzcnFVdlNyUHhudThKSHhqOXV0Y2tPUkxyNFRtV0QzMlJ3MGxISVFhTEJJUFMzYw0KdFBza0NRNUhpZjBPbkNaLzBwMjBkcjJJZGdmbXE0eTNlV2ZkSlpXVE5wZlJ3V1RUMitzTzc0ZzhtUVp1DQpBcHhQeXIxM1V6SkVhRnNiZlB6VDlXcEs2L09sY0J2MFY1aFQxUElyZjMxbnROYjlLcGRJWDk3UUpyWW4NCjV1a3g5dDJpSWV2YnAwUy9aSmJTU0cyRTRxSEM3ZGZKQ3pvbGRScFU3RmhlU0l1N3kyOEx2d2JoeHRNMA0KeHI1S1VUMmJraXlTL1JqdnhDeXRubmR3bndFRmgrUlZZK1hjaU8zTFBrOHFsdE4rVUx1YW9wSitDU2FIDQo3VEdPM0dLd1NYM3BJNXlTV1p1c1ZpMHNNbDNZeDJFTSsrbncwRVlQR0hBNWdWbyt6WWFDRFl6aUYvWUMNCjJ1bXhCT2RIc0dvNEJ1cHZaZHM1dE9Xa09rZFlnaEZrZjkrMjZESVl1dTVOQ3VWRXZGbVIybURFd0VKSw0KSUN1elhGSFVDcGs0RWZ2UXVjVEZPTXdGNGgvdC91aGhCRlM4VVZ0cnZJbERLd3FTdHRCV1hSSkxpUC9HDQo0TzdOamdHU0x6V2lGeDlkQlRJUU81T0RLOFQ0ZU5hZkRqYkNETmJ6aDViNDF6WDdJSmcwM3hNVWQ5aHcNCjVjZmJ6YTJaeWE5SFFyVjVWcnp2aW5uR0JtTVhwUWZhaGlRcXQxMWV3YkdRZUNuYTBJRXhtc2FLdWhPVA0KaTN5OFJTSmNvc2ZXR3NNbllITnJLWFNtRHpFNHpSRDhqY2dZblc0UnVVSEJGTUVKZ2d2UmFSaUY5b3EyDQpiK2FiTU01M3U5NEpFK3AwZmpzY3BEdVJpTE9sQ3FJVXJjdm1RdTZ2SjJFckhHNWZObUZKU1pMdnVFTEkNCjRQU1ZFQWlzakQxUjUrbVZGQ0ovYjFHbkQwN1lrSkRkZTB0dUI3aUJ3bGlrVFRZcFFtbG80cGJjNEk3Ng0KK3JPNStVM2dPVUtZNUFSRWs1eFJ2bmNoSWJLMEdvTlNTdURnT29YVW13STgzVWhmcnVBbXRGbU1UUHQ5DQpUWmdQdlV0SXoxSFBWbVIxYWNxc3F0cUk4YU14YnJmbjVWSU9aYnFzc3k5TllRL09LL0hLWVJ4SjhRbHQNClVrd2ZUMlF1MUxVektPNlZjTUdzK05Rd1dnMWdrd01peXozQnhIdkx6UVl0UFJRRllQZmxBa2s0V3lnYw0KVmNHZmdRYVd6d1p1SGFXYm55bW5naGlDQTZ2V1JMb3JLYzRxdWdKeVd6WnMyNk5LTzR3OFZUaDFPM2FJDQpNY3QrYXZldmZpZ2UzRGR0ZHo3aGlrWjFrYTdTZ240NjBoYi9CNkp4SVZrajZpaThLcVdQamhjUGxhMGoNCmQyYzFIYzU5N1k1RDBMckxXTkc3aEZDdXRqRXQ3cVlFUVNzaXZ5K2lTVnR1Tm9yaGx4NldiRE1KQ2d0Ug0KUjhGajBCdGwyYWRYMk1ZMTA0Z3VVd3NDdW5saEsrZndHNVIyZytwTmJRNjNETVBCTFd4QUdiRG5ZTnMzDQppVEZ3TWhNaXpSTlJnaDlpL292VWlnME9UV0VGbk9ielJvVjBwWXo4anBERjFSN3JrZEgrS1VneHo4RFkNCjIvb1ZIWkdIYjBXcEVVVCtVVjgvTzQzK21iU3ZydThiUnczN0lGTENmVFZJZnBMN2ZROTRTOXRCTEI3Wg0KbWRISUptZU5XV3JNWTZKSnlPaXVYT25KTHI2c2E3b01rdlIvYUpoMlBuRWRJZEQydFFIVDNRM0xxck00DQpjeUJSVDZjSkFsVUw3QVRCN3dEd2RCeGJPRUZ1NTFNUjN6cGh5cEhkbDdWUzBqYXdCY3hzbEtWb2NDeE4NCmFrUWpSbEFIcHgzaEVzUUdMd1d1amlMNlF5QTlmaDBWVmlqMTN2cXhIdHJTZnVJeDdZSGNVSFh1a1FLTg0KOWNmakNDS0QvVE5CVTU3dk5qbTlDck10cWIwYk5uWmloZGN5cnl4RVR4bHhtS0JjM0EvUDZVSmtnUFJJDQpiRVZYYmt6NlloWEd3Nk5kM3BuMlFyUU5BY29wOTlaKzkzTEZEQWdFbVZaNmlVUDU1SEhPWXNOQ2hCQWQNCm1CV0tVbm5ObG5uV3FzYlp4cGxHeExkV1I5Z1RWRnIzUFRQeWJrQW5EaDRlVkRhcWgzV0RpdHl2VFEvQg0KYjZYQUE1RHR0OTIwRnZaOHlpa1podzhtZThUd1VyUTVhdlFRL0xXRDdzWlVJN2Q5T1BvK2Q3Tk5mL1N0DQpmN3JjRzMwdFp3NWVsbGhWQUlNUlV3OG5FS3ZSNDNPUWpGczVhdENLTTgxUnVYNUMrN2daMzk2QXBwMHENCnJLTVdoNFd1aGdwdWoxVEZURDAyczZMRVgraGlWMUIxaHZGWndzMCtMNk9BTG15bFhxWXhsNGRwTVpqRA0KazNaNDdoKzEzNWwyNVNjUTcwWVhUeWs4LzBmam16UXdMY1lQK0c3QlFjTzBnaUVBY2ozTlI1a1lhNUFSDQpXR041eXp1cWRMN256YldoWElwRitSeFRrRVBHK1QwVVoxV01CblR6N1dRY3M3L1ExVm9UbWwwZEFHNDANCk4zUTAvSkRmUG9tMjg3c2FVcWVzU29NMk52c1pqTURUTWN3REU1U0pHOHF6VjRKUjhCUVQzZVdhVTBSQg0KVkRkMXRISTJLOG5LekNrUXIyZTBuQUkyZWZCZVU0V0lXZGRWeXpEZEsrZ3lJYklwODFWYUM4Z0NtWEJRDQpnNE5ib0VWYzNHR1NuZzFmKzh4eWIvbDQvckI3UXd3RTc4Yk4rUzJIV252UktHUklJTGN4emVzYmdXTFgNCkZBc000ZnRGczNlZEZ6U2lJSGVXUDJqN25lTWxhVk9lMXdIbkFSWG5JSlZvT2hwUnhDSkNDUVhRdzBpcQ0KcjBYNzE3dEpYa1NTRG1UUUZSUjd5ek44QmMyMm05M2J6eDdBVURhL2hvdEFmNisyYXYzRVdxbmdDVElnDQo0TlZWbWpER0N1SnlwQzVZS2hqWDNPQ0cwMkkyL2haNTB0dE9GREV0VFJ3b1V0Y1dGb0I1VFY3SnNnWkkNCmc5d3YwQm1nZlVPdGE5Tk54cEYxWWExR2tlOFNUU0M4Zzc3bVUvUTA1VUxiUXQ2QTgwODN0dVZnaFlqeA0KUFUyQ21TRUxjdWJtUFlXNzdyczB5dDdYRTJ3UUx1S2p5VGlxVytDcXlwU3ZRZCtvOU1SaGNjK1RTM3VMDQpjMGVFN2FMMXF3dk1hTGcyQktoSk1QTXhMTnVFTmQ1TEVLSVF3bnVJWXZUaXlqWGFVdEVBZExiTllwdUMNCmIrUDcvbDIxVlJ4dGtuSTRZaTh2VnpGYmUrWHRMT1FlVkFVQlNtS2NvcUd0bUVOc1VBbVErekxXb0dzbg0KRnYwT2ZZZ0Njam9kZzl1MjZJbmgwa0tWTDBWbDB6VVc1T1Z2NmRHV0FkTTllYnlDMTJmZFBFWVhhMVFsDQpNTVVIeWhWNDBMck81MVdSL2RZUWFiTnNLQ2RYQXdlZHN3RnVpS3lkRDI1M3pjWU5ZcXpJZkFnL0toWHkNCmo4Z0NzNGtwUW5TVTkrejVNZHhCalg1czRPSGRmYWVpOHJoRjJSUGd2cjhnUVNxaURPaEtNRGxCN1NqMQ0KaWR5K3I1Zk05dWh5QWdEZ3ZzQU9GQU9VTWxUcDZWZGFpODZPTDVQVkNXOUtCbmVPVEVwT0RjamNpTnJVDQpmM3AyQUsrMDFjeThmVnJXNi9Zd1BJaER4Tm9VQ24rRHBZaVAvOG1qUHhpdTB5RTBaZTBTSGRSNDU1M2ENClBJRVFJU2lRQi9wMDRHVW9BZXV4NWRlVjBGblRwcS9nWGk1dnBqV0l4YTBEaWVha1BUZEdWUS9GV1ZiUw0KcG9ZUDc1bXROZ2RKYmJmTjMrUzMwUWpmRzRoekxqRjhPb0FoQW5Ob08rME5YcmVBWGljUkRKZmRpZldKDQpkcTRUK1l5YnRXbGxXb25kNFIrK2EwV0xNdE1JWHJMQzNQSTVtR1VoQjVSNVJtT1RrNW02MnhQYzcvQ2MNCnVyZ3BuT1hzNkt6dDNnakJlSDlxYU4xdUJjakw3VGpBbnRTRkd2dGxSM3IrclRYSklpUjJYWklzMzRoRQ0KYXQ5QUROUlJFVGRKL2lrN2wzNW5FVmErRVpjR0x1RVIzemVmQUxjbHZLOHRlZ2haRDc4TDJDZnA1dFdSDQp3MXBJRXg2Nys4K0c2c25YQXU3c2JFMzcvU2xmRXp6aDFXQWV0Mzk4a3FuUExOeHRVQmlBRy8wVEE5L0sNCjJhZlp1Qk5ha1JobEtPSjlYRjV6N09DWERTUE5JMWF0Zis1VXVyZVVYenVBTkVxcWxFNDlzSlZPVmFzUA0Kait3ektGdlNHYk43aW9IRWRkdVhETkRSWWxjY01hbUo3MnVvS3VHaXF4OVFQVXZwS1Z1ZjUrUUZ6Z3pHDQpBUER4ejR3SkJpVU4xZmc4bEIybEZyZUZKRVZqTXNaYVdCWTJyUDQzTnJISThzWGdkNEdlUFBMZ1RIZ1gNCldmNEV0eFFvN2g2dFM3MDJKOEJiRG44WnhNTlRwZVUvL1ViNUtmOVFWZ2RSSm4wRkVQZjMvcmlvaTBuNA0KemhnUU5GL3U2Uk1PQndUbnM2cXJiQ0lXQ3ZzeUdlRHY5dUMyaEFFYzBRZXExRGE0M1c4OC9lblUyNkl0DQpJeTdpR1pRTUR1MHhRVHNidXV0R0c1OEM4M0xKWExZQVFBcVhmVkRwajJZeFkvTHF3WVZqc1gvemg3bkcNCmdXUjdJc2t3L2g1YS9NMUF5dG9uN1VUOVFOOG9iSmxBdnhCMUcyVjlZczBPd3JuY2h6R0Y0eE0vTHlXSA0Kd1E2eENHN1VWdE5zem8xbUlybWs5UlZqUlFrdmNGREVrSWxyOVhsclllaVhsd2xwWE51QW1wZysrR1h4DQpQQWFmNDRraFZ6VW1yQmI1bFAwMzZleko5cjRJc2Z5cmMzSS9tY1UrUDRHRG03ZTVFTWtkZjlrTTVWUEENCmRSSlh1L1VLVlNtSkFUUEZVNDNmdDNmT2dwY0FseUV6S3JLaGg1VkFvMWF6ZXJKVHptN2RqWTJ4MGRaRw0KbmhLSTVvbUNFd0N3RC9QS0RSbHVadmR6ZW1QVkh6cFlpSjJtZmluMzEyWDlmTmpxTDFWdURZWkdGS25YDQpzZWxCSHlJUVN3NFZKM3BETTdjUmYrcFB5QjJRZGRmNjhESmlQa3lwazJEeUNyM09IUHdVQXJOdyswaHYNCkg4MXl1U0taeFR2RG1YKzNObTB2R0U4RkNwNW9Xa1ZySUk3VmsvOEJwTDhGa1IzaFlzRHVpS01SblhPbQ0KbVZZMFVrUUNjanBmaEhoTGxWVVhMNGU2NjZ0bHJPNE5kdTh4RzFtbXVTdGR0TWdtZldBZ3RIa0FyalJvDQpBNUtSelNaY3BxV2RsVGpGRllsci8vWkRsWHpsV2ZFYVE2Q3IvWjF2anFxUVA2dS9zd05uRHdzcW5sR00NClNVa09halg1VzVkdjN3MGM1SExWM2NEUkFuZjNzdHRKbWdIMTdUSTYrcGtqS1hVMjdxenZCZ1c0Ym9QdA0KeHZFTjFmWkdDaVJ2NHpwOFhoZmhEeXNRZWZPOE9MYU5TdWM1QW9iajE1Znh2anFVTERXcFNhOVZpNkZRDQoza1RyNHpoWDJoV2p4MnQvblpLWitwZVVkK1A2NElqUXgyS29uc0xlMTdwMEpaUTNWQU81RUU3ckNRa28NCnB3TWdqZDEwZEl5MXlKbFpiMWJPOEhHR05WZlQ2TnFESVBwbTlYN3A0a2FLajZBcEVaTjN6YWZsYkRETg0KdklKSzF3UDlSLzEraXVKOGtINzNzTXBlaXJEcHU3V29BdTFpdmljVklYUGdpckl6ZnBWVFp1SGZMWnlGDQp1L2xRODhrTnc5OEJPVjVWd1VtM0UzNGEydm56cGhXU1VhMHVYZkRmOElpTEFhV1NYeGdMOHM4ZFVwOUgNCjR1clV2ZHp4by96ZHR5R1JIMFNCdGRRYVFXVzFubmJPVndtVnJhSmpwSytzMEFwTXJOMXJTNnEybjNoMw0KY3F1S1UycXAyMkhKNnJPWXVVUU5jWldxWWZDZU5MbXpsTVp2MmRST1hTMHhrZ3Z1QzJMV1RCY3dxa1JkDQp6TG1QOHhEWU9pcTdJWWhTcG9mYldubk9DNzBTaGxzdkpPSlMveDZUVU1PUFA2cG9ZdndpdVdxbnhJcjcNCk9LQW50M3Q0NVZUaGcvWjNxRzdTdE9ISG5sTjVnT1RTV1N5alVOVkFvM3dTNkIreG9FUUIrcWxiSW43RQ0KWXp2SjNTeXpSMFFjU3pUUTkyVCtNU1R4SmNaeVZ1MWZrMXBZVTRna2YzUStKdU5JRG8yYWJyUTRBa0dJDQoxcTAxVVNIeFVOY3lITkdNUXE5Q3hPS2hSK3l1M0gvemNQNWNwUDBnMWd5cDlSQmwveVZlNlNyd1hGeVQNCkh4NktZWHBVSmtLY1R0RllvWEJuZlpha0tsRVpQaFdvb3NiTTlwbDJJdFlacXh6OUZLbkRTbGJ2UmZlYg0KRnI2clQvcDliWDhVc3JkeUxTaDdyK3NVK0c0KytHNWJQM0FGM3BJOVZjemRnQm90d0tGbm1NZ0p0WWQwDQpvbmZsWEpVeXJSbFBGNmUycWpGNUZ5VVQ5THdmUXpMaVUwa3ZBbTB3KzlPRG5sYUpLQWp1WWlnU3kxWWENCm4rT0R4T0lzSFRHbngxd2VYVDZSSVMwek5zck5pbnBpdXJmKzJMMTd1bERCYjk1WURmdTNpU2V1WG04Zg0KVmRpK0dzQmZ3cE5wOER4MkllSCs5aEk0WWloZzZYV2tCMExRVmVBeTBCOUhaeW00b2FUYjJENkFVcnhnDQpXRnZFRDRxVGVES3Z2VDVHbmlVTW9qQXZHeEhSYkFLS0FaOE50YW5JZ1Mza002dWZjNVBIWkFBVWtobUgNCmhreFc1Mjc2M0l2OVhwdnpsOGpHR3BGQWhRcWk1WXRCcVBCNXhnQVREZ1EzcHpoN3ZCOW1nYlI5NkI3OA0KaUpVSXNTU28yYi92aXNiL1kxM1BuZ0RkQUV2NzVjRTVONlFaajhmMGZ2OUg4cFRiR1hvajh1NWtQNnFmDQpDWFdsNGZwUzJQNEVkTjRnZHZSeXBnU1Rta25DQU5jRlFyUlhqN1BYcVNVMnBXakRQZU5NN3ZzOThpZUoNCjRhVi9FdjFRYUd6eldEVjJpYzEweG1TYzdxQ1pDeHppQkJKMGRmT3MxdEZzRWJ3azhRcDNUdWFzSGh1Rg0KNUxBM1Y1VGNZekRaN09DQlVMY1dBc2FQaFFKOWRYTnRqR3M1T05xNXRTeE9ydHpDTUlHNmFPa2N2UU5tDQo4WjNOVkh1OGJhL21LSUJnYjhDUVRCVmFqcXRVL0U2V0lJenZnTSsxS2xFOTluWk5hNThhUW55aTZpU2MNCmF1Y1lCakQxdFVGOTJoQkFqRWhTbGw3ZGNIaDdiL3FjckF5R1ROK1dERzdManhzYjFUTW9WMFhaR2lXUQ0KK1AvOHp4RUVxazZyODlrYTNCTk54QnAvUUFCYVdKWWVsaVZ0bjZqOVRneGVlbHZydXZ6QUNRVGtod2RXDQpCNUkvd2szS0c1cWZIT2V4MVF5N1pIOXo0SkVmUmZyOHM1V2ZYbkVTQjZZemp6bUxSVDFpcVQ3cGIzOUcNCkQwUFZRWG8yTGNVTUJTempMR1RlenpXMEV4dkdxUVM2UE9hemhaT2lvdWlwVHdodXFBNldWUkhOQzQ0VA0KSVVnVTNQNlZWS2k3Ync2L20yS1VGb0xUM0hEQVNFUDJrVk9ENmFpa0FOWlVRNGprYURvU1lXLzV5ZEF1DQpzWjNBdVRqSk1lamp2bVRZOHBUbVJKLytQeVN4WjB1TFZ6NEx3QUIzbUcxNFVOZW1GS21yVjUrOVp5QWcNClhWQjZSU053Ty9KWVVpM0JZcGZEcmMrNm1LYlY4ZHFtSWZORFQ1U0FmR0wzVGpHSkZBbW9OVzZlMUxUVQ0KNEl1TC81ZG40dkJ3dHRMMnA0VHhjTC9EUXNIWnpSTStHejViKzJ6c25iM3V6WkN6eEZOQUtUeWtvdnNtDQozNFJnZlBORHpmVU5jUU9pTTFmV09pQnIyM3RTS2RDUjhhOWtwYUdNZHVmNDdPZFpXZFQxYkg2YzdBSEcNCnFwdmx0dWxKNGtZU1hIRVhwM2dRT0YybXgvNlJRYkhDVzE3WHl3RnExQTB2K3c4Mm1yUGUxNGdhR1pOWA0KV0RzRmVIc1BXTWN6MUExakRLYVprY1lhRlhXTVlNVHZ5bExNQkZ6WHJaYWdadFM0NkZaUkhDNlVwNVFtDQowVVJNN3N5YzJKbFBKN1NETVREZ0J3Q0hPQm1YQ3pwWlRuRmJxZnhwRHA4K3Y1eStLNWFyWjlacHJNWmsNClBOWkZSTlFSa3dINXN6K2JpMWdLYldIazV2SnFNZEo5disyTHF5NENZVHhDcERmWVlvTEZJMEVxZWcyMQ0KL0NsU2hCNm51VDdqR2NEdTltOUJCV1kxV0tDaUJyaTB0QlFuY0tYR2pUWnZsdUF2ckxSTlp6MlI2eEpmDQpTZ2V5Z1RMTmZwOERNRUJXYlVldTNjazd3Ui9QZ1BheE1BZ0JvRmNKQTNrYTVKZVlqYnNUQUhuYkZZSm0NCkJ6SGtJTWMvUXlqWmlKYmhzQVVIdTRudjhDYmFiY3dpQ05IWEFLeE12VW9DanBYWXZEQjRZM0plMDBuYw0KTW9uVitmWXNzekptdlFMWmdLR3VvdEdHMXJqNmdxRTRqci9FS3hobUN2ZDZOOXl0UDhkT0pUY2xINXdrDQpXRGpmZFlVVnd4TXNPaldDTmlWL0RUSGJWZTVPODhJMXFoSm90RHVyYWhXdk5lSXVoTHIwb0ZWSDR1K2cNClZucEtySm1RdHlmL3JRMm9zZzBkWGlZeHVXa0t3emt0aHRtUFhiQW9YSFZLaWw0c1FycFhmdllOOU9jLw0KdjAwRDBaRk1HQnFVeEU0UmdseGFmU2tVUVd3eHVOcEJlS3BpK3NaWXlieXVlWnlUQ1RnL1FXcHVITXdNDQpZYzZQMnRraUhlYzFjT3FBc1dMbWtrL0dseDZKMnVkNzlFRWhBMU1RU3Q4aUw0QU05RHpjMUM5dlEwd3kNCmFjdHhlU3JtSEdxL3ZLQy9SL0wvN2xnNHVUcm5vWnlpNkh2NWxHNGNwQWl2RmR5MytCSWVGZGd6L2ppVw0KbXpuYi9yUnVwYXRKUkVqZ0F4T0dtcUF4dVpJUmpoU1ZwbmE4TXVlc2hGMU1vNkh2UFMwZ1hEbWpjeE1IDQpsYU9LM2ZUVlB6M2EzdWk2WEJ3RnV2YWNUbHdkVFNIWnROcDVYTDRDcGx2Y1FpTkxDWVYrSHR3dHQzT3ANCm1YaytzRC9sQitnNVR3MzRVekNVQXFySG5CYk13cE42UW1xWk9lVWVOWm1FY0ltQ3d3eTUyMHpMNjJWbQ0KZUZPcmVoRm1wQlBkbWJvdStMQlU5c2M5QnlhT2VrTER0bEVBaDFiZnRub1NrL2lsZndjbFFMNE9qUHFtDQpIUDhIR1NTVmt4S3VpWHhQS1VrZ2l2WEFGcXAyNzlSeEFBL2k0WHA0MHVOZE04c2NwNmFnaEhnYXE5eTcNCkZNQlE1ZWhiWk50RnREdU43NnE1cG80cDA1NEp5NTdNNXhhQ2htOUZWK1ZWQitVZTJhVkk2aTYwWG9MbQ0KYWhvdDNyQWhCODNZbkwycWdwY2F0VzZLUFVsVTJKMlBqQ1lHajZzaEg2SVRocHpPa0ZZVWVha3dDMlF4DQo0MWNUSTFwdWRMUE9rakI0d3VKdWpHZDBVYS9zMGhRdXpDeEU4cGo5b1pWaXI5TFpxSVdkclBSWFFYL2INCmt2am5PcG9xSjM3MU90aXUreThNYllLekd4SFgremh0YVVSNklEb04rc3hwNkFoYWRQSk45Q01HM2dKTg0KNFExS2MxQStmQVBqN3d0OVpJdThCV0FMZ1d3czJPVjFObHVGWmRHN1Q3anBNR0NmV25ZZHdrOHNrdHU0DQpDVW1YcXJyaUlmTEpVMDAvbmlmL3dEcmh4VmVlR2cvbzFCSDlmMnd4TDdEZk5PNUdPRVpNVFJlRHdINWoNCnAxNUMwVlVXcWd6OWRKTHJMNzlvNHU0VU1qWnQ2dG1raldvaFcxZUNSMEh5NXJ3MmxMbUxYNkNsdzNiRA0KdXhWbTdaZEhUREEvOHZZZUdNWFJDdnVZWDZxRGFyd1J5UVNIS21vUWlmU3NRYlhpQlRmRWI4K1hSWjdyDQo2THd3dVM3Ym9rOUlrS281T2lBTjh3TTFlN2orcmRzemJWcVY3TW8xNHlaQWZCdnUrOWlVS1FSQVJDTWkNCmZERG5tZkVneUIvVVR5Q3pFTDF1emxDcGdzR3RXTUVSaVhPRXlkVlN1djhJZmt2bGpqalBIN0JkZ1pmRw0Ka2JkYjgvT09EemR1bjdtWUYyaG04dFc5bXZBcm1PNW8rVVNOM1J1SjVHMUJJZ2VYdDFjbklXKzd4czFuDQpYb3FBNmZIbVpTR25XSUtrR2xBR1k1MnFSR0l3d0tnbjJxeVpCY3J0VzVURGhLNFJyL0MxaDQzcDBSaUQNCnROdVdJSVU0Z2FnMC8zcm9jdnN2LzYvTm42MlpEL05qWEJvOWRzd1loL2wyUUxaaVFSdEhsbjJrSHcrRw0KaVZLM2tibi9McFIySlRNTTFmcHZRODBZR2RpZjlXRjdpaUpicWdGc1B0SE9TdXZ1VVE0YnhUb0txRjhlDQpvdlpSRFpreEZaNnNwSURTT0NUOFl5Q1FrbEs4S2pCdGxQd2FCeEdWYVRtM3RXUktoREhEUUZRVzBHZ2sNCkcvejFOSGlMWURXeGhWT3pySFZxbGtPV0N1YWV4OE52TmtiQVU0Z214MEt2L3piOGxEZE1pemw2RlBScg0KZThwQUFpSDFYT256WFA0V2NUckR6ZGM4SGJ4a1JWNkYweHNrMjFUdTkrL0FKT0I4NDN3TUNRam1hcHRGDQpsZHZqL3pXWlJjQkRyYk1CZzdNN0t5L09Cck1rYlRVcGx1Mk1udzQvRXN3azBZZWNwVll0SnB1ZGMrRTENCi9jU0V1NXppM3VPMktsU0tqSlloWHZTYmF2cFZTZWcxNXhKU0oySDJQOGJiNm9Od0xET0JhK3B3ZGErbQ0KK2R3YUdiQW41T0U5UXppQnBaYkhKL0s5N1IxZllqb1k4Qk5MQS9JcGNWTHNLRmxHQkpOYkJBcENqdEZFDQpBa01aMHF2NWZOTU9WRDNqNnpyL0RjY24xVnJrZG1HNUJ0dFlHN3hOSzZKbGVHc3ZvaFZwaE9BM1FOWkwNClcvU0dtck5ZSGVOYjRIbkxmMzJqaWx1OVpOL3dlV25iZHZvM0orUFF4a1k3by9vYi9rM3IwNUJ6UFZvRQ0KSGtJeG1PRzlvMkVweWQvN1krdWFuenNIZHJCMlpUMGVBcUZnb3hhNVJoa1pZL1psaTY1b1BMdUQ2NUpJDQpVc2sxNk92QkFJK3Z3MjB3M3ppcHQrN2tsaHZ0bmVoTWNCUU9NQklSeGpSSWJOMSttQVBRSU9tREx3bG4NCjgzTWFwZTVhMTdSZTlDZHkrd1RMT1dxZW9DNXFiZWVhNjF5VGYvdnJublhRLzM2TGFINkV6Nkd6TGNobA0KdXFiRmEzTE1VVW85NjJpdXRQUlRld3MzMklUVzdYK3hFNlo1RjRwYU1uTmJFS0RhdzVJRU9ReExCRjNoDQpTK2tpeXo3ZWNFZHVyUDFMVExLTkN3WmJ5T2JZVUNRcy9RQnVLOFllRmhQRndmSDFIMmlmRmZ0NW1WY0QNCjhZUVFOOXQ3emRkS1dHNGQzVWMxRU9tV1Izd25EQUwwckx4ZUs4V1Exa2ZsY2Ewai9HeTJJVVlDNVBpSw0KdTBZbndSeFFXS1ZacXNqQnlQaHVWaUNTZ09GaFRuU2pmaHhjc1hQZXJ3bEVHb2Z0dld0WkhVNE9XcDJHDQpuR1V0T01tY1QwMDRJTTBVVVZwQlIxRVhOT3FhaURaR1U1WGxNRlFDblZZTmcxYktoSTF1WTRhK2xZRzENCnExTjhkVFlBbkZmc3owU3cwNUN6UTFMNUphVHdLUGpoUHg2ZGVuaVRGelNSeXZaZCtlalo0OHlwc29nRA0KcVh5WUxOREoxN3RPd1c1Q1ViVVFOdnhJb1NZWkFvTnl3ZXppMWZQb0xrN1pYcGhnTWhWalVNdmZHTW91DQo5eUNFeTJ5VW1xVFg5WndUaWNpeUQ4ZzdsM1FkQ3lsWXRZUXR2VnJDY1pERjJQV01mUTlCamR1N0lJeUgNClQwNjljYUlFdUwyZTUzem1iQ3FkU2VtaUJybTQzRktjTk13b1N4dXBFRzBlcmxJSTFLWlRvVzF3TmZ6NA0KUkNhd0oxbCswNytaWkZTclIzTjcvZWVxU0tSbWJWNkNXZFVCOU5zdkRzU3o2QzhVWER4WmRGL2RodzhwDQpIeXYzRTNMTis1THV5YkFPYkRDNVE5SmpObW9pOWZkU2ZXdXJHYm5yRm1xbVQ2eUlQZzVjMHpOdjlvQkQNCjNxSjZob3pjMlFHZHpYV0NXVFoxYVRUVDYxSGtWaDc0QUdNN3JwSW1jd0t5U1JQOHJSMjkwRDl3QWNMNQ0KTUd5VGdsQlIzek5JWnQycXlyMm5pSHBrVTVxLy9LdHdUU2sya053SGNUNnJTTGlKMVUraWxJVHhyUHVyDQoxSy9SOG9qYVpKZGZlZFhPeWsvMzlpZEM5QWV1bWpDWUduWTJmZGlkemlXMGFkRWE4NjBQN2lsd0JnZnYNCjdORU9wT24vallKazBjOTdlU21Gc0RSL21oMjBYQjhLTVJ3RTBEOFUxSzl4RnNvK0MwdVJHSG9UWFNhbw0KTVNBamJhNGU0b1ZFQzRrSFByaTJ5eVNEeENCT0dnWndodUZzMXllclF0WjhZWEZvMlFHZEQyQ200ZS9mDQpPeVNmaTZYZFBMOEFRQXFzN2lJSkJqUm51c2FZa2FWL2JXR21xTzUrS1I0bjFKaUxyNlFjb0pZakJMYlENCktBckRLS2ZMQVpuaGxtQk5RMVNJd296SDVueWJrelFRMkF2U1pheWpzT2RDUUkxeitCMHZQN3ZvYUVibQ0Kay9hdms3NTdxQkFTWEw3djRobkVWSGpMdUdtekpjR3JJMGV2dHJySkhWWk9KZC96QVc0dEdwemt0OHVpDQpwTWR5MGRuOU9yRHFKVTFKTzNyUmdvb0FPTTQwVnEvUlpSMHA3MjV0ZVp0Z2pnbFR5SmRqN3kxYmlvcWkNCmpucHRGNWlMd1VMbjBLU3lrOW0wM0ZkZXFqT2xMUjBGQmt1cDdtb0FiYzU0MzlXRkd4cDF0MTZhMzF1dQ0KOCtHTnZvWjliaE9Na0ZraGdpdzVMUEMwZXpLemM1d1pYZkZseGwyZjhRODVlWEoxTUpieG1xaHhBZkVNDQpxc1Fmem5tbzhscHFDRlF6WXFBcmRTbkMwa2lvWnZYMnFuNDlaSUtHOFRSWVFoUE4rWXZnRUhKYTdSZjkNCi9rNkNQWUY1OEMzY1U2MGtYMktXRkxiWXo4VUdLeVR0dEozK0t2akFpSWtzR3pBRHNPaG5pWkdlVU1QeA0KOWFYcFB3anZzM0N4MkszUGNGN24wTzZ0VldIY3FvSnVzSWdkK0MwTFMwbE1hREVLN1NFbzZxNHcxTE1qDQpkNjQ2Qmg3N3MvRUZVYjYyL0tycXpCKzNmblNCMDRtWDZUR0grZjBBbmsyS2xWR2owZlVoWVNoM0x5SHkNCjcxVzFxL2ZUTWhiSE1DajFpQTNSaWF5dXBMT1RCUFN0dFZJUk1uVjMza0pTbDZSWDhWTER5TzJlbWhDMg0KOXZYcnlHOG1WNjkxSXgyYW93Zk1vZFBhNWRVMFZJZmowT2lMQVBGckQ2M1VqdlRSbFUrSWM2TGsyZzcvDQpHbUY5Q3c0L0tua3NBSkRQVWFQS2NUZFBjYUhGZWRydHp6VUk0SzYxZDhJVEJtVVpLN2tNT1pEa3hWSGsNCjExSUFpV3A2MjhjWUNJL3Uxd0FRMTRBaGlwRUh5KzIwZFBsQnR2ZFZDMGM0QWJ5WXp1MmNIK1NnNTJ0aw0KUi95eVAvVnVQUnAvSTdSWWQra2taenlXb056QS96ZmpzZlJqSEFvV3pTS1pDQ0h0UDlKZ0o2anBGTXdlDQpXdEN3U1dCWGExdWdoM2pCSXpkaVRtRW9LQVdDRXBWSDlNRlhJZGFiSjVvaC9tdjhTTlkyNlhvUkJtQ0MNCmU1aUNpcmNOVi9oMUdmKy9EQ3cyallzYzhQSVVXanFpUXRad3pMa1hYVnorY2wyT2JORWI3MGFsbWF2bg0KMDBxZEhDNm0xTkY2bnZsckoxRjJpV2svanRBN2t2bG1SNzZlQ3gxaHZLVkNiOE91SThuelFqYTNwZXpFDQpQeWIyV2QrVHcrL0pDN05ldWovaUpoNFUyYUl2a0FKZDBDZ294NzdiN0tIL1hRbHIxeDgyS2ZZZW4xTnINCnR6bmVmSmU1MzVpcDZMUExoSVd4czB2S0ZoYUlWd3hYd0phSGRhejZXWStVYlNYdFNPYXB5Sk9CcFdCTQ0KcitnZFBTRE84bXZaYmF0UmEyaFdmbkpOSDdlUFlscGdoNUFZeGFURi9NeHNRQmtpeUNDREFPMUErNFZGDQp4Uk93Yk4xVkZwMlMrY2N6TWRmQXhrVEdIQU4yRWVwZzBzYVY4MTNRMnc2cW83NCszZG04c2NxemFXR2kNCjlZclRjaWNOYnhMU3I0eVgwYVJxamVTU0N4SlN4UHdYQ1ZSRVFWNkI5R0xxWTJWaHRXSWI1Tmc2dWI4WQ0KSU1hZzlzVEh1RWIxMEkvYVcyeVpJZC9wYm1zUjZzK0NPZ21pUmRZWkF2WTlITWtkLzJMT1pKb281RThJDQpJbXJ3TURhMTJyWms2RVliUWdtdEM2SkVFeklIRWY0NWdURTM2OGwrOHVnY3FMc0ZBQlRZa0g5YXRPK04NCkJGNVVPb1ZaVXlmWmdRSTVIMGZzNGFUNVFVcmxWRVJVUnJBeEFSb2Q3a1p2a2JLM0U5YzE2c0VNMlJyNg0KUEwvdGNZSG9VL1kwQkl6M3Nib1F4RU5DSzhvR1h5dVRzUE5BcjVLRWxjcEk2cWgramdSdno0ZjFSbkxaDQpMeGQxWnU1T3pRVXFDRklSbU5hZ2JyVituTS94MVVwZE1hYTNjQmsxUTVvVWdDWGx6L0hLK3Vra3JzdEQNCkdyTnh1UlNWWFRZYVd3SmZsZlpGM2g3ckptVUpjUkZ3TTV2NmZ3TjdOZEU0OVpjcGQzN1NJMlNSZCtMSQ0KYW1xSSs0MHpycXlWem1SKzlCTDZkbDkvS3dERmFHTk1EMXlsQTU4SzkwM1FJcWxZek5LYS9xR1cwYitQDQpJWjlweE1qbU1rV1FoRE0xZE8yaHFzbGdiNDhJdHoyT09mOWhzRXExcUl4TTRoYmpoMW5Fc3dna1NrMFgNClBZeEV2MmZJUUhPOUl3eUMxeTllNGQvK09DenFlOHcxd2FBMis3V2Z3VDh4UUoxV0hCUnVNZGZJMk13WQ0KTkhiWWg4UHdnUkxzeHN0MmlYczdwME5DZWV5a3pKYUowR0JJMjRGemt3SzBUWW9CSzZVUXFhWXFHQk53DQpWdFFBdGpqVnNMaUF5MlNCMERqbzZaTlJjRjA4TDRPT2M4c1k0NVIrWFd4UGVWUjJmK1EvVTg4YldaRjQNCitVY0h1QWplK21uRVpaY0oxMWErWGVrSjJRV0dzaWFSSW9BMXJWN0gvWTcwa2Z4b1ZGcm5GOVBMYXJLYQ0KcmV3UkFQK1JhVkNzTGRaWnlhOG9TVWo3RXhKNzZ0WEVnQms5S1o1MUQ5WnREVk9yVm9lSENudkpsMXZRDQo3eHQ5eno2Y213TkR3R0FMeHlkM0txdXE0S01hZU4yV3JyNGZIUHYvVnNHeEIwRGxHbVF1UWc5N3Z5VnoNCjJzemVvS1BXWlQ0a0JXQm5tczh3d3UrLzAwZ09HTXpYak94NXBVSUdObks5akdzUFlUbmxsRnBoY0Y2cw0KRkFIYS9qbTNSaDBGVXhvZzl1c2YwQUNpRnRlZWk5dkQxUXJxMGRGbkFKYnJGbG5RL3RHL0N6alVHRndVDQo2TTVEZzJsTGFzdy9oM3QxMmtoUmloVGNHQk5rbzdKOTY0RjdSVW16ZjU5U1Zha0V5ZFlvRzd3S1JtcmQNCnY0WUF1bkdiZUc1bEQvdEhzZFl0c3lZazFBUEZRa0h3ZjBZaWNXU1JZaFRUSEU5ZmJHcmFoOVZXNUpGQw0KOE1oV0xlS1RhVGlUSzdsQVJ3RytKVXAxYS9QaEtQQm5yVWpnZS8vRVpDTDNvdGJ1aGN4aDhwdHFrNzVxDQpTalQrcWVHNU1CdEZKREtRK2ZGMXlKaTgwNXc3VjNMZ1ArbUtSa1hSc1k2R2JUNmJiQlplUjlmUkdYNVANCkc0VERzZlg3aFZhaTl6L1VucDlXclo3dkZ1WHFEUGZTa00wVlIzOEhtZGN2S1FsWXY4NnloM0NXOXJKTg0KZHlUVVZ6a1QxRmhVeWtObHA2ZCszSmtkM1k4VVRGa2tQUjZ0eGJFZTVYcXkvMHNFMnl4aWZnY0pxZ2NwDQo2dlhuWHFEOUp5OGQ5dDJTQ29qcHM4N0VzaUNEb1NzUEU3aUV2ampVT1BQbDZNTTA3UFVLc0VUZ2F5RDENCnBSd3htcnF2NWpQb1NUYVR3UVNicWU0ZUMycFNhaTBHOW80eVJNdkZDWmpPazBnWVVDUW5IcjcxczQxZQ0KMlBFUVJ3VnM3VExBRVo5U0pNcndQTG1kNVZaWGhLNDB1QmVSN2tyUUd0NXNiU3htazRkWUdwNHk4UTNUDQpDalFvSTVKSUIrRFdJZUhsUlFDOGoxNm5pQlM0LzdITGdMNEdZT25Yd0l4R3ZGU2U3V0ZjZ3dEOGh5U1QNCmxrc3JEeTVlZER5VnZWNGRmTUpmODh1c0pLNjBhSzVyQk9qalZFRUh5M1lnTHIxNlQza09FMi95RXBqLw0KSXJsbXdJRzdRSERwSkFlVHB6L0hqbFltQXJhMGF2Uk1XZVJXYTBRSW5iQnAzTzA0RlI0THZMRFRaUmlmDQpHRHpEU2U0RDh2OVQwSjFWcW15bWl6SXVsQVd5NE9uZC8wbE9jRjluYnVyaCtNWC9aTHVkbGl4WE9tanYNCnMzdGtXTE9DK0tuSER0UWlod1B6YzUrVkpyaWhvUW5QQm1GcWdmTk9oVC93dDNpSG1UaEkzR0ZnQktFMg0KQmpvTmxoZ2RIL3JEWHFKL0k1VS8wT2ZhcG1LK0dNNkpwWVZyNHhGYUdvSTBCTkxiZ2dqSjJQVm9sWjB4DQprczNEbzE3c2JoTk5aZVVKcnR1OUw5SDExVzAzUUxXU01YRGhFdzV3a2haSUJ1dnlMWnNmamZZK2F1d2kNClZVN1ZyU0RyR3BQYTllNDBLd1YzK1NqMm1kWEpUbGZ5TXpXRGdjY0lQTkV2Qk45SUlpUWdHWGNRSEhPMg0KYTB1ZkFhQWFvR0Z4cExVd1JYdnlveExNYS9aeUttTXJFcUtMeERyME04NFI5N1FJQVRqVUU2aTZ6Ump4DQpTSnhNZzg2dzdKcm9Ub1V1S2NqRkNFYnRJbG1mWWNWd3JrOHZ4YWxsNTRKbytZQXJJY1lvam1IcWFVZGUNCm5vZEMzOEN0TWhQcytPWW5Ed0tRaGRzRk1wQnRCaUpURW5tNEMzcmpIOU11VzExS3ZQQkMwWk1ZQlFKVw0KNDdFR0U2NVZYWThZL3RwYzRQZUczVDFUaGN6RlNTcGtPZmhIM2J3d2VvNTAyYW9QVWZ2amt3SURaZXR5DQphY1NROWtwUXZ2SGJteHJFTFVscjZPMHNmalRIMHVDbFJpMWVlZmNKeDhWbmxlREd3cVBSNis4RlhFdzYNCjU1TXZvT21FVTVmQUhkKzJqZEhWMHo1L3ZaR1MraThXMGVkd3BjSjJMTnNUbk8raktLbFBrNENXcVU3Rg0KREtlMU16ZGRjc0pvZ3UyWmE2dTZGTXFPYzFRNlZhb0J5MWdZdm5DN1FOZjgvYUU0Q0FRMGRSWG9xSTd2DQpmbHp0WG1VOWswcnNzOUFRZVJrVE0vcTMwN1hydjZSOWtWeTNXMldGQjB0SjF5RHNUcktYcUZqYWNoYjkNCjdUWHBpWkFKNUpIaE1PTk5tUlhKUnFwdkxMREYxMW5Sc1dnUU5saXJmL2xNYWozcFVqVmJ1VnpwZ3loZg0KR0ErQkR0MHQ0ZDVvTVZhSStOQ0RaT09DTm1KcjlTUWMrMFRoVlg3Z1AzbC9tYlBvS29zYmtQQlp6WEgxDQpLVWRLYi9yc0VUdHdMQzZKK2RtNjM5TzNzR0pWUk8zZldVZlRCQzIyb1plRzlQR0VOVkVud1dZaHE1RWUNCmR2WDdxUmNhYVRYdnl6L2xUbzRsTFNNZWVZL21ucUJZY2JPd1IwRGhQNnkxOEpaZDBubmM0aGEvU2V5cg0KUVZ6WGZVZXVRTDRSOWprdUMwMTRpdkNxSmtTQ0V3aTBobEQxYnpTTnpjVzNXQldTNzZ0TDdFTWhzTURNDQoxY0laWGR5Z1pXMEtTOXRxb0czRmIrRFhzZmZWOWFWbGxvL2VXM2haZEFTMkQzVFhDWXNZK3JWTzl3bU8NClBzR2Z4b2lSa0hVQUwyNXJnNEdseTZLV1NJaUZKTG1wdW9kNjBjZ21kcHJPQXV6bDJSdGV1Z1hLVGI5Lw0KZHB5RzYvWkFpMlV5dE1NV1FVRE5rRWJxY2t5Ujg4ZURYOFRhTlZnajZaNE1VMjZXZWRvaVV2VjBqdTMzDQpONlQzQ0tMbkVBRjNMQnBYQ1NwbTlrRWk2TU8yWUp3SEdsUk9iUmRkYVB1T09iamRZSVgxNzI5bk9BRHQNCkh5b29YYzAxcjdSK2JxSStySGk5aHJuc0NoVnhrYVdyc0V5Y3hDWS9xVm1BWFlhMmFJV25FZTM4L3ZlaQ0KR1F2ZXFRSmlJODlVR3k1ZVlkdmk5MVdxV3BOKzlPVkZLRGVRVmdWRHpSRGltRDVHNkUvWG12SnZMbklrDQpST09GS2ZlaGtYQTc5b0s1TWRZbVcySkRNZXB2dHUvd3VsUExZVzRuaVdCRlV3RG9KRXpYbUFCeHkzZ04NCnVac1NvQjRGelBJalpaeEFkVng0bWRZU29lYmhyZ1Y3ZEt6NnpBbEJuazUvQ0E2R0FPUHhpK1pUWG04Yg0KcjNxNWI0SUVBYkZITjJ6TUpGaVFZbVBtTXl1aXVzQ1hwRDc5Ymh6OHhXaXcvWXNPU3ZzaGw2eGVFcURYDQpwRnR0SHdyWW8rVHlWUE5YbGZCZi9JSW1zZThlTGRPN3o5RnhxZC94UEhLNnRsQnBXVFBGYm5ZZVVwT2wNCk9oVG9iQXEzQVN5UmJ1VVFZZXQvZnU1ZzVZN3o4NTE2a3dEQkNRMFgrTHc2WktMUVdlZU05WG1IcHFxKw0KVDFIME5TODZRTlNUdEFHTGo2ZUMrRDZ6TVNIN3N3L2ZjRHZXTUNtZFFwNWcyNFhWQjBaT2J5WkRVTnQ5DQpOQ2lwN2EwR0ZGVm1sUWpzTzkzZDhwMVZMbUd0TWNrU0ZoTS9UUFVOMU5RbFpEWHFLRmROVlJGU0M3RWUNCnpJMEV5QjlEOERvMzRERTRkbFE4cDcweUw5d2Z2bExhQ3QrR2ZNUlVpbmNoc1QzV09IcGtpVklmcEx1bw0KeVZ5RkJKaWNrbWFLS2lrS2hNblByTTlIRVhySGxwWmxhdFJPTXZROVJZNjhQSmNDbEFzUE5hMkdyZk1kDQpDVFI4MkIyRThUeWRMSGs5akF4RkFUbkVVZllLRnZvU3dlYWMzUWpLcXZidDZ2aGJiMGxrSjB2TjUxeTINCnRwRnlLang3cHhBMnNTYm5pcGFpaFMyWVRldGZQYW85QkVVVmtXQ1prYVhRc0NSaGZ6OFZLK0gxVjdCNw0KdndLVDdFR2tVdjh0OGpEcllpbDNNRHFqb2JjdUFla0hKUTR5N0NnTDBsYXVVbkxnNnFCditnSnRkc2dmDQp6WmVzR2NoSmlnQkdhQnFPbGsrOU91OE1Gc29yZkFja2tPcTUxeS9pWUpGM3VDMXhEYjl5RFNJZTRkbW0NCkZibHNtbnlacC9va2tBYzBxRFQwVE01MUdVMHM1OWVjMUlncHh4dXFVaWZEZVc4NG5kME84YyswS0x3WQ0KREZQb2VxajZnWUNTQ0Z5ZmkxVHFjM0pJVUtpUm4vbnBuMnFRMmI0TG1jK3ZzSDlOb2d4a0g3RmZnOTVZDQpVMEpJQmFuY2Vxem9SSWhTMzlqbXlKT0ZLVVRkbVJtcGFNTmFnU3FITldoWW9xNE1uVXRmdkFiRFlqbmQNClhSYy83bVgvTFpEeGJ1SlhKWHF5YWxFVzhmNklmT01DSUpzT3dKRjZ6WkU3cEZxK2VPT05kbXBYUDgzYw0KSzZ6VmJJcjdrVXV2WWxJTFQ0OXlhcW9vM1Z1K3RwUU5rTkNFYUJuSUhMMlBodTI3dXFKNWh2ZVg3c0xvDQpQRVFnamIveUg2bHRqZ1hHemEwdy9nR3c5OTlXUDN1TDJ2bmw0RXBwKy9CdFlVM3hPOVZQdllNUzl6QkMNCjN3OUJWbUpnN1R2Y1hNTTBudEdxeW9oTUlSdU9XaVpBNVJhbjVNbVd6L1hpWkxTY2xvU3JDRWxRQzdwdQ0KYTgyMmloVE1kVW1GVDc0WU1nTHlZTnk4MXJPVFJxaFNjS2p6S1hGWHp1QndKNzFiQ2F2YjFYZWx2UW9EDQpiWXB1d1FWWlhBZ0ZsRGxJVmk5MWc3bWNKTGhxNXl1a1pEQXBqRTdkT3hnd2dSSFVPbS8vc3RSY0VzYjINCmtUS2t0YWU5djg2akJUbk5RMHNsYUpYNTRSTi9hYXFwTDA3ekVHNndmUkpOY1NmUktnL1VUZkkzOFR3OA0KbTRDSjU1a2hpRHc2OWFkRlZkMWRTL3V6UXZQYm1iTHlOa3hSem9wZ3JZR3ByY1VYUzdWZllHUmdNcm80DQpJS0o5Q21md3p5YkREWm5DWTRkVXhZV2pEcHcxZHF6bVBDVEY3S2J1QzFwVDlvaGF2R0xKaW54NkFRaGMNCm5aekgreXYzanVaaTZWY3hwa1lidUlLVElPRTBFZ3ZSZmRLK2RyK1FSZGtnUG1iMHlvSzlXUXB5dm1XZQ0KVFJkSUE3S1psdW80d05yTVVOem0vVWIwbndvSWM0UjBQM3BpTVR1cVlsa0xRUDNZVWhCWE1DRCtxVGJKDQpLcmkvY2tTY29XTDFjQVl0dU1GWCtYWURsQmRxVEdGSkQyNEdtamgyaGx2U3JTUXo3R2FjUS9TVVBSbTkNCkxjbmVEbWhKRTVhM1lGUXE1bzNVQ1ltWURvSm9NR2FENkVIbVFrMldzaGN6ZkRBTWVUMUp0d1RCTVo0bQ0KaVA2WkpnY3N1Uld5OFVwS1o3N3hpeXdxM1M5T3NDSkttMEdnK01odmVVSFI1S21oclphVk9YNlhhckY5DQorVFdRdjJtQVpiaDV0WWxwdU5sS2FxRXRXNEsrNUZSZzJoaEZqQ1U3ZjdSRW1FU1cray9yd1h3cCtVQkENCm1VRGFCWU5oN2FjbnpIMnAwLzFvTWE2ZXRmSnJpVlkvYk4xNDZYM0t1b3FMV0lGdTl3dFVwamI5VzlmUA0Kb285NjAwYVRvSWlOOVl1WURDRnlPVDlzZmNVUDN0V2lDVTNHMHFFc25OWUFLY2VpeWUrZHhYcEs1Z0UwDQozZ1NoTG9VTUFnTFJpYiszL1JXZ3dncEh3SFlUOGJ2Yi9tNC9QVlBwejZIa0EyNTF0c2E0ak5JSlhFc0INCjZuMHlTNlNBL0JnQnpJQVFsMGsxMDFab00xYWVHS0VxU1VTa2VPWlNGdFp3YzRxQzhqUC9DbVZLVmFTdA0KbGV2NHVmREhPZlBDcTVCV0NEUTNpVDBoY3dhdWR3MDFFTFBiM0pIeFkxZVc1NStBaVlCc2h5SXZLNTEzDQpJdy9MUUkrRktKdlBJNnRUZXR1Z212YUJmeUFhWlp4cVpROENtTy94aEhxRVZ2ZTRueTNnTGRucGI2MUQNCm9qTFhWR2E2ZnhicWc2dmk2Rjd3SkxCenRyN1BubCtLdk52ei96UzBKU2FhbVV0UFFMMitCUHQ5Q01mTg0KMmgzb2cvTnVEMy94ZUpkTVR0M0hhN2NrMVhmTUdRQ1N4Uk80SUp3dEtzK3dKWlFsQVlkeTRxejJuRU8yDQpuZldGVVkreXZyT2J6UU1VelNtUlVEejBpajdVL0NpTXRXK0Vlbit1dVBnYnFtQ3I4SUFmcTYvYmF6bWkNCmlkUmhSSXhQbXZucGJ2a3AzaDV3Vm44THdmdWRuejAzZVorNUQ2S2p6cEF1em53SzdqR1dZdGY0RTRCUw0KZHdHMmVqa0daQWdJcDZCcjRROGR4MG01dkFnMVd6aUhETHdZQW9DTXB1Wm5YS2VoVjVHVElTNDM4YWtmDQowekFhRFloZHFHaW9vcFdGQXBHYnhJU1FqM0p2djRQcTJHdmJ4UFRsdTJoNTNKSHpyRFJpM3l0RThXc3kNCm5nODFjK2pmeDlxZ0FQaGUxa1Y0b2JKYjNTZnhhWTJ3aXVHYWVzcWZROG9aVC91dU5abFdxRysyWFErQQ0KWm01UUs4aVF2K0N0ejRkUHBVZ2MySzVpemd0cE5xVTI3c0x4U2R0Uy9ycnRycVF1N0xiMkptcjJaQmVzDQpaOGl3SzdqTXJaVk41aFBsc1UwMDRlbmlhYzFnVVpxUDhlTGwrN1J2M0FPRFE5RGNjeERnMVg4WGRiZ3gNCmxhWEZLR1BDRno5RnZrREQvR3VsV2Z1Q0JBeXNXZlBGZ21kSFRid3JXWnNTdSsyUGs1TW50UTlvdEFmeg0KWnpRM1RBUnpGSlVPQXJYamV1WWIxdC9zYitNa2lTZGJrOWpwaUU2REV3YUpkcndhOXo3S0xjTVFGM05IDQpsOE1iaHNPRTl3V3kxUldxYUpmSEw0cFZqZmMrMnpWSjVnTlRxMThVMFZnbEVmS2JMRlZvVmZyRnFaZW0NCmk5T0JjWlU2QVp3ekc1WVNpbGkvV2pYYkNuQ0Flc1Rac0lSb2ZlZVFaSjRWVE0rblludGN3TTRNOWtyLw0KL0lQczMyYjBsM25DakNKSmdkUlhLVThPVVBHNW8vN3pOQndWdFY5c3c4b0NmMWJVTFRWTTlvMHAvYllmDQpXY1dmN3dFa29pRnVuWkpEYXpYNEdGbXhFdzlOdUFKbGZNbUlxT05EaEdLZ2RXbEkzV3JaMWZsb1M2em8NCmtjQ29hNys5OHN4N1NYZ1BNZ1ZzNUpScFBZRzRFQnB2Qjk4QzBHSCs4cVg5NkEzWnd2NHk1TlZxWS9Hcw0KaTNQQll1OEkzdm9XNnFXMWRzb3pQVEV2M2xnWnZlOTdRQ28vYnFBYWhhQ0tLOEpzSGtsajc3YnQ4d2ZiDQpsVTF5WU5vdWlmRS9mdG5mT1dtUmhFVVV2MzhrUndteXd5NmxKb1JPbmF0UllUNlRiUkk0aWlOTGxpdEkNClQwQWxDb0wvWWJUV0UvS2h3RllwYmNpZUhWTHF5eEx6Rlh1djQ0ZXpPQ05oWTJmbG9SSnRGRmdlajlMcA0KcUJjcGNyYktZb2ZnbkdzT1FSY2tmOTJ3SjVqZkV4NWxpQWcybUxmZjVyN3l0aGZsS2NrR1QxTDAweU1jDQpjM3JzRTIrK2lvcFZrN2s4Mit2SlUwRm04RzJXWVJYOGFuVHNtcnYzdjhsYlJ3TVhFaW5TQ2FNdEkvVzcNCm10ZE93L1J0Q2lIdXNHTkRRWW11b2Uvemt3MUxoVHlOSXU2ZlBNVVRDSWRMRVBKc2NSQlRldHBVOEMxRQ0Ka3pIL3hwenh5b3Y4MDRHRkJORjFET05qOXhQSzdCaUYvNm1yTFpmVjhzR3VkOGkyU1JzUHFkcDJraWM1DQpoR3dOOWt0MWIzZFM4WVNJemNtNVhCSjRNSEM1Q2cwTmhBNWgyWFV6QTlOTEN0Mkk2SVZMckdXbkdqMUYNClBDRHVKSHlHd09tb1ZQVXlsa0Mydm9UVjFraXozYXRGelRyZUUzTUxXbDhnQS8wZUJKbXZjN1lCWDNGcw0KbGpnQm01cE5PK3Y2c25Fb2dEYWVOS0xkaTdlbVNsSitpSG1rakIzdUhyTThadmEvUDFsWVhlMXdIbmxpDQpSOHJuVjEwSVN6N3lTVDh6K1VoblNiNEdqT3ZGTUd5MUppU2dYQ2hhYnAwY0phQkg4SktGVk9uTGkxWkoNCmVqdTJHVytTMUJmaHJoc3JqMzZuQ1JTbVlscUFBU0pRRWtFYlBZRVB6d3dlUUlDSHdPMXNyV24xYStZdw0KQk5xZ1kwRG1xTnoxUU91WjdBemZ4OERhUDJwakRYV3pMOWc3bS96OHFCOHFrN1IyRlI0dksweTBQZGJzDQpQTFJjNmFGdU13U3pJaGhQRlJSZkdFT3d1Smhnd0NzWUptSllGYm9HYWJjbytCM3RkR1ZpMnVQVC9YTHoNCjIrRGRDSjh0NThETXJIc0haTjY1TVJIRzEvZjk3ZEJHUDBnVXpGSmdLTDIvR2hKbEQ0WEtzY1hGVmZjTw0KbDNzQzV1dHFabDdiL2VyVkwzV2tGMTVmUnp3T3VhbXJsdHo3NlNnTE1JZExVZEZLV0tIcElOUm1tSUtjDQo4Z1ZNY3M2WGdVVmtxN2o1TnlXUDZrakFlUEFHU0V4d3VvcldXWjFCSHJPY2Q1elJ5cXBkZEpsa2dYcHQNClN5NlNZQzlnZFM3cVFqL2hNUWM4MHR6d3QxWGcrQjlPb25ROGZ4VXBOM3E2b0JHZHpLbGo0blRGRk15dw0KTGFZR3ZrVTN5YVNJOVkyLzJQRURtMzNEY2xWWUVyNVhueElMQnRrOG5ZUTZPbkExN3NTNjJIOXFtYTNrDQoyaEJKU1FGc0pBa0VhS3BYbnpqMUdIQ1JIMkxWM3pTV1FvbzJDbWRNZ1A4QWVIazdCNWNGZVI4Vk5DVkwNCnhiZUhaMml5ak0vM09GSUVBanN4N1ljQXpEK2Q4TXIvakwvd0twUXlWR0hDOTdkNEJWUisrRDhoT2kzVA0KMGFJQU1Rd25BTERHS1cyM0JDNjdhNlQxak9CaUE5TVBDenFzNXRRTEIvMnpHeUhReXc3cGNDdWozVzhiDQo5NkdPS2hQQVJmT09VYVc1aEZuQ1hwa1NqcTNSMlA2cEFLdEpkaDhINzFPM2NxRXJxaG0zdXFpUVl0RUoNCkRTYjA1VnN6Z0dVUlJFSGhncnZQU0xJbDBhNVpsUmNseTRUTGVIZGdBL0xyZTFFNlZpN2dDVHA0c1Bjaw0KQ2t2eHFucTB0YUZDWVRhSUNZVEJvcmFuckZ4cGltQWw4TU90dWJhYWloYjdpQUVBeHBMd3FWTi9DOG45DQpCeGN2RWk3NzZkb25qVDAreC9XWU1rdHpDZXAxUGhzanZiTXZPcWs3K2tHc3RLRnQzaG15ZkEvbWVROVYNCmhIdFV5bTJjNndXQU92YjduZHhTUkthV0RBRzgySTBVQ2FxbTRwQjJ5Sk4zTnNJV2o3QzlvNXdybXY3bQ0KcURLVEIvbXVRTS9wMkRwWThkRm5vSHhKbS9sSzNaT1RocTcrU1M0YWlTOWF0R2dHWlFRVG5LaDRqamQvDQpocEJ1LzVRb3l5M1JCckF4NDdBdzlaZmZ4UUw2NkxDb1M0NWdxSVl1KzdtNkVVcHF3MXpRaCtiL2dLZmINCnkyZ3EwLzF0ZFU4dnJZRElLSzBsa2MzSGdVZE40Zzk5SytqU2F6U3U0Wk4zYXVUYlpHT250dlFDTWhkMA0KQi96L0NyVE85NDBZalNjSEhudHQ1NEErcTZDMUN6Vkc5U2c4eFNudkFVV1g2cUJWUW5LWkd4cmMvbWdtDQpCNUd5aUNyaFZHRU02bVRZcjhtbjYrWG5jQm5pZXVmTFBudGN3SWZjWTZ5K00xbUZUMStaS3Q0WXZaRG8NCmlkZ0RiZkhXYnVSMEVwNUVCRVlpcFl0Z2N3VU45VEZkM3RyeEZ4dXFxNCtYY0JmaGxKb3VUUWFjVk9iYQ0KT2JtME5aMUhadHcydWFaYzluSmtobXdwNUE2THJyRTcrZDhlR2ZkZDAxWWJwWTZHRitKZm40TWliTjduDQpPak5WLzkzWE1WRmdSYkNCbXBFRVdxRXBBbXpzY0IrbXhrNmkwVGkzVkltS2srdGN6UDVucitqOGVxVjUNCkhPd21CY25UYnVNQkRtYkdKcXVJNmIyblBwclhtTm9pWnJrbjJTNkFOc2F0Y0NnTzBjVm13dU1MSU1rUg0KeWh6Z21IS0JmWlhBOE93M25WZ3BqSUlDcVhndXFYRmpMb3VkNVRob1ozMkdmUHovaFRXeEFueUpsRFl2DQpRQVNGSE55U2lJbTVlVjRRbkhnV1pOcHNpMno4S0ZENW5SaDY0SHMvQlA2cTNzZHV3ZTlMTDRCOVZETCsNCjBmcGdWKzM2dTB4UkVvNEQ3ampEQXphc2tsQ3B2d2NFRjUrMVpqMFFIQjBNVkMzV2c4WCtUYWpybGNQTQ0KdU13NFRMbTFFVm92OTd2eXVYQml3YkF4WEtmWG9PSm5VRWE4UXNFNytBOXo1OGVOd0pvK21zQXRwS2RODQpSM3JpREFEZlhQTnN2bEZoaDJSKzZzWkhGQTdQanR4b2h1VTBHQUtCOEYwR3E1K3FxZ0xPTHNkYXhSQTYNCmFSWGhRYjFxVGVnZDBiL1p2ZVJLWlhQbDJzak5tRXlNQmdTNmFJTmprTTNpZ3hKYytYSmV4Q2tWWVFaaQ0Ka2xsTlBFeDBmNUV4VGUzalpMY2k4US94M0ZaY1FxOFp2ZHNlOUVMN2g2VTFpSkloME9tdVp1cVZwRjJrDQpUK0RlLzV0UElCTUFlQlU0Qk5uUEZBUlRDMWhCT2oxWmNQb0NOcHdQa0xoUU5lRG1qNU1nbFhkbHdhYW0NCmI4T05GRGg0SWpJYnhPU0JFVWprbXpUczhTSTRRcTA4VEhkakZPR0ptSzNTSElFUGo5Uk1TdlB6cWphUQ0KSG42ekp0T3h5aXV6TSsxMGttR1o2NDdNRTBkaFpjM3RNZEZFUVFpb0R2Z1FROCtrY3d2ZzQ2UHZUTFRNDQpjTTh6cXMrWVdSSWhvaGdMYW9EMGVTbXU3ZXViZDBUZE14ZWNsSGgvdU1jOFE4SGFCVjdYVDNnNTBubHENCjNJSlMxUDFoNlFPZm56bENtWnVyZXJnQXFWcnN5RzBoMFR2VnNkUWl6S3ltcDFiNHN4aU1lVnhKOXY3bA0KVEpGTlh4MUhhYTE2N001UWFXSm90ellpUkdZTFlaMFhLdlpUUFJSeU5PdUo4eStGNitPM21jVzh2RlBEDQpzZDY2dkk3V0xlQUxJdE9pSERrSXVxWWRHeFBObFVLanI2STV3NklwZThVTUE2VTc0TE03TkUzUmY0WXUNCnBzSFV2V3JzcEZOdkpaVjA5cVZWVkw5Mkl2bCtES1pIYVByWTBuMERpa2srL25FZkxwanlicHVlUzhMSQ0KTjNZYW1FV0pkQWJUQW1JWHZPNGxxc1VNaGhLMlR6bTlzRGF0ZGFSQzRvNDlpanJpNFFZQ1UxYVIzaTZ3DQplQjZUd0RqNURURVo4RGxXakZodllKNlF3QkNqZE5Jay9NUXZjTXd3TERXWHN2dzIvMDhRNW1XWSt0NmUNCnNpMHhuZXlBdXlqZDNwMGh2aVV2MmJMWlJRVXd6VXhta3VoUldXZCt5TUl2dHlwbjE3VFRDbkJlc3oyMQ0KZWNTMm91WW5aMXRIMm9nUUgyOTg2MVFObjRIQmxFNlVNNWtLc1lDbmtpRTV5MkYyZE9HekJiZ2NlOHhYDQpub0VLditlSkx2K1VoZVVoUlM0TlAyaUdzcW9vS3hobzJGSGZYemF6S0hnUDVnYXJoUEJmVndXLzNwM1kNCllRbkwvUUtuejkwTk5vekgwYzkxVlkyOWd0ejJFK21iR2pwTmdIVGlsTEtqV3ExdHEvQmFxTmRhRitzUA0KU1V5KzhxRXR6TTBzdHBkUU9qUXJBazg5cXpjcEliTGNWMHZYdHljR3NGUkhDOEZ4NVJ1dlVtbktGL0h6DQp6MGQ0a3lHVHZrUTh4MEZTYjQxMTVVeUhPNmpucWRnWW16amZNZ0Q1Tmh5dm43QnZBZGNhdUFFdXQrdXUNCmRHQUZaMVc2TFRubFpIeGhWcHlDWlZhQms1SmRxUTVvTExRd2ZiT1FnbGpwU2M1TFVMYTE2aDE4VEFDYg0KWmNadHFwYXBMemttZFo3SGoxb3ZWaVd6dzN6QkJQcThDd0V1YWtIRlgrWXE2Si9Tb2dETk1ERWNUM0NLDQo2ZHNmZkpaV3AvY0dzZEZBVUdvUmI4THVqZnJsVGFiWEFybjRQcjUzSzdXbDZ0MEhwUWIzZGU4Y0c4RnoNCnRQV1g0bW5jRnJFMWl0L1FmcUkzYUhqK2g0SnEzYzRYbWwvUnRMYVhzS3NWU3gzUG5UTDFhU3B4SDU4Zg0Kb1RhMkxsK0t0QkNiSndCRmpNSUp5Qkw3MGJDMmV6RkZCb0N0NE5LMXpialphYVpqYmg2SFBxZzhLRUx6DQpveW9YY0JVSnhseGhSZmswSHFISE53eDNVQkFUbFc0RTFnd2xyb1RrNEs1V0pDeDh1UkZKaXRuN1FJVjcNCnpyZGdvVS9KaERYdnd1RElMa0JHOHBxM3FtcDRIQ3MxUkd5UDEvSlpZL3I4azR4d0VETG5qTVErazZobg0KZ0psRDNEcEtRamNZQytkTWlSK2wvSjlTbFA1K1BNRDBvbUQ1QWx6V015RWpheEdyM1ZnZzc2M3lJSTdVDQpSMWFnK0dYMTZPZk80Q004YllwL0xhYkJvYjNoV2x5M0gvSDltYkt1VTVPN2d2am5zVitMMHBWdTkxQzINCkNKVUsyYmRCRkNqeWhKWkVzczArakhCTG5MYzN6Y3RjM2dJc05WSEtjcmpGUnh1L0hxRU1UMjdGc0gyVw0KdFdhcU54Mk1uVDRqeWRkYThNZ1Z6OUpUNFcvMmtJN1A5d1RIY0d5NjNYZHpCVG5mN0FPUFNFeGI5eG4vDQplRjZhdFJ0RGR6NXErNjdGNGRobUxIcU9BdWhPQ0YrajlFVXNzanlwbzZpTVJFWW1XL2NwYjNVdkphZzcNClRKQllJL3lqTFI3cDlVcVdWa0pXQ0RoREV1ZWw1QWE4NTdOekdNTVRuaEQ3NnpvU1FWWVZodnM4RDJxeg0KS0hPYmpERjgyTXkxV2prTzJzL3ZlNkd3YXZ4SEpEYkt4ekpsY2IyWllpUXQ0SjIraDdLamQ3NHpyaHV4DQo0UVI1dmIrN0YvbHFsY3N0a3V5YlNEQmFhVTMwd1hjeitEamd3cC81RFlOeThrVGJTREdLaXRxRmliRmcNCkZRYVZySHhNMDUxdnlZRm8yQ1BKU1dYR1FvZGlQT2c2eUpJSDZ6SjAyTHRWN2ZUZWM4YjBRZE5QakU4Mg0KRWZuTm1zUHZxT2RqcW42YzBPWlBtcmRsaWsvSEp5Z3VrYUJPajEyc0luNjNLWEZXb1lnc0M5NGx3MkN3DQp5YjdEQmxLNFg0Y3g0SmRxUTFSQUhGSUg0TDdUWkhRRFZWUDRuWkNNckRQb2RXRGNHN0F5Rzg4bVFZWXENClRIck1oRGcyOGtSWjJOd0FWbzRtZ0dnQVRzSkJTVGJYZG1DTXBxc3B3NFNDWnJpaWdPaVpBYUFzVTkwQQ0KczBWWk9OKzVXeTIyMmkyc1pFY1RXanF3NHVJWlZNSGVCZXE3Q1RlK1V4ZVBUWjFwbjJ6UFh2c3ZCREhPDQp0Z2QrbVFwTmVLL2dXWUVVOWNYVmViU1dKSXNqOEREQ0Yzc1JlMzFtRURRWjFmcXhvUU9ScFJ4ejhacFANClJnWGl1c1Z6T3I0WmJQV2R4MlVqK0p1cXYrZmlqbitEUWk0R1VBVmYwSS83SEZHMXBSOThRTjVYVnlJbA0KMVhFQ0NvNHE5dWh6RGh0VVhpNFBFU215b0ZWaXhLL0VjSlYwZGMyTEVEMFNRVFVRaFk0a2lvWXBZRENlDQpHc2tvOTFvMnppRnEramFMWEhCRWl0bWFhU05LZE9iT1VTajJheWsrTVExY0dwU0pyQ3pYSHZUMVFmd2QNCm1PR2xXTFlWZ2NNbSsyZGhhYUpPc3RtSUZFWTBVYXpXbFIrUy8vUDNoaTFUYlB2dnFCbGdaSitRUkhNRg0KWDhjNVlrbVdRNkxiUndFbXNxSWE0cG5vVjY4YWNqWEE4N3J6Ujk5T25uYzcyVmJBV2FLcDJoS1JZN245DQpraHFOQ0lJcEwyNUZJVityMzNzeUlHdHpXZm16VWdhZGtWUWt0dTVzVUE2dXlmZ0IyN3hWMzg0ZlNtajMNCkZGQlRydU9ENG56WFBhem0yV3I1U0RmTk0xaDh0cE5XWGx1Y3BOd1poN1FYZytOWkJqQVV6TFRjUGxEaQ0KQXBTME5PTGVkVE9pZmlib1Voc3lma2QvV2ZiZFZkV1lzZW03bitsT1ZjbXdrV1cyZFdsWTVnb3F0SXk0DQpEL2QyNEo1cXRuMkYzbHJaaWVKaS9RQ3FEaE5rbHMvWi9sYkEwOUJyem5abHVsNHlaa1M1QkluTkF4RmoNCkduTEFnRHRJRjFqejNBeWpmVHZ1TVNJenZaVjdRWnlYT1huQlU5U01MS0NFQWlFTHUvTWNmRW5JZXpwZw0Kdm9sRnQ3Qm9VODBzRFVicENTNzFyTlhQMEVMSExyV0lVV1Y4K3k2TEpkb21rQzRIWVA4YlNma004c1YrDQpqWUxKZENTdWVma0hHb2RtM3J2Q3ErTW9vc0x4KzFhdEUyWEJPV2pDM1UrWTNobHpyQWV6QjVta215SXANCnhTSlpLTDR4R0c3Q2d1T2puTzdpTFB6UlRnK2dhZS9kaGRQdHZnckFBMlNGNC9aMFQzQjNZWTN6UTdTQg0KVkpINXFyZ0VPNnh5MWFwRC9qandZQjdMd2NjTi85ZTJpQjhBOE95YlNqTmQweENBT255SDBvbm1nVkdDDQpIU1UzOWgvL1hrWGV5THVxYVJ6VTFBYU8weU1hRXkvSk5rUFB2cHNKMnFPK3VsdnpaVWlzOXFwSGFWLy8NCmlXRDU3bE0rVHdwZE5SS0p0K3BrNkgvNFlLcTRTSmMwQjNTRHN1dG1BV0NwanZQcWpWK2pWbXhHV0FzSA0KdkpYdnFHTUdiL0wybFBzYzZuMjFLcFVRNEFNSWpLY0NvZUM0MDN2bzZheUwyMDhpMjJtbkdZQmNheDdoDQpycTRZTTNLekpxVHhEeEU2akRuN25jUm9Ta1h1dWprc2swWXRqOEVDMjJnbjg2ZFdCMVQ3ZkhFa2UzTHoNCjJBMm1TQXRRcG83bFQ3SUtPSmpVMjBZWU5idVBNZHlZVnljQ0hIZHBXMDl4U0R0eFN1UTFUSmplQUx5Zw0KVHlpb2ZyU0JNSHdIekhrUHpjRlNYalgycjNwMUk1VTJPeGtsOEVNNG9JNkZXZWljQ0NUdGNMZllJNjhUDQovMnpobjJvMkx4bFNnK1M5NHhzVXltU29BQndWMTRUbDRxc1RIR0k2TXpqcE44S0N2YnJBaUtDZ0ZDY0cNCkdPd201YU9zSUhFRmZWR2RudENPcG01Vmp1NUZubnhDT0tGSVhjWDFNKzZPVzRXc1FIdWJxUDNZWjIvMQ0KQzFjWlp4UmttUkJHd1p3WlJIZlc5OXNFeHB6aHhnYmtDMXhTQU1SOWt5SG1lbFlGb1hVUXpWcjZNdHJGDQpMa0V1OXpxS0VnU2g3Q3NoQnlwOWxoSG9zcHFjNkRPMUN0eW9ENlhxQXY4Q09Ob3NOMnhqcUprUERITUENCjNXV3lGZGM3S2FaSGlsVmV3cWdGWUozdXQwMVRTRTN0TUp0Yy9uZ2cvUS9wc3pTam5SZjNjN3hycXVFMw0KS2VnRzl6OGRWQ1hmVVFEWHRvMVo4SHF4T0FrTzRIWnBxbkFrWHBxRk5QTlZMdDBtRkRZMEJWNlZRTGYvDQpMbERVa1R4czRnbjNpd2R2bEQzdmRNc1NCWnFnMXhKTmIwVS94K014N2I1VTViTTV5OXY3a0RweWpqazENCjN2WUtUWGl3QmhNRXRjN0VBTnVpUDVjU1hDWDBKbUFMRHNLdHJ4WFNSSnlud2JNMDQ2eVhXdUVWM3M5Ug0KZ1JXa1A1aS9JUktsMTRTOHFCTkE2bHJVQWh4WnN2TEI1MFc0bmMzZEs5M3RHcHZ1Ykd3WllxSUZCSUNzDQo0bEJYVDZ1MDlRb1E0YlpQNmpoZnhyL3FncmhEN3ZQMGRhNk1YVVFrVlNNQkhwVmducldtdDZyTENFVFoNCjJua0dXaGtpYjdNbGNUb3NhaDJWeWRmeFU4RnVlcS83SE01Q3VVUlJoV3pJQWhvSElpdGJBMGY4Q1VaQQ0KcUZWYnVJcFBpTXh6UXB5WldJOXpvbXFCVytzTU9UZDN3T3B2QmtvQzRSMVhEMjlhaFF6cjJVeHlYTzRZDQorWHhFUlJlN3dERmpJWkxYbXJYeUdJZS9wK0k5UVdDMlYramdlY3dGbXExNmlDWklTVktwUDFQbFRJUXcNCnVDWE9BTTdwUGw0OHl0V2JpTU1hbDkwZjFDeHBHZzFxY0ZBRmw1MXJkZGtEQXF2dXZINmtGb2NQWEQ0Ug0KOHFGTWhKb2VUdE9pTXZRWTIrVmhOa0VESWF4cm5venQ0eDByOXhSN3lBZFlmSytFL2FvTlEyd0RoY1liDQoyVnd4YlBqMEZPM2o4c2lIUFA4bkRLYnlsZXhQUXFZUDluZW9ycmVxcWwzV29qV05TYzRxRVFKMCtZR3INCnFrRE0xb2RzTWpPWENWdjVvRndBOGNOeG5YQjM4MzkrZlRGdEhjQ0VmZXRadGJteWNkU28xVk9LeXZIVg0KM0ttWWljdGRPSzZ4ODNTK0FvWmtCWjZENWwrdDJrTlB0MkJCNCtxOUhwZjBoNXdnaGxoMm5ET2ZyeDkrDQoxb1hySklwc0RwQ2lBOFFha3QvSlNDOVBxdnpKY0VhV2RyMmVBRzhUeHpzNTErTUtXZWwyQmRlT3VqOTANCldYUTdFNHNERVZNdWRKUWIvM1BiMm5wcXBLWmQ1Y1FPUVJPbVFlYUtqMjFVOEt6R0lWSXI0bm82R1EveQ0KZ3B3TGFrYkZraTVOdXJEbVllc2sxS0pYMExFS3lBV2c5d2tkbDBlR01kOTdKNThEVkFta1FMQmt5M09WDQpGZmw2TlVET3dibVZOeTJIcDNDRkZRWmx2SnQrT3ltNjh5RnJMTHhrNEVTNVU2ZTRSTDhlZC82YTVoYVQNClRCYmhoRVMwZWpGbWxNUW5tMy9qMHhWSWtLeDRmTjdRSXJmZGRUYUtBWkMyWDY1c2tQa3p2QUNyZGtJdQ0KMXo3ZC9sUDV2MWltOTJUL2RjeEZ5c1cxYkJWa0ZmWmIvdGpKUU5oa1NHQ1ZkOVFveVdqV2gvRXJ5NlJWDQpXVlpQM1h4UDBUWVF0enZqZ0t3cVBKZEhYbFFZQXJzcWdNbmEwNXNmY2piN3hWVXhnWHpNK0tBd0g0UkENCi9ObjBjdUVxUFZNR2V3QlhPK21kclBIUDJIa2U0N1lDcFEyQ1JPdTY1c25QL3pjemM4Lzh3TENRU2JkVw0KVFRSNnRPS2VxR3h4VGcySHhldXN3NzZVdTA2c1Y0VFhYODl2OFFrUmNxbC94aXJaZ2g3QVVheEs2UWp3DQpjeWRWQUJzQmt4cW1VK09BUWFuc2RXUlRmcytzSUxIMGwwbnFwdWI1VGFPYnJjSFhPOVJ6eitjamVTWGgNCkMram9TMXdTN3ppb2lSdGpNcTRjdlNWLzZXNTRnS09EN3FBSFlqdm04ZUI1VDNNUUZPbUdjNU03YWlGbQ0KUmkzMUxqaVVGa1UzQmloczYvRWc1UDFjV0daZVFZQ3oyMFRkQnBLTzRQOGZ4cUtoUklzMkF6UzZvWlFTDQowRWRDdE5HTjRUS2xkWWJNTDNzMEVhNVVMK29NcUVrSE1KbW1YYjNhSFp4V1ZXWnBiOC9EL3d5WnZ2MGsNCkd1YTNsT1VJT0YxbjBpdHZ6UG41K2RIMXkyVUcxTlNQRUZwenVDaWpnRm41cTVXMGdwVThiS29icVFqdw0KckhVRDVKN04zeHFkcEYxOXQ1L1ZNa3ordjQ0TXhnbVIwb3BJd3VGRU5EOW5jWk9pWG1VNWdCM2E0YzRlDQpjU0dGL0VYUTRWeHhmems1Zy9MMVBWSWVsRlBXRWtGNDJiakRqaENQU3RTTXR6SVg1L3VTZlB6eWVwYkwNCmd5VUNySmxqeU83VGhHRUtOVDZOdmlINFNWTDV3WjB1dFBUYm9HMVh3akhPMnpxVXlaeUNqd2VnNnh0SQ0KcHJqWlFmL29pNmhYcGZpZ0l1R1hBVkMzVzducjByVlJONVhpZTNWdzBhZnpnT0ppY1BCcEY4ajVBNDM3DQpjN3RGaTdhc3RVWEk3eGtqdlNFOXBpdzlxaUl4MWU3LzBuL0V2V1MvWWRRWVJkMkNWemZKRDZhZmNHR2wNCnI5OVR3dWdzNlRTeERxME5JUnY0RHI4cWlkSXJXQTFVZEZUbnBWcEozTlpDdEZaRVNONUJTVlVCTGZkNw0KSXJVRFdIOWhaaTBJdTgvWGdGcERaa0pJL3ZpNkM5VURGMjJHZGZBd3pjMW5YUTgwZGlWdGxtaWUxODBBDQo0WXk5Tnh0TVlQM1ludVV6Q2ZCRlgyZE9oWE9IZGV1T0NjR1hGeGN3TXE2UXZaYWlyQUdnaXpNbENiTGMNCko1anYyVytDNEp3SGtyWVRjcWJpZ2NXT1JDd0RJTVV3bzJhY1N3N1RvZGpnaDZjdnhnZW9yRkZlUkdYSQ0KanBPTGI3aUJwdzBXSkNJNFNqNUFRbnk4UTRzazdvalFmU29DZVdlUktldURvYUZTTStDTVgwZkQ2b0E3DQorV3RIaFZkNDFiMTUrZmJvUWVZNjQ0RkpXSmcyWGRTYmxacWJvQ1hvc2k2NWxYeFc4Z0hvSzBIV2RBUEENClgvTFFhMFR4N2F0VllOanFjZUk2dlpXR3VkaHJnN0l5OW11UE94SDBkckdNNWs4K2N0eWlacjM3azNuMw0KK1pOeTh4Zm9RbVJ6TzVmdy9waWR0blNsWm03MHVJN3JSdGxUdkhIbXEybFlJK1g4QXcwc3BydTdTR09QDQpaYlBBbjZoVkZCTmVOMlA3RDQ2T0lEMERKZThrd1ZRbXphTmF3T1BQbzlISWEvaS9oT0FYN2xNVDlSNVcNClZ1aDlOOGpuRGZWMWo4bFJ5azQ3d2hHTVMzeXRZQTluRlFWb2xlUEhzdldNejVuSkluVXlUOUVsR0lRNA0KdWMzclBTNmJ5NzlqbTRSME9oWlNMa3BTMEhEaHBadk1NeVVmeUMwM1pmM2NHc0Fnb1JOTVhoVHltU3V4DQpCY2ZwcWVUbHJkV0wxRDhMU0J6Mi9peFUvUzZxUmhSOXUvOU9FVGtNaFN4QzdLNkVCMW1UczJlYXZQY04NCjZVTkhRTVU1SXk1Ym1jWGwrZmFGSit3RjJLSWFZbUs1TTlSbDlEd2c2RGs5Z25PK1hxbE4rVnExeEtDOQ0KSHN4dDlkdng1UFBMeFdUbTFWUE9OSndrUTBIMFd2WDFRbUlLZlBUcjNlbUpyNW9rb1R0Y1RWc3BMbFpCDQoyQ1FzRzVqaDNKL2htSUtjV3JMS1JJQTVoQjRCNmVrbUF2K0pMNHV2a2YvTmdsbG1GTjdtUTdsOWFLcVENCmwrOFJPcU5NRlRNbTMvRjJxM3BJT2tWVFlRYVo5ckNIR3l6cUpvVUVJRWkwZWdsVUxlZThTaTM2KzFUdg0KR1pzM1RmVDdwN0dNMDNPT0NrOU5yOG5sUjNrWXNoZTA0NHdkMXZWdk5zRVJKckNIbTNVOUtGZ0FZNzRtDQpVMkZWcTRVYldWR3h6bmdvd3JidFBMVFBxSDV6MmJiZlhtSHJYa3lXbGdZVitBMmh1SVAzQ1J6L0llY0YNClR5RTlmeWN0YzlKOU93MWVSZUhoQXQ4ZXFvS1ZRNmNlRFpIRTBGVm5LTmZZRTJhVTRWV1psaWtKTXNvNA0Kc3hHUmIwMUdiam9WM1dvTWl1UzgyTjE1YWkvU0N6WSs5aC9iRUpLemdxZ2RFRmw3NDN5Yk9KVFBJbEVHDQpBVHZMRFp3UFhhbmxRVXlzNU5GWXdzWC96QWs3OEJzQnFNYnlqNXIycW5ieFlXalZyTExCbFhzU0ZhaVENCmU4Z01SczNGdlNxVDA0TmV0bnZhejcvakhmbXdYNXM3NXFSZ2laOU53L2MrU0orRDZTNHI1UkdtZndDNg0KTGw2bjQvZzJZRUFkYlVQUXdQSzNuK0RqQTRMSzNpakNKVXV5VmplSk1jWHlkTmRQeitoWWVJWktiY1ZHDQp4QStwRGdwSUZhZXdsS21pZ1krTFplOE03QmJmWTRtNFplOXhFa2hpNkkwVnNubEpyTDlPeVF5Vmw0VmUNCkU5MzFKV1R4YnRTcVZtWFA0RHFqUUgvd0RGYlp3cUtQYnNGK2lMR3dJcVo1V3FMSTdGcTQ1S3htdkJJaA0KdnRhZHl6ditKblA0ZVJSNStIdVMyT0JydWNJOU5wQjV1STEvZEQ3UlNYQjlFUzlUTmtteGFkcHlYM1dBDQprVVBHNUlYTFQ0c05JMXY4OXVvV2N3TDFMTEVFRDJ5OUxxM1h4VTVjWS9KcjVCcHRZNGdsaklhRWRURTYNCnNaZTF4N3FLTWRpTndHZVR2UmhrakJWVGFjSkE5ZWFFQ0xqME84SHU4cFhDWUFDdnBnTElFYmxDL0NQeg0KRnR3ZzVwQU5yUkNYdUUrVnZvNUx0WDBBR3pFS3U2MHR0eGMxdktXSURZa3Q2Snh6a25PamxTaEJyNHpkDQpSRWJreVNzTlVvZlhya1hnUHQvWjJONzZFUTQxOHF1RU5QTnh6STBieUUxV3VHWjRBeXIwcE92MXhDcE0NCldSN0k2elJnVEQ0Y3dhNEduZitTUWpaaC9mMUw2ZjhpR0JKc3VMSWhSVDNsMU5sMTRSVExZWmcxdjh3TA0KTVNZTVVjY3ViNWduWVlFZWp4NzFpa1hqMU43K1BmdWEzYXEvUlR1WWNUelNlNUpjdlc1TmVlZVRNd0NsDQp3TWpFQlVGOUVGakpIMm9JUS92VC9tVHZvK3Y5MEhWdS9PdE5ObWllMmFqcldsRkhaSzRoUHU1RVVaN3INCkgwVVpObXloNFRNeStMa0VnaTIxMEx0dWVVVXcycXAzWnAxaElqdUordnNGdHZKZCtqRFlVYURrK3pQRw0KbFJVRkdoaDg3VlV2eEpTNG8rcXlUbE1JRDVkd0RFc29BWUMwT1RMeGw2RDFMN2laODBRKzVPODNVcVRCDQpIREowNG1KaW42MHBhSjJoQ1h2dmEwa2VPN3dLN1MvMlN4aHhhaVJKbHA3T0JwRHltQklsUFNyNXV2RmkNCkQvNVA3OXVJQ1RIbWhHdkZTT3llK3kweEY1V21LVVZBOExEZFZ4eDhZUHd6S0V0YXByaVZHVjUxN0RTcA0KL050MFdTWC9rU1p6SEI5Tms5aUxiYjhLU3VQWElVTnhCK0I2djRuc0YyVXlueDhRRVBVa2hVMWk4WE8yDQpTbS9VRmxTekxPZFR6b2ZTM0lIM1VxSkljYmU0Vkdtc2RXeVlvUVBBalUwNU55dTdQUjRIS0RvcFBIUmUNCmdjQ0VDVkJWaVdZMWhvZmd4aHdKRmw2TGQyNlpkcUZoc1F3dXUrcFlHcWdVNVVqUDM0bTZHNFBuTTdMaA0KZEkzOUs0ZlVCcHBMbm1abWQzTks3azFVVkJyRndvdzBsdXJWdHY5b2x2aGNTZUdmM0o4T1NUd0dsK3VDDQpJRVJQWFZSSVpqQTlTb0JIbVRsOEdWOGFXU0xyUjhuYnUrYUNPdVRWZ0pTalFaMytOaE0wR0ppbjZBdGkNCjRqL3ZHK0lnclVYVG9qS0RmTHR2K2g0bFZaN3k5SEtvaVlydUluUVd0SU56djBaWXZYaG1xM2ErdFlwRw0KdHdtMS9aK1BhV0hHUDRCZ1ZFNmFjY0s0MXRmaFBvYjUwSnYxNHZQWFQxZUM1bDhVWXNnVVQ2TlhPdWxIDQo5WDN0cHVwblN1ZE5kbnVRRWtRSTlMam1JMlhRbWVNTVFRa2tNbFdZN2JqOGZUVks3eXVFeDVKYVhIdysNCkJHMm1Ed3NKUmpXMEFkOFVLR3pBMTBQemMzYm9NRGZUUlpDVXZtQ1hvTVNQMzNLYlJWUUZwNWQ1ajh2Zw0KbkpHM1BqcCtOQVE2SU9GSndCODFqdjdaRjJ4aUVTOTF2SytEU1hvV2lMQ2xrNjExSDB5WlVJdjdiNk1RDQpnZzdzL0djZ1Qwa0RVTXZPTWdEdUQ1c1lFcCs3OTlwWU9MaDZ0VkZNQ0EzbnEyWWJwd21WU2pMdWcrUzcNClZ4ZWo1c1QyOUc1MW5RVXdDdTdlYnFtN3RZa0Z2RVZOOW0yYnRQN21oSEFHcUUxbHQwaC9RcmgxQitpRQ0KMWphN2xYdEhvTzdJb1ZwQmRTWHc3RjZiSGNaWEF2QVJTTXVab3VnTkVzZDdpZGZEUHRLeUU3em0ySzRoDQozQ3ZPMXRURHA5MUUyQWVJb2c2Y3ppWFN2cHl5MkE2Wk54TlZScU43QkVZb3I5ZllRUmEzMEtWZk9SRXQNCnhoQjdGRjkzL0x6dFVBcExvNHN1NTIzRGdvdS93UkRiQzkxeWg5ckJVMGJMRGxLMW5odVlSU1QxaG01ZA0KcGpSUmpJR0dmUTRNZ1FYYmpRL21kYURnNmVkRjZFNlMxd0p3Rk5oMXo3Uk9Dd25naGFjbHVlMmsrUi9oDQpXQ2ZSelFGTjA5VHM0TlcyRDBPNklnZzlXSExubjBXWmZYb29BVDk2WTg3WGJOclhxaHhXY3B6aTNoWXcNCmRWT0N4ZjhFRnVCZGZHNFo1Uldta1hoZ1ZGZk9LMUhxZjREalhjelBjbHV2NDZLdGVEYndvdytKeGV2Rg0KQWNNRFY1ZUhyZml0TXVLNHMwNkVDbE9kRUthT0RsbUNGOVR1VFdDQ2hPRGp6YzRHa1VWTmwxc04zUmpvDQo4YkVKT0xUSUFhN2V6V0RrQ0k5ekZNQmljY1RwVVpoWWpGbTBDSWl2UTVjZkZNWVA3OGYxMlU3ZkhuVHYNCkhyd0x0bjNoN2xCaXRGU0xucHYzSnN5SVdhNGZ3cHkrZjlWcC9xeTRKSmFMN0Q2Mnc5QS9nZ2RXY01ZMA0KTWZ6QmdEbitYS0p6enRxdkV4eDFQakdEMTlHZkVSNWphQUcyU0JKWUl4ank2V1hzcDZrRU4xSDA3RkFoDQo5U2N5Sjh6NDI0cGo5SkZPTGVVVmQ5RXc0b0w4SkFWQVN3dG91cFVOdnJiUkFTV21QMFAxT242TzZwUFgNCllQWnVRb0hINlIvdkU5MmZwVUk0MTBIQXhwVG1TcTFydGw5UmdMaDc5L2kzdkxIbmhMMlZPeWZ5S3gyRg0KeFhCSmVVOTJJSW9ZekNLbG9GRURzbVR1VzJTOXluUzJtcVRHMUQrbGpTd1JJNnViRTE5VmVoalFnQ1UzDQorcDd1SklIeUZQNStpYjdmSk9kNUVWdVJWN2hGS2pjS2Z0cStjQ2FxWVlPMWFtNVJnMEcvNnFGZzlKUk0NCktFYUR3UmljNGVmNE5DSVkxRFUvR2dxY1lnL2RzSFpzUUV0SHQrU3ZCcVJHL2g5TGRPSUpnQVhmcGN4bA0KWTJxbnZIRU5OOHFFWFVvOXZTUVRGSUVWeE5oVE9EblQzMzRGY2U0eUJTMzllTW9DMUhTTTdjaGc1MjZoDQpVRHBkcUEwcjB6SkhPc25wanFFQmhvUGVTdlRPRHQ4eUY4VWY4TGpjNWVjYk40NExrbmRSdU90LzVuUzYNCnBBUXNWN0ppL2huRGh1Q1FKaDBFek9FMGZyS0prTyt2SzZuaCsrRTdobGZRY1ltT2tVa3dYbFE5cFd1QQ0KRDdpLytUSFk2K2JIcFhpNytkY2tpaU44b0daekI2czBBUW8rMXhYY0RMR1RlV1NFVG5wZ0RGQWlUakMyDQp6QVdqeHFZRldoaWtKY3o5OXRjUXMvMFE3U0dKb3RibWEzMjVJOGFkQmRHNktlbkVoS0daZm1PelZxaEoNCm5BejZTMXlnQ1U4citKUjN1RVFRSDR6aWZGWkNxUHhneHZabzBGaElkb3oyVTNJTlN1NzVnNDZKSTVXVQ0KKzhiaGZYM0VxSUhwNGhUc3ltdENINnBLQTZ3YUpOZjdPWUEzTENOSDF4eGhuSUw3WkdwT3ZGMDlQUFNyDQpCZXVsM3JSQXhBQUZ3ZDNRTkpuQk9EcytIaExaeHI2WnZTSkNnODl6S2tTNVFoc0l0bmlnZThnalJqbkENCjVWSXppOE1Ecy9YbHI3WGkxZG9lU0tYeS9hZTdFbVpqMjNTYUhWNkRObFk0UGF0blZkdFI3bWdKbnBnUQ0KaWcyNXRqTHdrczcvbTBRaFBoT29XTGxOZHZPOUlYUVByTnpIYWtHNEVFQjdoZS9pMGt1aHVLYkZzUERiDQpZaXZjSGZuMm1XekRwbFM3WS9XOS9Fc2dCWHZGVHhJTVBqMXpxQjh0V29hOERqNW1xVHZHMXpaUVY3K1oNCmZGdnR2d3B3LzJybnNSUGR6MmZaTGl2ekpRdWNwcWduNTBQVXFCYnh3b09SL0Z3Smlya0piSW45MUxWZQ0KbmRMclpoSGx3S2QvZElHRjFWZkVaRTRPYVRiOWFVajdycTB1V0JER3h0M05kYitDWlRvaE41bTI2SWtQDQp6OG1hK3g2blN1U3oveVdHTlM2M3k2SG5yaFJLL3UzV25xWmJ0cDdxc09ORGFBc05zWW5HWTZodHV4WWENCkdwaEMzVzh0VlFQeGRCdFRqbzJKaGlwamVrbjNiQTJjbXppU0xzNXVkOUFaV0pDZXFBUFAycFZ4Y2Jqbg0Kc1dsYnZyVXRPdXVQMXk5RiswczlGS2Frd1NuSE9EeXhLVDIwczhJSmd6MDFneXN0MEx6ZElZQzQzQlJqDQpjaVJpT3pIVkM1blZ4dUI5UmQ5Y1RkY1lUTFBLbHg5NGVGK2kyU2FkSy96a1Y1Wlg0SXljNGlTNjByVmgNCkRIV2ttb3BRbnRjZXNLNkphS1ovS2w0ZnVEN00xaVlnU21PeklKQnoxMEpJQ0wxZExRMmZuVGtSbWRJMQ0KTm15bnBBMHdIa1YrMmEwTXk2a3hxMXcyZ0FzQzBOQUZLZlYyc3p6N04wRG4rYmpnSHZ2ZnY1RUsxTERrDQpOdEhHS0ZrMXpPUTFrd09hTDY5RUVqV0NXeWVDU0EvNFpzQ2hMdFE5dVBBeS85b0VTNU8zekx4MnoyYXkNCkV0b082dTBKOTI5cUFHVkdHNXAvTmVicTE5dm0vUUEwQlhZaENNcWQvQVluM2QzL3Jya1lEc0FWTGh3dw0KMU5HZE9pOGI4NXZYSHQ0Z1BaSkhoQmlpTm5XV0plVkNFNHBHL2YwWnpWM3dYZFcxWVowYVI5TWtsQTFUDQpKOWFqS3JxdVVTZEcxTHhzS243Q1VZaXpZaTlrYlpPYUEwL200aVhReTdvcW9jSlZFM21ONVgwaW1XUVQNCm5ZU3kvN1drY1FGMmZHTkhpNXllRU5mT1I0TmRnNlh1Y3RyMitCWmw5NzZ1a0tqRTJXYUN4aGdHdjdEZA0KVnBjTFVEV3FPU1Y1WDVyN01vRkJkbk4zeExaQ2hXemJDYUgzZzVyNWUwNkJObFVrL2VJUEdRUC83TGRHDQpjdGt3ek5BSEYrVlpOelFYL015bkxSNWQrenNic0NiNkVFaHBsZTEyU3BuYzg3VEZiWEJPL0M3SUZ3eHYNCnRNbHNPVkRpWW9INkR2MjcxZ2pWMjNkK1kyVEpRWG5GNFMxcCtuWG9CdlhUaS8wQ1FaYU5UYnB5cW5JRQ0KanVyNU5SWE9ubFV0d2hrVHozSS8zNjJReVh5ZzVmZHB5TjU2dThvK1hNS3NORHV3WTI1MFAzajJMOHJnDQpnTFdIRFFGbC9LY2Q0MmgvcEY5ZnJidnVVd0JMUk1tT284MmNRaXV1QUJhd093dlQ1R0hGY1JDNVE2ZlMNClJkeFhrdmE4cnhEMHJCNEU0emZSQU1obUFPTXFid01nVDhQaWdZUHpyMjZqaGhVejVCWWFxRFRtUG5ibA0Kd09uOWRPc3NHZjh4MG13TG43VXJQMUV1RTNrZElSRGkzNlE4aHNmOUhBV1cvcTRuM0cxSDRaUkh2VGNWDQpoZjltNDNVZG52eExuUGlrN3QyeEwxRVoyQVdyREtTbU9NR0hHRUVobDhxYkx1NHlUamdicVVIOENFUGENCm82NmlmWmI3RU9RQ3FCVnlGd05wd0NqMHNvemZPYzlRQk1qeFd6eGQ5KzVUdVRGczVVSklTOUQyTHNYeg0KaDhGaHc2TnduNlNia0RzUFZucGV4dldHYXRqc2VURjZxbjcwMWRldDBuTmsxdks3SzF6cjc5TElKaUFWDQpHUTFKNWRPc3hETHNKR2hDdzREZVRkQnFKQWpqbm00RG91MHRKcTdpWi9TcnFNeC92d3czaXdodi8zT3YNCnhaOHVucWIrQTk0Q2p5UEhkaE5OVkMyK2RzbWhnU2RqYUprTFBnMityNnhFTXpCNjdidG1ESnRxNnliMQ0KRFh3M1EyRnFueXlWaUtLVDhid1pJNjUzTmllRVJ2SVhOVWYwR1U2NWZnZkpCUEMvVUpMRmVXUTNzVjJ4DQpFU0h6TkpWKzFtYUFCSEhUTE1nMmRoNzh6aVlGVjM0cUE5SHNOS0dpdHdkeDZOQVU4ZGpoRDlHeERCaXUNCkFMWHhPTm1MOU1DblhiNmlxZ3VaUG9hT3VLaytDdlp2VS9USVRsaitvZFhuZDdZQmRyTWU3U3NueXJ6QQ0KN3BnbkZIb2drZzdSU1NVMmpCRGtqUVlaam9CU1NHN3dpWEYveGQwMU02Y1JvbnJGVWhMOS9semZjWC9nDQo5SFhFWWdYenVUeHNxQnhNMEVyZkM0MzczUnVPUDJCK3UxY21tWU1PaDNMY2d3c2NNdXZQcDl1T0VKQnMNCklHL0hDaGIwNCtuajJsRHlsYURjR09XUWNnTFpwSkhCb2tzaFU4WXpNaU5vTlNza2dONDVEQTRYTEIzdA0KcnZidW83OFN6SjVQVW1CRE4rdGRZRlgvNDNiREFXdzRTNGtZandtcy8yNkwzakR0MmdnZW5PejUyK3ZxDQpyM2J5V0pJSk1kWW9sMDE1ei9jNmFLRnhOMFRqK1NUcjU3ZXYxSUZyTFgvQy9XV2dTb1dJTGZoKzY1Q3UNCkpTWnRxeU5VekdqOXBFQnoyUjZ0b3VSbkFja0UrYUNZYkl4V21pWlU3bmtGckNjb1c5YndqQ2dsbVhDZQ0KOFRlNkcrU2xFcnR1TEFRdmxaWWVsYlFPVGJObU9uT0Y4RkZrLzBtbzV1WjVoNU5QeW10S2dlMU4rNHAyDQpuTDRYV0h6OFRIOUtGS1BlQWNDUFVpWjc4RUtDVlN6Tnh1REZmR0h6UzJhOFNkb1hudHNZckg5ckhOMW4NCjlJL0ZyQ0JweU45V3pWMEVHRlljMThLWXR5NHRHN0N5V2NtcFBZMTlUeXpnV2kxTWJoVGZkejJNUkRlZA0KejNkWS8wbVROUUt0d0pubGZleFAyZzFxYWFtYXRZSlNTZ2dlY08yUWNYemV3TnB3dGlhdUU0cVZXSHEyDQoxUys2ajhUTUhLSFpGOWVPVUpmTmpvRE9VOFdoNjJwMFV5bm1ZSnIrY1hxbW45RVhCM0EzOFNoLzN2dysNCnNOa0I3NzB6SWFTcitkZ1ArNEdhazRKTVpPaVJ2MDRpWmJUeEtUaE96SFJEUDNRSWFpK1BqQ2hWZ3h1TQ0KMVZWU2dmb1dxbnhXT2xXWXloQ1ZaT2ZhVC9KT0VJNDNMYWdFelpnN1ZFbnBaMHQ5eDlIT1BoRktNK3ozDQpqelNYRTZkaEMvYW5QaGpEeGRJS1I3d0FZb3lUN2lPUTBaV2R1b2h4d0QwL01jOVN0ZWhmbjdQNUZleGoNCk5oUXNCd1ZteUZnM3Y0ZDZYdVg1Z282NnIxRVgxdzlFZDdMSmRIWTMrcUJMYkcwTDhDSTl2Rnl4OEJEQQ0Kb250Ly9BKzY0V3dFME5CbnRDR3IyZzZCTTROSFNmTFRRMUZJUk54Vk1PMkVsL0pyNmhtU0lRZ0NSbU5JDQpDdnRnTG5SaUpZd21uRFVLSUl3YkhBSDQ5ZDRJcEU2TUFESy9FdG5xRFRWdXUyZGVyQlRDS09ZV21mdkUNCnVmNFJjeUdSUTVSRjVnc3A2YXBmaG5uRXo0L2dycDR4U05SNFVoZENpOXFzSnhhZzY2bzluZnZtaWxrRQ0KV1ZlQ1Y0MGkzR0IxaCtkSTZUb2p2YTFOK3lFaXhUeE02d1NTQmdSMTdYMEpyY3hXb2loM0V0UXZvRTFCDQo3WXR4M1dtRnhCTDFGQm5WNCtIb1ptNUtZQnJLZlNPU3lUV2tJK054VUVaZkRiYnVWdXFvOEpNTWxOK0sNClJsR0tWV3ArTE9zQ0djV3VpcDl3cUdqOTY3b0FIRTBiYWZ6VWZaRVV0aWRHTHJXcmlSYlBFNWhKVUdENg0KMlB6dWx6cWw0aFZweHAxVXVlMHlDeUQxYytINnFiTEFFTDc1TUh0OW1BcklaWCtVdkd1L3E2eElHdnlXDQo0aVhrTGZCb2VUWmJrOHc1SUIzV2pvdHR5MVRYMmkxWkEyNjBHUUpxb3Q3RmVYWWRieDJITWVLVUMzaS8NCm5PSE54dS8zMnpOeTdBUVBqdlNmeXE0Mnl2UlFJRmRBRGF3SVRTMkJNcTBMcmVhOUNlN3ZoOWNhckJnNQ0KeXJ4R3BNRTZZamcwYnZXbkprMzRMZUNzczZiaVNVeEJuZ0FnM05zZTdXMzM3RW1va3BHUXlyOWFIVEN6DQo5cENpL2FNSkk5RHlzenpJcmxBTkoyaUQ2Y1liRU1XMUhlckZCWjlRcFVXNG1rREVjTk5KNGRDOGd5WDINCkdXVWplS0hnTWxEU2VKbEJXV1ZqVVh3UnRrdFNKcU9wU2V4WXp6T2JkMktTblNFYUNPUDJnZ2owZk1GZw0KUU8zN1ZjalhPenZqcU9ZMWJkMVNSZWZyS1JwZWl3VW40NEdlL1hWL1oyOFlXZ2tUOGFpWkRrbGEvUXlsDQpqd214N1FLQTZvTXJkdDZ2Mm1PMVdhT25GcUdJc2FzTlFydEhCMzZsYWdnTlhJdHBMYzdBNzllMURvRHYNCnhPRnl4SFNBamFVMCtNMEpKWE9WUWRxUlVWbDhCV2dCeDNVUVZyUjN0YkRKVzkzQmlKR3lLMTVyRVVybw0KLzA4QXlRdDgrUUozeGxJUmRsbmZGWjMySlcyV2FOZlhybjZLNkZTeWplTTM2TlpnQU5Cbjk0WFJvRmtZDQp0M3dQT3Vod3pJbURJOUlpYllvdGczaFhsdGRienJCNXlxRU1iWnpvNlZ0aENBY0U0d1JOQ2laUGdnblcNCjVveWZNUWxaN1RPV1FkajFEYlc3RmVlcnFmbVdIZHgyZW5xUHNqRWNwTDZnOC90blRRNDl6Mk1nVTYvSw0KZHZqM1JMeDRneXFuUnBnMmtJQTdMQndra2picEIwQ3NwWmFrL0lrQ0g1aHIyd1hOVS9DLzJIV1hOSnRnDQpRV2phZlFHODN2VUlsci9kSDlYYUtQWEdUMGRWZW5YdjR3ZG9pcFpxUTFienMzamtoOHdvRFRlTXlDOGYNCk5kRE9zVkpaMW8zbEUxUzJkcVhlSENjTGNhMURhMVR5bElISHk1b0tnUXBUQ1pDd2R4Nm8yNE5Vc3cvVg0KOUFIRlRWTEVaZGx4MFhZVFVrZy96cGhxMmNTRmR3ZkxyVzVZdXNNdEZHbHJSdzZOdCt5Zk82QW1OY1BMDQpKait5UDd0clFhcXBOZmZmWUJHZWdTaFNOMGk0K1d6LzU2Y2V1UmFJdkwrbERsMlFZa0RmN2pHZFJOYUENCmtYalgyUHVJanNaRVBDeFdUNlUzNnF3QnZUQkgzQmwvT3VtYitVbWtvZzdqTUZ6NUM1SFQ4cWVKYU5SYQ0KZTZZanBRdjBtL0lVQnZ1MmNTOWxBODZqVjMrd0c1U1hGNjhHK2VTRlNBeXY5MCtBVUJaOGRrUmZRN2ZBDQpiSnJQQ3dBQ3RIb1RSVDVzbVltclZFakZzR29taXhUckxOeFp2dU5vSzZPMmR5bzRMQ0RYVms1TVpQRXYNCjFId0psSEJ2c29VaVd3RjZrdDZtRkFCUjRodU1rOTY3d1Vsc0JVRTdvSkcxN2NxM1lSTkp6ZmdsYmxzTA0KZXV2SmV1aDBOWHRXYlFjMVJzQnlaYUpTdUNpcjJwK0dBTVhrMTN2QTNyOE9MYjVBRmpuS05TenViSDdNDQpmbDZVSFcySlZwYWp6RVowMHBnZ0lEY3NUNFQxWmc3M1RsRkFyb0lGckpVYW5NcE81Y1hqL0RjMjRMdDQNClZ2M1dXMk9FQ1dKVW9vU1VqZ0xXMWgyL0tiVUtXQWRwNnpjemk1bGhkUnFFdnZKUnYveThHQ0tSZ0x0bQ0KUXI1Wmd1QW13SGxWWHNCMHRoMHNXemN1emJSSU82Ly83czdiYy9nckZ6YXZ2N2FranRTanQ1emFmeUpPDQpRS2NrTHdlazJESEZublJ4TWs4bkNrTUFQRUdtQlZEb3JtTFk5OGlSMnZnU0xFUHhUK1JzNEFUSjFPVC8NCnppNkdMd2VCRnk0eFhLcG1uYkh1RGx1b3Rlc2JGS2NJMWg3aUw2NnVha0dXdVBoOHpqOENCK2UvVlgyWg0KTk1xNHREQjQ3WlJ2cnI5SlgwN3N4eDZMSHNIYWFBcTdSVFA0OEdrZEU0VUppckRKWkNGd1JKUlIvMTN5DQowbEl2ZzBZSlprRjBnUWxYRHJKczgrell1a1pBMUxMVFRuWkFGZWFZU2Z4dElGVXNrREtwYStjZ2ZxN1cNCmQrQlluZjBFMUFBdVB1VFZzTmU2SzEwd0wwWGNOZTdZZGNEdzVnSDUxMzNXdGVWbGN4QVhnSng5QklUUg0KaTRoUjloeEhHMW1RSi96bmE4SXlSSEladFZubTdyS3JxYmxtc205YlZPQmVHUmRVUGNBVERrNklKMldGDQpsM3FOYXBiSDZ5M2VwMDc2TzVCejBiSmpyWFNoZzJwQUlmcm43VVF0cWg2eHlsaUxWdFNjRmJRWks3SjQNClByZ1hKRTJneVVoMWNoVjB4SWVoTHB0ekFzWkUvNFlSNHE5MW4xWldpT1U2aXNSK1RnNnozNzZXTUhJQQ0KNGNQb0NoVUdQSHFTUXU3RFlTbkt5akpwbEJMRmx3VnNOUVhZUzJHQmw1MmRSeXp1cnhCU3daZTlSNUFjDQpNaE9pTEEzdEFqQ1ZrZDk3cTdIZCtXck1NM0tMTTdDZ09sSVF2U2ExU09vbGNDcDliS3FzNVZNRkVpQmwNCnNKTjQ3cEpra2pDeUY5dkxMQXQvR08rQlNVSXpjRWQzRUZUNytOU1V5dHZXeUdnc0tNMEQ3MGZCQllIZg0KRnFLRDB6R3dkVk5kaEgybE5odjIvZXNJeEc2WnpUdXl1MW1TSEVLN1JjbWp3dUx4dFRBYldzQ3hndHI5DQpnWWx2K25CQTcyUjVtVXFJTUwwRVlmTERqWnZMTkFMbkVMNkFJdTNsN21uYllhQzJUWFNpZndVQzhLUWkNCkZZaFpRSmpZd1IrTkdoNDh0eDJkV05GbEk0U04rcmtocm9mMjJOaXMwL3FFSlpXV0tUQ3VxZ1g3TkZjUA0KR242K01RTWVhYk5MY3M1MDlKZEkvdzh4dCtNMlgvMkE4SEtETFZWU2N5RWdrdW14Z1BVbXF3SmhnOThJDQpNN2FlcWJtUXNjUjcvbEFvdHlXc3liTmdPU1Q5dzZZdnhQVG1nOVlkNmYrWVdJaVRiTTV6VTZSSkxROXINCm5qVW1vQnJnaGo1aHJNeHFrb05lV0hjYlNPbFNoQUswdkpET3hjaTFzK1NzSktRaEVhYXlmaUVuOG5MSw0KNE9lclVYWHFoRVdyRE5PRHhETmlGVFBXdlZjOTB2V0dONnZEK1NXbnFRRDhCT2tNcDRJSkk4bkFZT2JqDQpTRmplOXd0Um15ZjhtSjRobHZodmJwdEFUeUFkenVUNXAyS05yYUd0WGY4ekJaSzVHeThLMnJwQmMrOUkNClN3RGZwUkdtWURZNG5mbGxsb2VqY0h4K0pVY2tjWnFaeWt1MC9vdVB0MUdQamdzYW05TXBtN05LT0lyUA0KUlBmeXRWQW5mcXlRcnRlNDZnTER5ZDFLdnhjTE0yV3RFckZqS2xvWlBSaVMwTFN2UThWZmpkOXFldDU4DQpWaVdzZUc3YnZ4TFRVMWJHM0dTQXA2V215Mmk0ZFdlVWJFSGVJbWFCQi9kRUtSc2RxeHJodjNoSmZUblANClcrcHJROXBUVkc4bVFyS3NRM25kSFR0elFSTHBsRjZacHpCajk1ZDQrYnJTeG5NSHNwQkk0ODNsOVFQaA0KaTg3d2plZ0V0VzEranNkNHhmclBobHYzc1NrL0ZqcnErMlE3RVZBSm1SdGNKcHRvSlp3emNYS2Voa2VrDQpaSTFuRi9OZ0Q0eGlYa2dkYjhmWkxTd2Q5TFMxWGMrTVp5cllYMHBLNFBhNlpkdk5oS2lPdkhKbGp3Q3kNCkZKZE8wcWkzczByQjhtTlFDV2VoSCtBRmZkeWVQSlNLNytwanAyd2VzS3o5YXNlWkRvTEpQcGpoeDZqMg0KcjRBeFFTVUxIRDNVbDRuaXFJQzdiSlcwQ0VFSk9qVXRtOE1QOGIraXkvZXJ5Y21nRUNPdmc5VXNZUFJiDQpZWnovdm1vWXdFUkJQYnNpR3BtL0hDWWRsT0dmYTFraEVBOWo1NTRmV1lHTHlNOUYyZ2UxLzdRSDg0ZGUNCnIzYzNGQkxzajhZZCtiRmhUbXFmTnNrZlZJTjUrcmloOWdZMmdneUFzUWV5aEhqUk9kRGNaNjNBTUMvbg0KM2tSUG5pdDV3YU0vSlZJR0ViYThJdkV5VUwzWUpVUCtMV0c4RHcvQ1NJdDlUTXFJSC9CU1dOTVVtblBZDQpyUzJLRmhnUm5KMVBTU1RWTXA3MmNIaGdHWXVxcmorZzhobnBaYyszbkpuRVNDd0pGTUljZWN1WkZYbEQNCkh4TGtTbXdzMTdqUDRmUHM1T1RIS0pKclptYm8wNWJIcXVyb2pTUXNPZEVjYWUvMXJTSDRjQ2hCTDMrMQ0KYXlqdlZoSXMxWmRXcXFLMkxMUXVRVFhEU3RPZFNPcStVSnV6OWNNMDkxcnB6ZVNwTVFIRkJEUlFuT3hzDQphcmNTZ2RQOGhGSWhwbGVhVDJhejJ3MUl2Uk14VWVEelhoVERTUnhtVlFodzVHQUV3b3ZkRDFNMC9uZVUNCkNqUThBcFFuYk5EQkJuZHl0WStwRExZV0lWdVgyYllEOWRjeStneDFuY21KOWlrZDYrMXFUZG0wZG9ZRA0KODdEdmtKT0RKZUdnM0JPV0RhaWpjVmhNWXpnNVQwRkYrUTJxRmFDcmcrWFRNcmp2Z2J1VVptcWtQQzl6DQpjOU5MV1RxMjJ0K1JrL3hFbzNEWHNDSDBORnJzRk9mZmM0Z0N6MXQ2S3RURytGNlE3aldwdEloN3A3K1kNCjkybFhValdNVURPRnpvZFF0VGR2anpLcURvU0ppN1JnOVRDeFdtWE1ieWJZREF0VDh0d09qVFhLS0NjUg0KS1hmK3RTbW55T1kyempSK2twblZlWEJkdzZucEdDYTZtYlp3aVlRZGcycUhCRFFQbFY0aGpmQzZ5RWcrDQpTTXZ4a0MxYXVuQ0xrSytBRWo2TWd3dkUyMEl4VWNKRmFaeWVLRXFZYUhmTEp5T3Q3M3VsbDVPWldKd0sNCmE0bGh3OHZPZGh0VndFUDFyWkQxS3RQa1krZmsrL3h3aGJuYXRlS3Z1M1BROUw5MktHQ0lZWW5IWGxabQ0KcVBGRC9aRHNNMTZONHR0bjltT1pjc1hpK2ZmY3VXZjBlL3lrNTFGZUZFUS9PNzc2ZnBvalpqNWxybzh0DQpkYlJGV2c3U2VDb2RhVml3WDdTVjI3T0xPaFlMQnlCdG5RbDVsQXNvMERBOVpHck9Ic21scjRkRnJaOVkNClFVNzhnZklUaEpyQ1psYmdONEJYaks0M0cxL05RUDlST1BWUXcyOXgyZ1d1TUVtLzBKRkZGSnMxdWkydg0KdFpyb1ZoV1lVRXFocUFRS3cwVkxadE91NUFZbkFEZlgvbTZjdkxSb29CKy91WkVnenRKNTlkZlFvUlJWDQpNc0ZrY3o1Yi9qM1dZRjJyQjVIUjNsbzFka3M4ODZGblhhVmhQREVscTRaaHNDLysvdFhzZnM3czhZZEUNCmVOUmM1Q0FEUlZPUzhDWlh2WkZwRW1JMVZNSlg2NUhOY1JITzFadkRrOTRzWHQrQ0VQWFB4d3NIdnUvLw0KQll5dlRiUVU1WnNrSzNDL3BvNGtxVVdERXVTcXB0L2VRd01JbHNWYVA2NUx0OWpMVzkvUzI0aGVxY3BVDQpFWTNXRSt5UHplU053b0dnWFl4Wk9RQU82aUtJVm9mS09DZWx2QjcyczFRb09ETlRORHVxenhxUGliNE0NCkV4SzlSS1kzUkRpaE5wOE1aNjU2cmhFaUVqVFQ2czNxTEsxMUZ6d1lmN01qQ2tSeTg0aXp6a3Jvc2VYag0Kd3JBNlU2eFh3NHdoNlgyclc5WEJiSE5aNWtYb202ZHQwWG1jcndzQitJbndjVlhpbHVoRzJ5dk1JM2hJDQo0UnlVWlhuUXF2ZEtPZks4dVJlQ1loNmxMdDBhSDdDcW5GdU5oTkpBcFMzYmZtRmdROUhRajE1cHpBcEINCnpPajN3QUxlK25PeVB2M2FIRmJJUWtjdFF4cSt4VTBIc21UOTAxaDRiNmZKU1RpRnoyY3N2TmFYays0Vg0KVkN4bE5FbmlIenhibE8xb3JPdGlUclp6ZEQrcWZPa2tuTXQ0eEMrWWJGZ1RyWmFhVmtGVk9RMHFFc2JqDQpBT0szUGJ4LzZEUHY1RzRsbVFHNUp2c0FFckFtS3NRbTNIYnhIYSt5TzdrWCtsN0VNdkNuYmhOV0V4UmMNClFobGNQWExjb1JBeU1nb0RlbXowYzJUNU9yU1d2R1BiaUQxRlVoVC9OTWNoRTRUSGZoaHorV3pzbFAraA0KcDBQYStQV1FLV0dUR0hNdjViZldVZElCODAxR253cDI2R0tZS1FiOXF1aHcvaERuODFLRDJTcERSOTB6DQpqUEUvVFpoaVpwNDFNMTBqSWdyZ3NaN3poZGlELzl6WUVjK2c0OHg3UXI0UEFYdnY1UDVLUzJZTEsvWkINClJMK1I4MDRDYXl0Sm1hcnlQU09kMGF0OXJRMXRtck92eG96djdGa1dkaGx1cGRWb25aeVY1dUJWVnkxbg0KQ2JVUG94VzNOZ3pXTUZsUytPcFl6T3lqUFpEWWhrME5paTRrYndkUElwbmtnUVJvM0FER29uSkZTVnNhDQpna2dOeUpobndET2ZoSk5xai9sV2E4Z29UbmszVXE2RjgwMld5OWp2WXJHZEFJUkdRUW1oSzZsY2R0SkoNCnhqVE9raVd0NXB2Q2NTRlpBZ0p1NlB0OGIrV3A1WkJGcTJLODB5ZjZmelFJMU9uM2ZXcGpKb2MwZ211RA0KQUFVTDRlZEFFSjh5UXNzblptNlBQMWR5Y040eTRXUHNIL2MvRFo1MWY4K3crUGRUa2dZRm83NzBHUDdtDQpkVTM5RU9RWlNhRi9XbWR5M0hEWlZkZWpkZmVnUWlOWElBbFNLd2F6L3JNSWcxQmRWeTREQ1ZtVXEvSUgNCm5zTm9ra2lIaWRWNERiRU5xU2hvR3h4WERFSStNeEVvV0JCYXFwNCtWOEIvV253eDRBTDJHVGVZcXpZTQ0KMFBLbTFZdXRPTlNQTmI0bUlNWWVsc0JTYWtCTkFkaTMyYVc5N3JvQzBXbjlwZnBSbmdtaE1hL2xkL05BDQpMSDgwd04vaW1HSU9yQkNWVmhkclBYQzhGWlU4M3c1ZUVrV2dpKy9mVjU3M2RqSUdoR2hPLzJ3dU1IemUNCkR4K1M4Qzc0OUJVclVKM2l4dTJKQ1JCSno4WXUzQjNEYnhPYVhMbEhjRHFXUWZraDc0Z0NzanFVWkNTZA0KRGNZMVNGeHdma21kaFdiMU9CdGxrV1JWRFhLMU9JeFBodlpnZDVXL0w4QWRMUFl1NmdyQzBGQ3k3SE9IDQp0Qm5vK1R6NTNWSDNwc0g4dzZLQk5BRThPc3RoU3NGeDhBR0JWb0NQMFNBRlZxMnNScG5uQnlnT1pxR3ENCmJqUWdTRWlTVGR5UkdIMjFLWkNkcjZVWFJrdjV3ck1XUEhxbVFwK1liRWViREpyWGdvMkVCbFpsMnJqcg0KMVdaNmJLc2FnVi9kMWc4bkZvM2J2bEZCYW9WZ2Z4NloweDZvREVHaDM0TjI1UVRMV3FOOEJxMHF3NkJPDQo3QWp6a1V2dlN1RVJobTh3ZUNhNHNwVFdGVVdpR0M2a3VTamU0RWIrSFRZUmpBaU9WejJPdVBLdUZoT0ENCitvUGQxa3dxNHR5TWZhMWY3aGlpcDNFMWxyZjZNRVowclAxSEh0OVdtN1dYVWpLajhLM3lSMVQrRGkwRw0KZXpCS0IzUWw2N2hjMHNrZ0ZsUGRIZGVsNm5JeWdYLzVRUlpjM092cDhzUzgzQ2lKalNnZFBhMzJZNkRGDQpwRWs5WjdETm1ONkFGVmhXQ01jUUZYa3ZMV1pVU3BBcHJ2Rlp1VXFrdGdDMlF6ME1JSy94OFY2MGJ6cTQNCi8zYjZIUWtKRDAwcTl1ZGh2dXFsNVQyajUrL2lUbE9xZHBEVytOQUliSzVQY09YR1ZDdzNRZTRjd3ZZNQ0Kcnd4N08rYXZ3Z2N6Ry81aWQraVJTL2xueTloSFp0YlR4R0JLdGtpOUQrT3Zpb1EwMU9XQjVJTmh2TWJMDQo3dXVqcVNRYXlVWHFvc2VINDMxQ2hXQ201Y0ppVkVsV0hxcFBUWnBsQXZpTkMxTUU3clkxcC9FNEtONFMNClVDRWxPeExPamN1WUhDSUc0bGtIUUJMaHdJbm1kWDhWbktid1FKUHp0S3llYTNPamtrckUwbXViZmttMw0KRzlOTU42RUhZdjN0WTZRRGxQWjYyU3dFK1Y2SXcwUHZ4VFBQdytDR3J5S3d3MkpRMUh4NytLUkttb3N3DQpKY01HZjJEUGdJWlRGY2pETER3THBsQUpqN0I4SU5oRjZnTVoxaGUvZHlHNnVOeUlydWh1WXdJVC9CcWoNCnoybEJRZWxVb2dTdStNSTlHSmNZcnl5cEIyb1ZaS1JpOW5aajdZdVI4SW9VdHZ5V2h6YTZYYjZCQVdnbw0KR2Fia2xWSTRIVmZtQVkwV0NkUDVhTGhPQXRiUTRBYmZMY3NMclc3YXAyZHArZVRYWGsrUUY5M0lyZjNqDQpjR2paQ2xvbk1QVVdwYUdCaVRMdTZ3bjJQV05odTI5ckpTUDJ5VWZrNWhwK25QZERldkw3eS9RMVdNdG4NCmhBRmZZS0pYbjNHYXJ5cHF6REVTeGp1V1I3SVpIbU9lMEdtaWlzOGpMRHJJUDByajZzcFYyUmZ3ZVpVZQ0KMUp6QmhkbUp0SndxaEVZN2p1a0Y4MHcvQU9oS3kvUGszZEdGa2tieHZXZjBaNytrYzAzUzU4ZzViT0ZWDQo4R1NlckMyc0c0OUJlUWZiMnJKRlFmQUVWNkpqcFFMTlQrdnJYWmdLdlZ4aks5YUJtT3g4RHd6R0xhc1cNCjB6Rm85VU1pZHphUWNkSFlJQzdYVndOajRzZUwzRGZ1MVZNeHRMcWs1U2dqN250SG01c09ZaklxZ2VVMg0KWVdDQmZVU3BDQXJpNmFBWDhycXZqWFlkZUdXd3VlTUJPeDRIb2FQU1Z1a08rVGpvRVlBNEs1ZzUvWVlwDQp3ZFI5UUl2ZWg1anVpWUVtNjJ4aFhZZ0RJS0VvUTZybkRSMUVvdjErQzJQclgwa0JWSHdrY3BzRDRMRFkNCmduZHFvc2Fab2hzT0o1VmRLUWVOK29GbjkwZEd0QVZnUWpOaVhsUXJRcGpFMVZJanQ1U2hJQVd6c3lLMA0KN3JnZ2llcE4xK2FVbG1TQVVaYTlmeGRrWHUvdHFSZWV2cUZGU3JSd1g4Zjk2dUp6TGQ4cWhYb3plOHJaDQp1emJKYnBUZ3lWdDA4VE5zOStoZlRldDI1eEwvSityc21YS29oaTllcVpOUEhBMTJaOE1xMkdIRkZiYUgNCkRCMEJQSlJpQ3lJQnBzZXB2aEpacjFFRVlKZ29tSXhuVXBOMk15NXFtYk5VbmNqMFNSL0VIV3RLaFlKUA0KR0RiTnlzN1FEMnpKaFl1dEczL05ZcFVkbDlreEcvYy82TnFPN3ROTG52TWM5b09PZDRqd0h5dXdDSHlUDQoxMXBsaEpKTnlxZjlNamdBYnFQa1FJc29yWGV6WFhVRmxkU3Z5TXk1VXc3SHRhOURjaXA5YkZ5REpCUzcNCkIvSnhsdVhFSmRZbEJXanFXeUt6dHU5RTMvcGt0Mk5LSXRoWkdxVWE3MGkrMXhTV05OR09PZUxtWFN6VQ0KeCtPN1FMMWhMNzV4Y0dWenFJSVR3ZGlneUUreTZsWG85cTZDbitIdVE4NG16VWRiREM0Qlc1TUs1SUY1DQpxRDZ0UGZnemIxWmowK0M1ZUhvMllXL25KR3hNWlJwSGs5SHZ2aWlzckp3NFpBQVlLbmxkQTNSZ2V4YUINCkhqMTZJOE5qMmZmSGpyYnl2aWdkbWZrMTNFYWhxeFk3c0ZEZ0piMlZIdlJ1MmlwVm9IeE1XQkNKdUg1SQ0KcTR5dk05UGZPSks2WGMzWVRqZkNxQmdxaFRWa09XU3pyNDMxTUFhczNnY25IZEQ4UEZpVVA2VnlCTkJTDQpYTFlBSjUxc2VqTms5SlozRGJKQVRmTk4zbUZvcDFWVGlFVjlDK1NPZ3hrY2UyN1ZJMWUrbWZSRGN3bUINCnU0NXBJY0wzMER0Y1VHaWZOaS9JdGxxQUhDdFpNVHp1WHBZSHN5NDZiRGlkME1YWExNb0RrNDMxTEVDTg0KMnlYdkZ6djJNRUxmMlRyTUcvZlY0cU1iaTNrY3oreGw2blQrVFVXVFFERm1iMkwzTWNoZ0tibVFhMXFUDQpTcnRyNzJQNCtTdVdvWWJjekV5bnQ0Uy9aaTlMWGt4RUo0blNmSkhXR1hyNlJWZFVwNnlwb0lIR2x6R2cNClpEa0w1Q2pVZGNHbTJDYUk3SlZsa0ExRGE1ZlhzRjJtUzZpaWJxNXZOL3ovTDlOMjNuT1JUellMem1uaQ0KaVlXby9NSU1ObHVZOWZOMWNjUytiWkM4QitOdkF4V3RXcW5DaGg5dXUwR2ZpallNY3lMRXNQa2hZOG01DQpxYm9ndkNNZHE3SDdPOTBrVXFJaUtwRkRrVFloSWJMSko2ZmJzMFpuSjl6Z2pLeWlBUUFiTVFRdkVXemYNCm41SHFTUnRiZVhmMTFmNytnUGwzOWhFdWc0VmRTZWZVeDRIUWY0UTQ4ZHU4bytjeTZRMmRTUTFETW1GZQ0KbmNMVitEMzFsQ3VQU2czZXNRNkVVem5nTHQyN1dWZW5LWmQ1RWpQZEtoZXRsWEg3dVJkTk9CdWRrdTdRDQpZb20zQnBhdDMyaUpBRFVQNGE0TnNGSm5lLzNpNGErWEJyR3owN3FEWnhIWlJtZUswZlZtK21GWGZnSXANCjlLTHNFUEx4OWt5WHZSVzlUMVd3TlpGWXJRTEI3WE10cEd5azNFSE1UU0VId29lTjlyTVpWVGJQYWFFZQ0KUVV3dmNuWTVqTG1ud0t0ME95aWpxdDJETU4vR3VCbWpaQUxiYUozYjV1OGp4dE5iOUFhZ1hvU3VUK3IrDQpmV0lUajBkWGhNVHNqdGVEOC9Uc0FDanJWSHVjc0hIWEF3WmNscWRMS1JPQitkMjNwcXF1bUpFbWp0TUUNClVHS21sUFdIZHZCWko5a0F1RDE3bDQxZDN2ZzdFd1M4RjRYNlpNbGRqU0pRVDVXTHhDb3k0c2ZJVFRHMg0KOXBjdzVLVU1hMDNvSTdYYklncWpaWnZjRTFYL0MwM2FrQTAvTVdXcmxMTWo0TzJZMGd0aUFWeVEvdHYzDQpkSFNOUVcwQXRJeW1XZnB3bXBCclhzV0I3OG5NUHRrVkd4MzdrOXpnTU9RemtacEJseks5UUZBZ000TU0NCmZZeVliNUp5K3p2d09Cb2dwd1BCbG8rUFZVNnBQUlJnN0RBRHBwbktyMGV6eDd3TUZEajhQQlNLeWVSYg0KZlRxTkxaSFlRNEovWERKelFlcU5yOGJPOWIzN2k3b3BYME1pU2NZaTNJd1ZVbWZDeGh5ZUcrUWZ5QlMvDQpZbHJMZ3dwelA4NEVoVEhWUnl2c0NKcmc5UTFHV3FpMmRXWmp2MFBRVFhoeS9YWGlKZk1xb1dMd0xvTGUNClNwSzB1MTBzU1hyblJlRmhvNW1yWnlMVElxRXVMNnY3bWl0clo3TW5uY096NHFQY2NrM0NDd1Z0UjBGbQ0KVTc3RGlFa05DUWpvVkJnQ2xaa1lWVnNabkswSk9nYkpKUHBKSWtVVlNBZ2RKbTBEYVp6eGNYQlJvSlh0DQoyRGJpN2lMZk9ublk0aDl1OGgyR1doWnNhRi82Z0diaGU2ZTVRSTdCdERDdkUwRnFGb2U1QVAwbGo0amENCkkyZDFHRUFnZjhWSENvMWJyMUFxeFRmZUZHckEvSnZQZFV1ZldoSGpRMkt2RWM3cEN1TlZWQ3lscXhDRQ0KUGxka0ZWWUZqUXFrV3NoSmFZQitoem9zVjZKeDFMUm8zMHo3dkxjWnU5b2VOOHFXaks4cVRRZ20yS0lODQpDSko0OHJ5TE1PemJ6SERUcElPQm9IR04vcXZaSGxEUFNjZDNpY2YzTjVpMGw4YlBPbGNZT2xrWENxUmsNCjArM2xwdGs5TWVMbzdrWk41NXc5Mk1xT0tSenA4VnQ5eEJ2WnlpaXgybjFoME4wS0hQNmlPQ0hqRkFWTw0KOHByeFNPYzJNeXVIeXkrYmE5d2JVd1lwcHltOGxpNm5BaGZIN1ZWUzY2YXV2VUlLZkUvWXMwbGFtL240DQpVUHp0WjNKUkZhSzgwNDlFbjB6RDQ1UGdGMEcwckUxZGtzcThxc3ZkTXlCdGd4SVFjRjdkSTV4dGdpZnkNCjZHYzJwbWRyOXA0NG1oVURxa0RuZjE3RlhPcWJzR3FVbkxNcGZIa3VFamJtUnRIZGUyT3YwdTFYUXI4aw0KcnMxQXhpZUhEcTZ5ekd0aDJPa0VEQUlEa0VhSXNLTk9tTmxpZkZQRCt6ODBENElpakpKdkJMbmhDNTFwDQpuQnprMEJHc3UvQkErY09ISEpYTkVUTFZpdE0yM2JSeEtQZzN4UHpQdjUvT1JoVmQ0WnRKbUdWcGdZWXENCmRzME9mTnp0QXB5MVZKZWJCb3o0SFNOYUM4MVBNb01aTWJldUxJeWErTGtPZ2pNUHhKTkJYQnpOL0UrOA0KSVg4V21IaGtzUUxkblBEblpscGphM0xaTWVrdzlHVFNJbXlOLzNnZWlNd2VKbmoraUNYZ05UcWc5SU9DDQpEWmxIQ09VQkRQYkZ6SWhmMGFZWlpOYXNneXA4TUhnSnJXQktUaitVa21pNHY4cHZWcGtDSjJLQnBJUWQNCmhXUDFHZjRKN2RtV01YRHhvS0NHWk5vdzRFT203LzNvVlBOaDJHalhSRXhJT0NuSWgwc2QwcFkxYlp3cQ0KNk5xYUVRVk5LdEpZdG93T05taDRnN1IxUElpekRud1BvOVozZFlwRWlaREVVaTNhRHE0M2lWR0E0dTk5DQpFTWRUTHp6WmVNbnhFakRrRjAwWjZPdkViUGlQVldFZEpGcmdmTjdNNEdXRUh5YWZrVllHdC8zSWJlM3YNCk5Gbkc5TW1MaG1uVDdsWGVzeFYwWGdnbEUveGVUOVdYMExhMFhMYnMzcnBrVU9NeVlIc2Z1SU5Qem1tcA0KTzY0VEtrYUl5YkxIc3NPWHpENkFibXBlRDBobDQwNmFuTUh6M0trL1VKOEZPaGgxZ1BDU1dibm9ydFZUDQpUZDAyN3ZtSnB5a3VnOVVsaUp0UE1Eeng5UStTT3NTaTNMT085bEduK1p5SjViY1JNQkRQUjRpL2k1SEcNCkdsTHBRS2MwYms0ZUhWeis4ZGNVS1pnYXFkRmhZN1drbk1OZ0pRcjluZ0pabHEwRE94bTdkZHp5S0xUUA0Kd01ZblA3OTJzWXVlMzdJQVZGYWNXM29QY2w5Rm5BN2gwYmxmMER0M2hnWGgvcUs4T3lNdjN2RU9VdE43DQp6emJUSEU5M1RqaTd1V1RWRGpLdG1Ib1pjWE13N3lCbXZ4NkRJbDRReGtucS9KaDd6YVNvRFRvMzhZdHANCmRvVEtBUXdPaTJEM0c0alBLY1FZdmpZSWdJQkhLdVlFTTNMWnl4YVNCTSt3VTA4eEliMEVFUnFoalVMZg0KeUx5eE5mMXhwaTBvSlJoNW9PYm1ML1RudEpkai9ZcVBPTHlXeHRNbTF4RG1PQ0JKVzhjL0VndlFSeUd4DQpUOU9UV2NEZzAyL3JRYzFaUlhJUmprSHQ4S3JGb0VEVTluZzBsbzF6bjlZY3U0bks1d1R2RlpBZlB3RFgNClFsbkpYcmtJd2hkWHgySi9MNjB2NUtLaVArZEVhWGNheGNadXIzZFd6c1dPNGp3M1B0Y1BKSERIekRtVQ0KTXY3amJlNXJxUXBLUWZJS01SMFJHRXJENnRUVFNOcU1scjhHenkybURLL3MrTEJ2Z25kdWVEb2tpYWhqDQpXNVNGL3MwanZOZjBEbkNQWVhtSVNuVnNjekw0RzRTdExnaEpMb0wwc05ab2dXM2pmUjNnSC9INmVHVFANCngwdUVPUmtKdTRNTXk2TVhCZVNKaWdIZUNIVFg0S0dGbjlvZ3l0UjRScnc1ZEFwb1laNVFIc3RuZVpCUw0KOEs2eUtzRnVsODFWTHQyM0J2eWc0REc2WTJqWHE5VTBWd1U5RW00cDJPcWZrdzExcElUNFJlcnZwSE4zDQo4c2ZYMDk1dFNtbG1oQmpYS3VvOFV5K0Z2OWlsYVVsMStvTE5Relh6SVhkcXl3NUVJS0FZazNlQ2RhSGoNCnZFdkxtVkFjUEJod00vTHNhcmJ6Nks1YVRGTkh5SG02QmZoVXdxZXk3M2hLUnZ6N2FoZEdPT3RaenlXag0KRGNYbzBEYnBkZWd0aXRtd0U1cXV5OXJhSTdKaTYyWG5HRS9UM0YvWU5vS0c2Wi9JMzVkTStrK2pDZGZ4DQpwU2sxRTB3blVzejlhSjI1R0ZFazczb0ZnSUJYYVo0OVpqMmlCZjZrczZRQnM1SlhGd08waXAxdGk3R2ENCkhBVXp2M241NmNITTF3ckJjMmpnNlkxb1REZFlUVU1wMDgyV29oeW1nMU8vczV6anIweFV0SHJ2NktJRA0Kem9hRUNkYzdqeUlSLzBYTHdmS3RtaGo5c0M5UFJ6S3NSeXE5Y0k5L2tHNi9nakJhVTdCdnBDRnZhOTBNDQpmUmpqeW5ScG9kQnFNbXhQYVBESmtEczdRc1AzNVd0Y1FSbTdIVitxVmdKMVVPZ2N2QUJybEtSdVY0SHoNCmVYT0J4cEdzb3ZJa2dUZE50WGdXYTh3aVpJYzRGaUdvU091QTgzOXcwVk10L1o0ZkpweDV3Y2JRcE5ZMg0KZDVRNnNvUzBxOTh3d2hoV3lOZ1FDbGZBaWZBejllT0trTEVXTmhjWEJndHY2MzNrbHVpV0l3bUJmcEVzDQozV3B3Z0tjdXIwWTRBSTF5NEg5Q3BXSHpoNS9vSjZFTkJGRzBia0RjVURQMmh0MkVXRjR4ODFWQmpzcjENCk9DazRyMHFubHRkTXNsRm1zVzFVVjJJUGkxWGdtbzlHa0owdDc2NTBOV25ncjBVSlR3Smp4TnFVL1JCRA0KUU5YVDFjcEZTSHM0VjhvWnZuWGZWdU8yUU5qUHRJT3hlZGdNeTV2SDhzeW13YmZGcE1yb2NTSTN3TlFDDQpnMVo5Z0pMbnBxOTBtNS9Cb3lTbDgyL1NqSmZTdG9tM1Mrd1NEYXlJS0h6QXVkYTdZdEtYdDlPK3pYWWINCkhya2N0a3Q3Sk5QdUxlRWluQ1NNYlUvWXNrRm9jbDRuQmEvWHNqU0duck40SUxkSFZoYlBSUGpURkhOaw0KQ1ZVTUVrTnRxNmVzVW8vUkJ0eG5VRTBEeTJPRmxQaTVUbURvSkVBc3J5czNZUGxBdUlRLzBNZEMwQnJ2DQo5RXFqTFg4cUd0blBydi9kancyVGZibHNjZkNzQkhycTFESXlialNhTkVZQWtheFJIYTlnaENra1ZPMjcNCmZvZXVCL1U5RmpSMlY0TElwWXJlREovYngvcEsySmY5ZmR2Z1ZIZUR0NFpzdHorWDMwVWRMbHNSMmhiVg0KN2Qya3BwWU5CVDFlY1BjV1JHOFgvRUZsTUVURGRGR3N6RTAzSmF2Vkt4d2FUQ0orNVJVb2N3dy80Z29wDQptRUlSQjJkaU8xV1BHNUlqMngrNWYwSFBqajFJMlZxeE9xSjVTK0ZrVyt1L1BSKzhwdElOL2JoMm5uR1gNCmZ0Skk4VnJoZ0Z1RG5CaFQ2cjhESXJBaGx0TDAvaTVtVkxDYmxyN2VxWGpvUzdrd0VnSVI0SG5zSEIzdQ0KdXNGMnA5VmFHZW9IeVVOaDdHMDVkUi9rUXdBaElaZVBqWEUyRmt1RkVLbzEzcnp1cUxBeGtlMzBhdW9MDQpXWjJ6SnRtelp6dHlmc0RlOEFFclRlcE5MZUxNdXVUanRCVldrS0FVY01pemZxNEREVVFPUzVZY1BXZkUNClJIR3dtaDlJbGhGVi9Kdmhyckhrc2k1K1Fubjh4c3VjSVpQZ3FCRyswY2ZCK3NKQW9CVW56SWNHOFFPaQ0KSFBvQk14K3E4UkZSWHBOS2RrQVR5UnVXM3kzbGFvbXk5Y2wzdjJSWFJBRmNjbVFMNEIzVXNYTDd5a1RJDQpqTDZPeTFxT29EakVFcEFVVmF4RTRTd2RPTHEzcEFvbXBpSW9FcjRMaDdZOTdoQXE1U1I0YkxMRWtUOFcNClVtL1JYcFNybHVoTW9iRGdYa0ZUTXN6NUt5ZVFIQ0VDZU1pa1lHMTlEQXA1S1VBL01vNjNoYnQ4U21HeQ0KVC9UL2MyU21nK21NbXkzU2FhRmJuZGlKWWJvYVZJeDRUdXo1a0E0MHR0NnlxVkNIbm5BaVZSUkUrejJmDQprbENiVWd3bGU5TTByNEdCaklDa0ZKR0d4aG1KMmRISGJWK1JxemRTUE9wRGY4Z0QwWkJwYTdURHVwYkENCkNKOG5WSkxQYXNyR2grYWVGRkpHdnRKT1duMS9SQnBXZXNqK2U1UFlKQlhSWlFVNjRmTFNOYmkyM0QwSQ0KZjEvY3VhWXBXY2h4YzEyM0t3VVcyVUNIdDJkOUo2WHVES1pmK3ZSYkF6UndLakNueUdobHZ4djBCODYrDQplQWVDbHhOeFROMWJnaEgvSFV0OFEydUFleU5rbVFDOXpraTFqZW0wQyszY0JER0tmQkhaTHBVMWdWdWENClIvYlVCRS91NjVZTnhRUXB3T2dXNlVGTU9QSXhQakIrRzVBRm9lL0ZOOVhvZGlQcGd4ZExTTDVua1lvWQ0KUmxhd25IdW96UjBEMWJTQ1VTQVpiQnZFVzNWOWpydDBqMHdxejZXVFprZ0ZLc0hRQmtPOTRFTHZEL1NMDQpjYm1sd1pBWTF1YWRIZU9PSHpvZWs1dzMwQnRsaTJad2djUzVFQXBWU0JiNFh3eTJINEplNmc5dXIxYjYNCkJRL21ka0xmR3djTWh1Z1ZyK2RBMFU3WDREZ3FLUUE5TkdpcnJPYmF4Q2hNck0rcDRRbUxsNkVoRWFCSg0KZzBsTWdWSGZ1aGo3UHpNY1hzMEpZelhjUy9uaGUvcXhxMTFrT0haR3BRYlNKMzkzQkVSS3NVZGJpaXovDQpzREoyUVhmRlYzOTNVcHo0cVl5OUxGdVBNRWZhMEhXVldlWjI0N3RYVnFFOFNkUy9qTG1PcWhsRk0zSk0NCllaUEU3bENGenlQQUwwVXl3SzNqNk5udzFUSWpVMTVyTzA2VXZnK0t0RXdPZlBPY3lBOXdIOWk2bkxUeQ0KeXQ2K2kwcmxVMExDcTMwTWRSVmQ2K3RUSW1XUlNCZ2o3RHBlZ1hIZWV2a1AwTlB3eGJvQlJnWXgzcDNvDQpEYUs4a2FaaXMwK1RQYUNaelUyWnE4RUdHREdrK3QvNUpJaXBJK3hsWXBsVTVOWi9ZaExrQTlEUVBnTWINCnQ1clI1N0hUUUdwUlNXMUxPQ1prdUNHYXk4eUpJZHp4NXpueDIzK0lyYnBRVlB0bGF3QlFXbHBBcWRFRQ0KblMySE43bk14QjhuNTB3MVptajRoSTBIUm1qK0NQeDZPUUZ3S2dwZTlaUmFtWFZVUFVsNkx6Z2JpZDFYDQpJUWJ6R3FJTE1MY0I5ZkhqTGdNZ3VkLzlOaEF6ZGRUajJmdUpEdjdpak5nTmJabjkrd2djTDIyV24vWDANCkltb0FFRjNkOVFEODF0aXpSU05IaVNndkw5QmZkMWNYNjMwZit4WFp3V0xGWVRCM3I5UGV4ZDJKSXF5Ng0KNjBoMTNMbzZ3RFIwZTNGNExRVEpudzRvSEcydCswYXZPVzZiOG5uQzZQV1pxbFp6Y0x4VG5aTzlWSmF1DQppcW9OYjdLRWtGMnJRWExSdWROcC80NXNNUGEwWm50WUtyU24xbmtCNUJ0SlpvUldoYnBiR3ozZ3NhMGMNCk1zRkxEVDV1M1NGYm9rVHo4TkVOR3RzT1dkNUMrbURqNWsrb25PajZOQzRGdmF5bVd5bVY3bGNIMHR6VA0KczBzMXU1a3FGYmU3ZlFIdzdhUVUvTW5ORWExc1ZoWmpmaTBCSzIvVXVvVHBzblo2Z2Vyek9PSW1NeWVXDQo2aUV0WkU5NWpKdlZPREFrZlhBbjdnRGRqUXE4bTRpSE5MTlJkSU5SWWpYWXFQa3ptY0NDOStRTWVza0INCldoUXh1WDR1V05IQUx6bHhxczhYV21PNEpxbndmK2ZhR0VXV1RuR2ZLMHhlQ1NmRE9aSktXQUVQNEhrSQ0KdGhxRXRiODNwSFFrL2pFeWNiaWp2Qm00dW5sd1ZqR2NCbFVVSHhISUVMandMWU14YytnSXJ6ajNYTlJZDQpGeUpJaHhJelIwWGVOc2ZmOE94L1Voby9XVzBtU2xnS0NNakxEenZxVndXQk4zRjlISXA5TDZQT2R3bWUNCjVSRUxnM2wwenpOMGNoejNhekpSMHNrQXFmVk42eEpabGlhUDNaUGJoSU5CQkE3dzc0ZzJXdHBDZzhqTg0KQUlEcWNSSlNyVVovUXE5dHpmZ2tvNzFRU2NJbS9oQkdKamM3b1BYNWJjZEZ0N2FVY2hXOU5TZ3dhQXdXDQphRE9ROE5OQ3A2SlZRaTRUVWU4eXNnb3Q2TDNmUUxLT2Z2RkpjemhwbFNMMnQ4b3pkTEx2azZoMTNzRk0NCklZdDhpeVIzSHhNanNaMTFtVkwxOVdIeFFLN3EyZi81eFdCb09mQ2U4SzBMSkEydmJ4UkZjbmpzSEVhQQ0KUWp0SEo3R0hNUEZ5Q0hFWlJ2Qk1RUk85ZWIxK1dMNXFZN0lnYjdBZ1YzQmU2MDk1eHgvNGpoZTlpRDhVDQpnUG4zakJhTU5XbmxCY0FwcjRTZzRsaXRFN0tlbUJ3NGZIbHdwVk9hZUovMkd5enh3cCs5ZmRnMHJ3dFENCmFxZWRraE1hWGdpV1IxRmEraGdNUk9kM0NLSDNDZit0UUpZQVlXUzdTUG9ZZDA3ZXhzWTdCMUFUNDloSA0KNElvT2E0OVdBWTVERWhPZUtDNTZuVXVRVTFaOEJaVG1PbjcydmtPVWg3UG1sdHdjT1YzSDlDdGd2L3NwDQp3Ymw0M3hTY0doQ2E3VEZKK2NUK1Q3Wnc3UU91U0t2WktkOTl5QmVVa1c1R0VFenJLRGhEYVB6RnczSC8NCkE3MjU1VmxPTnVuQVFCVTkvU3c5eS9seElTTkNUdXZ4SnFjQTNBM0dxZW9ZSkhBSldJWXZJRUZ4ZzEyTA0KTWNDTzA2YndreWpqLzNoVEhCbUJVUDNRT3djM3JXTnltVmxVdU85TzNqRWZhcVVLOHBzc0VUYTlrUjdQDQpCV1IxV0lSQUMwSzFBWmsySXVXdWowdnk1ODdVelJWV0lqKzBjOURuWXNEM29uckp2MytwMmJwQUZtZXUNCmR6K1VGRHh4UFpBTWxlSUovaUlNVG14U3gwdlNQVExNTnQvdVhmM0s4R09kN3QxSHRmSldsc0lTajNiLw0KdTl6M0MxaG1yZDBOc2ZpYlo4S21yL0VVanhmMDhMaE9ZRkgwSEtYYjQwcFdobnNKU0dpZnlsQ3gvNmRpDQpQRGNmVlk2OXE4STRCcjcxaEhXbkk4UlpBZExNMGVNMUUyZzM4NFhZd3BobStkd0M4Q2VsWkMwV1RwQTYNCmhKQ01XT2VuZUdXRitCRXErbUV5QjMyWTNJc0RPOHl6Q05pVVRDYkt2S2hXQlJsdHFkc0hIQzZUZzJSMg0KVzN3MmVaWllpRzJsTnVWaVlZblZ1MkU4QVhuMkJLK2NybzdQOHltalRLSk02d3lWZU9KQWloaUFvaXVyDQpqS0l2SkFKZGFMRlJFYmVYZFcxd1RYd1ZpWTJPSHZPRFluOXB2bllSa2VreTM0UjNHUjFaN3NrV252ZEMNCk5mSE1WUVVpRy9hai9FNGg4WVdrRjlKdnpOWk5YckpxckVDaGxrQVJ1aEYxQi9JL1AyZDdCeFNHMGEzZw0KV3VqdmF2U0JJTStMMzZjbWg0cGtOUXVMeFRIdUNQUU5Fb3RZVktjcEp0WjNVYk5ESFIzc3U3UjFPRXU2DQpGblNCZHBxRDMyY2dZSWJMcGlnaVZjTlNSb2tBYnFkSXMzSy81VmtNUWRYaEphblgwNTNKMkxxYVBsNGwNClhsQXBZZkVqM1VWRW4yRVg0M0dZZEZZaWduTmpJYXplTFFPa0FjMU9abzZwUGZXUW9laU9xSHFhYjZ2Ug0KdzM0NW5YK1gvRURtVHN0ejBjdEJEajRoK0RYcnovREJ1dm11cE01b3NiVUhIQTNic1dUWVhtd3h3YmpXDQpOdnpnRWlsZWMxS3VoVUU4bjQ4YzhqeUhWcjFLZDRwWmFVQVJ2UDBFVnV1Z3hBKzRkQ3l5NlZvb0lBSzgNCjlVcHArb1I2cWxjei9sdmNhMzZIYlZGMklQbUpqSFB2Z0NObkExSlNVZ1BFbzhyT3BQaHhISVhHM1pJag0KVWM5VlRXODY2cW9YSGdUNkcxYjBxcjU3dGNIcTA1NjIwUStlVkVFeDd4UkZZZ0dEK09KTDJhMXlKZzRnDQo4T2NaWTVpZm1EM3lrV25PVWJRMXhNSFBZK1lYR1hQcFRjUUVCaUhMTk5BNGZ4amFxVWhQdkdTdFdSMmgNClFVK1E5N05NNUxrMHZRY2E0b1BDb09DL0tWTEI5aU9UQXJnQTdvQlV6OXY4amJ1L0ExTjdUZEdiZm5jYw0KUXl3djVpb201emRhMEd4SnllNGszTDJ2L1ZXZWdsOU1JbHV5Yzl2b1NGUU9wUEUyK3JFdHc4QXhUQ01ZDQpwd3g1SlpWT0JPTDVLYzE5Nk9ldUxyYkY3VVlhZHpvd3hkcitvTkNhT0F6Sk5uclRnVWdEcmxGeVFTbGoNCm8zbkJNaGo2OGE0d1krelRlN2FuV3VJVS83bEhiS2pLeHIxaUt6ZnN5R0pjRUM2WEVxT2I1NlFmcVFGSA0KT3MvUGQ3RmV6ZEtnc2NvMzJVK0liaGpGOTBLWWR6OUxndVd0c3BEUlh2bXB6TTFXTng0YmdzdEdwbVhGDQovTGJzcTZKRWNnZHQyc3AwL1o4b2hOakdrSXZzKzNScndDc2tDQ3hDNGlaZUtLdVMraXR6RktPelRKek4NCm1Vd1pQbUtFcURWNlFvUGp4eDYrNFFIYzU4SU5aRWRjVkdGSnZlYm5aQkUvMStKVWNiTml4Y0QzdFpnaw0KUlh2bEkrbXY5aSsycFByWkdmK1R0UmIrQVpCYmg2b1czcmY3VmsreUM0QlAyTkovTFpPOVFwRTdQWjJDDQpmT2VhMUtINURBTFFMcWNsM3diWGR2bllmRytSYzFYWEsxYVlob1pVRHpzNWNINmp4b1hEeDYxSG5HNzkNCjllVjRJRXJmUkF6Z3RUTWZHVEJDTVJha3FZWnJQMUNEOWNZSFNsd2luZXY4YS83aU1vZUcrU0pSU0Vvcg0KcDZYOWxNZStHRmtXUkUrbmJhOHRkOS9DNDZhWW8xYk5YWEJISnBibXI4TEMwaDVWS3ptZExxbTYvbkVwDQp5UVZJdkdsSTNnMlpVSENQTENVdi95SmZWM1ZSNXN5REdFQnBsR3RFWURESW16aUpkb3BxVWt3azFjQVMNCk5SaU44MjFXelRxY2JXODBtMDZ3VUlQUEhBOExhL21TWnZnZ25kazBocks0eFQ4d1dPUmQ0bHhwZXU1cg0KUkc5NGZiU0F5L2pwZXk3WGhWSlozL1drSkZFOWx3QzYwWTJjeUtVM01UdlBYdnJKWGhwNmhWa05MMFlkDQpncUFnMC83ckhEKzgzdUNrTFBLdms5YVFLZ1E4VWF1OExwelpRTTJlN2kvdXgxcmtQSitNWkp4V1FzWnUNCloxYnlhS29NTzY1Y00zMU9NMGdXRGpQWlErSlRkLzVicUhJQ2ZBajVRQ0QxZVV1THFFa1NCZk01L0U3eQ0KUmRvT1FNNVlMRStNd2R6d2RZV0pab3BGVVprdFdoWXM3UnA5OSsyOEpzdTdzQ3FHa3dYWXJSM0RWRnhIDQppVlhKbmdiUTEra2xuRVp1c29lZmZnUGg3Y0VUdHRFYXhYK1pGSkZ3WHRpOGRyOGxjUndRdzFtQzZRVVUNCndXblFOcFBwT1BHbmU2dHRBN0YvR2pqYkF1OWNVNDRZbEZnUVBmRStPUDhyazBJNy9DTnNmcXgrMzhsTA0Kd0pVZUlHWGJnOXpaWjhkRWRUNWhTME9LdWNtUytreXF1WWlwU2pYMzBGcm9KYWV1aWx3WnJkWUIwaXUwDQpYUFFibWlac21sN2QyQ3M4QWgwL1BJd3R0QW9sODVPNXNOcHB4a3FoN0swVHNsMENlK0ZQTDdpTVpsdncNClNiY05yd214cG5qTGUwbExUMVUxUEdLZWRvVnRkYXpRLzJHZDZoK3YxUVhjVGo4bmc4c0tCdGsxeEdhcA0KT1FreW00Z0JXK1Jnb2hHdzJ2bnR1ZmliMnRIeFFxaVo3NG1RTUVxWm8rVUFiWHlyZUdsOXY0MUZ3aHg2DQowaVFVZFd5am9ob0l6MUxyOUU3NGg2RkxYZ0hQejdvVzd3K3V1NDY0WG5XVmtIYjU1anc1R0p1UUk1WS8NCmNWRjRjc0tybkErMUQ0N0tUM2xEZVo1ekxndkF4d1paaS9vc2NIK3RwSHdWOVNzNUNNRVh1OVl5Z1hleQ0KYkxHYko5enRvODhxUlREeldSeUdWbGEwN3c1bHFsNXZOTG9uZmxjMUlnOEYvendJejhSU256ajZFUzlZDQpsNnRrN0E1N25lRkdhMWFkYVQ2TUsxNFpYMFk2NXVENWZWVnFJd0ZmSmhMRjRobWlvUGxXdkZwTGFQREMNCjE4V1lmeHlSUUQzKzN2K29XZC9uTWtFTHdBcDd5aUZrYVdwdUhiMlpPUzJkcUxuUVY5OVkzUXp4VFlMTw0KZWJ1RFJTNTNwcm5hS1JZMkJTbDhYZjVCMndYUFN1Y0UrNVBtS0hjb2lPYjFhNytNRkdETkdCc3ZrY0FpDQo0ZVJ1d1B4bFNYclBxNE51cVA5VjkrSzB3LzlqZGk5UTlkNFlPV0ZOWUVPWWN1UmZob3M2WjBNdnFzVnYNCmliQ2U4aGc5aWNJRHRPb25ua0ZqcWxqZUVOQVFmU2o5ejROMHN4bThqOXo4ckdLYjUxbncxYXhrL1NMYQ0KQkQ4cWpOZUFNakFqVDk4NzZ5ZmZDd0JNOWw5cUE0Z2ZMSSs4bkw0Rmg2bllZa0kzdG1qMFc2aGZvcWZhDQp6WkhvSjNobGU2SEdwdWhTaWgxaDBPR0VMcUQvcHBZQ2ZIUEZEaCtwNy9GQzNpdW8vOGkxWndQRTJtNkwNCjQyekdScGN2WG9hWk5CNitXNkdyVUpEaGovR2dvS21rM0ZGbnkwWVNIWi9Ubzk2SnJPNlJ2VkxpTXhwVQ0KZ0E2b0VGaEVYejNkTmZya2pGZVQwRy9TOVh5RUFKNm8relFCMzR4NWdiU0lwTGhmT2lKYVBTOUxuRlp2DQpVdXNGMTNWM3hLQ1B2U3BqRHF5OXFnQytjREQ5Q2JHUllBV0dtMHE2NGRMYXkraGJkc21sZWpWNzNLbkgNCndnSWczTFVkOXNOWnUwR1JlMlNuVmF4TEdXRmhZMGRlZThxdGxRMWl3bEJ6dWxtY0NNcGNMQ3hzR1JYeA0KSk1POEVXNHI1ckNCNGVPM0dqT0c4TzFzVE1JS05lL0ViTG52NTJjcXIrYUdzU011Ty9jenpZMkRLNzBHDQpGeDVVM1pPMmFXQ2JkQitsbEY4dkh1SGVteDlCUEFBUEx4QXhmR3pxdEFIREtHNWExQmNzaExraUZsdjYNCmlwN25BOStXVWlFVVJ4REJaN0tkUitWMGxPQXIxZm1HM3NyN1lvYm1WSnR0cEVIUTJvV1pDcit0M0dhRw0Kd0ovWVRFMjZPRFV5bzNhOWFvUUtYeUlkWUFSc2dPM0s4dnlHZ3NTMmUrajBoYkdxNXpSVmc1Y1FLMDJpDQpjeEpNNkljTEhXS2l1bkxoNE9JMjlSd2VDMElxcWdUa240aG5YWUFSWTZYUHFZYmxhdU9yeWVmTVJ3QXANClVNVEQ4OFpTNXpKZ1h6SkQ2aWUvR1h3UUNRR3Z4YlJlU3A3RWE4bnJUaWt2NzE1R3dtcDhaRXdYcG4vNg0KSUVJb01HVnNnOHoxZmJHd0lrTks2S3Nyc3pSRDNGNE1heE9iamNseVpTdUhEVUdZMFh5QUVrTjZ2QkExDQpNT2ZYVGFMU3Z2cGRYWGhObW5OVndmYUN5ckRYNmZhVVA1UzBzcDJFMDQ2eXg2NDZCd0VwQXpnZ2JQZlgNCjhqaC9Rbmx6THpZbU1KNTVFTGhyTDdOWEd6WTh4QzZ2UVZiTzgvL2pnSFRrYXdOelFCcTJWME5wc3ZZUw0KSDUrNGlNRDMzaU96RXB0REFiWHM1ZldEdytqR3pteVNHS3NOZjVmcU04dUE5RHJIUXR6MkNCVG9ESTRKDQpKT3h2dDI0Sm9MNk50WjgxK1pMWEpuVHVTM1VRa3RZQkMvcFhpcUt3dTlsK05zZEtZRStGY1U1V3pzUEwNCkVlbHBvVEdHSm9qT291cUFJOTdjWnRZNWFxTGN0WGVEVFpmZFpyM2s2SUJ5bjRCeU92eWY0czFzWmVEUw0KYUxQTk85YUM5ajZVdGVSMGExazhDWkRrc3B5RDJpb3JQNllDcURUYTdpVEdSdU9RdzMvTGVsSk1TeWl6DQpiS01vTVdwUlU4ditGVHFKcWl1TURrV0VrZGpNS1Z1R2UraElQb3Yyc0EyVTZLOG9xZUo0QmtiYkVOQmMNCjZJcXk3bEZwQ1pQZFUyZk12eDBIbVJMRmxlSE5pai9ydG4rRTBXSFBIMVU5aGZkblpmWHdaUGVOdjRjdw0KRnJCcEZlSDB1VXdhQTJxdnFKYUNBRGN2TllvYkxGQmE3Mi9TRm0ydjI2WmVQczh2Ull4a3ErbVBxTXNGDQpSVSt3RHB0VEw1OHRQWHdwaE5pL2hLNkZMd1A0UDRDVWhwTVlRZG5yY2w0ZVk0dVdZVVJSYi9PdTRxbmgNCnpsb25CaUxaNUhKdno5UEZxQmFjM0x3RHlMTGdCWjRqcXc0VFI2cmdOd25FRUV4dE9PT0x6R0pTZVZ2Rw0KMVM2bU5TUXNtY1JMaWF0RDFoUi93L2tvd1NWYU12YUtTeGZHZENGcGVtajN6NVl1U1dJMzRCOGNaL3o4DQpMTFlDNnRWOVZWYUV6MGMzRVFMWkQ4ZjRwUTRNUVhLbDFTUGw2YUFvYStWYTdSMVJZbDF2RUM2T2tBWGINClN0ZTNLTEZUNWUxRFFjdTZQWG9FeFcxVGgyRnFJbXlHZE1NbXNncktFVysveHV1ZDhOQldaVkNiQWVOMg0KZkxGcy95c3F1WjF0azBZdk0vdFhBOUN2cVJmcFR1RkZtRGtVdGV5aG83M2Zybm1kK09hd0ZqWXhLYzlYDQpFbGNlMnBiazNnVnVpbzl5QWJBSmtpaDdEMkJRSXZhMkFTbGtUZnE3cE9XSTlaT2tHTjBlUDNTdzlKRk4NCkFIUkFOM0FIendEa3VqOWJzQWJiWldYTGtLZnBJRHFjMlQwa0kyRDgyYmJYTHhUNHlzQmlqWG16TFIvNA0KVTY5NWROTjNmTUZVYUFGZitrdFNENFpvbG1OcWVqNUhORThJSFU1aURTZnk4eVM0Y1dkVEVQaFpOL3ZBDQpVMXBrTkMvOTdBcEtiek91NUZVcnR1L0pYS2ZuWnF2UlZ3Wi80Wk1GdGNFSDhnczNMR1hoYmwvbDlqNVUNCmRoTVpDbVNWa1RjSkRualJBQXZORWVYVDJNWUpqUllCTys2UWFmQ3dpckwzUUdtRUFqcysxczVvT200ZA0KMTBMcG8reEVyVEw2TEZueFg0WHFud1FzQTFzaHpDdlZpVTZOUGZtK1U1amZYZW9QOXJ0NUdENWNOcStHDQp0a1hvWmoxT0c4czZ1QTZ6WnlQVnRGOGFpYXdVQklnSkFQc2VTa1djbGJjZk1DelE5d01Nend0bklpeWUNCnljd2VCbGJWQW5mSjNkWDU4WGVLS0xVTGJnRW5ZTldmb3lic3lUa0RlVi93YXI5STJJck41SWFWRi9haA0KMUEvMnl5N1h6UEh0UzVRcnRSZDJIalFzWU1QbzFFVVlaVzZ5eTA2T2NCdE10a0V5OGtkNjg1cGZyOTNODQpBZTMwblIrMzl1R1RyMVlEdWRodEtha1g1YkNXNlJUWVZXQ1B1TlIwbzJkdWZNQUpidVBDekMvb2JhT20NCm9ETUsyalFMNmtUTWhGb3BDOWgzeHdjNHVpUlVXS2RRZkFmQ0MyV0d4YjV3bFQyTWllTCtuWjBrdlJmZw0KYnIvUUdXN0RCUzEvbjYzNndnUmRCOGp5WmU0aVR2NEJ3bUhEcStZczNJd1U0Mm1Wbk5PY1NRQXdGaEgyDQpjTVArS1BnVkFkWlhWR3gxU2JyY1AyWkZXWHdPektjNjZySDQ3MWlmdG9WNy95eFB0R2h6OEtsL1U4dUMNCk9KTWozR0QvN1pkdkNOL25JSmNsdnlPaE5ybzhZZUhhYy9sNXdJaFA2VW8xUnl6VzZoNXZDWEdWaU52aA0KNzlucmdlb0VONHJDSVA1WGFTSWZtOEhTL014MUJ0VHpTVTV0bnkzeHNiRHZjZE5EN2lsWEtnQ2ZKOHpxDQpRWDRSd3JQQUJoa1JRazZKdXNYVFRRNDhNRFRLV09KeHVWRkJXbGFwUVVkbm9UaWhiZFNCdGF3TndlbkkNClE0bzFqQks1SVh0ei8rZXY4WkF3aGpiUnVWSXR2cmNFMGFtN3hZa0tGbytDLzlpOHA1Lyt2dXcrT1ZvVA0KR1lhekhDQ3pkalpJWFRQK1htVm1JQjdHdDlxUWdpNTNqRW1kaHlwNHFvTXYrbk5UVmZqT2JnTHdXeFY2DQp5WUE1L3dwblg2UHdsVWtKOWw2NGpKVmtDVWcxVUZTcWxyRDZRNWNMYm9IN0VFMkpmQnUvdVJGNWptOEYNCk5UaWNNalJ2MXVVYU1ydHYzUFFzZEc2YnlndjNVNlZjbzVmaVRUc1BBa3dqNW5GWmFqeE5iU3UzWHphbA0KS2xyNUN0N1g2Wm96RllSdmRNbHpPTituS1VvaXErR3lBREhoMXVvUW4zQzVtQkNTNk1LaUZ6TGRLV3BVDQp2Q2lSWW9idmJVbE5DZnc0SDdQVVEveFNvUldiakZpa09LY0o1WUlMM2ZOakZuME5xNE96WisvQXdIeS8NClNCZXpjU0w5N3VzUkNhamxyK3hkWG9VVHJJRHNNbXdIYkRoVS81OHF5Qy9jSFF2czFxR1hxYW1Yc3ZieQ0KanNqTnNtL1JxN2VYU25pc1oxOHhiWXBpOC9KWm8yUUJORFVmMXdDVm1GOVcrRHVWd3BOSjlYd0psdnhHDQp1MDB1ZVZHdWF0emt0NStGQnNaRGsySnMzRnpadkdpSkhuSmNjYUdERnVwcGl4d25XUm9oL0ZjMS9DNW4NCktMbkRUTnNjTkFCL29aRFN2ejFLQm9lL0hoY1ZTR2dHeFByZlJXaGxvaDZiYzRtRFF4K1NTMXpkTnZIYQ0KWTdyVllsc1lNYXNFb0lXQWdYbUE3SjZBN3hQeGhaRmNhd0dPZGlqNlpualFNUnR1Tjd6dm1JSEJFQm9jDQppZFU4VXp1alEyekVXQWpXS0psWi91KzJWVkp1UnVSK1p0UGUxVXpENlhTUmt4UUl1WDBZSkdYeDRPSU8NCk9pSUZ0emszMWgzZWZvc09FcmlBS2dFWWFXK1l5ZHJUSzdIVEhkQjN6VENiVUFia0NEV3pYZDhYTnIvTQ0KZ1c5a2ZKWlhELzJUQldTYm01UjZxbURpSHlQSHdwL1F5cVlibDlqSnRTR09UMktpOVh2QjluV0RHaVlyDQowQ0daNkh5REk3WWVmMXY4VmhwYm53RFNNakhSMEtYclo2QmxCbXVCNi9KaUFBNm1rSlNrbWRLeW9rSi8NCnJvWlVmM2NmY1dqdytQZFZQcjdoWEViMEhXV3h2QjRUU09zYTJhdXdMUCtuOEN6bmdIdkQyb0c0VGxsbw0KL0ROTmJ1ZnZnc3Y4K3dBMklvNE1yb0xCODN0bHJ0Ly9QOUhoLzNUUlBKeUVrcmYvUXRFb1VyT29qb1hlDQpEaVNMYXZnNENsQ3czc1FaMU5vVExCUUlUZzY2UU9hZTJsZGZHZHF2U29JaisrdnByd25oaWV6cjhXS1MNCndqU2ZHVnI4UW1MaWh6WEk3aENBeEZMRXNjWjVQV09lUjh5Z21qMzRkb2oyazJWWTNMNUlXeGNVMFRrUg0Ka3VvWXp3U0F0Wmhsb0Z1dEdNdEpLQVdpNTBCT1M4SFFoVkZZbVl5NXhLaXd1VHJqeEZWY0tRSnRGUERJDQphSlVHek4rT1U3K20yVFlWa2tFbXRRdmdKb1hpQ3o1d1ZwNVJWZzFQdlZKNkJGZzBxL01SQzBOWGN1S0cNCmFlZW9QNFFnZldWd0REME9uUGJxRGUrZzVUZW5qcFpuQzQ4N3FaUmVXa1M0RkxtWDAwQjNIbUg2azFEdg0KNVdQeUp5cGtURmpUcjUxN0tEWng2RGdNMVNyNHVRRllUWUpPdEpHMXQwVXlMbkN6ZTE3NmNYdU1tM0EvDQptT3FNdFJaaWVNTmc3SHcvaVpsZmtYcUk4NzdBWGRKakFYWXV2bEVBVnZmOEdHRk0xUVBia0c0TXhsOEkNCmhWQ2F4aGViMUJ0eGx0U3lLZE95OXFlR2RXQWh1K2MwVWJMcHhSb3pGS1dEa0RzcFZ2S1NGMS9YZC9UZw0KQW9Ram52cXY5VWFOQ3VmOU50WG5zMFRQRDNJZ2ZQVitlbFF2TC9zNWE5YzZRbldYcThiZ21DUlNqS2tmDQpPVk1HeEVXQVY5dzlMYWFnb2pwZVFsL2xMNlovTTlseWdndVB4ekhsc3piN3VoSTJnNnQ4UGpGQjRXTU4NCnpNNis4QWc0aWN1Q1hnSVZaYzVXMUNTamtKL0VCbXdGSGdGSXdJdUp4MW5pN0EwMmlOLzRQSXZ4NFY2dg0KRThxVm1tNWVxL0F3U0NXNHZuSEI2THpaZEI5UURocWFudFBGeUlwQU0xZWptQWhaS0FSbGErMlpDWkhEDQp0aTV4WG5yczN6LzNUVElyaTJpaEdJNlI2bmhDMlhTcC9ZYVg0Vmt1aENxZGtvQUlQR0hDQkxiUlVxeFANCjZnZk5KYndtYkxlelhKMEZhc1VoU2t1enVtMWdhRXVWNExHUzNwaVdPZEVvdm9aV1dGZS80bHRURWxJbg0KMlFncnhtSWRpOFZwU0RkNHE1bnZxS3c4aDhydmVvYnFIMUk5eU03ZkpyYWhFWk1NMmFIMnhzaGlOeUNWDQpKbEhWNUtwV3ZUWkJ4ekNReCszQlpGQnd0ZnAwT2poY0hveFZKVU0zbG9wRzBBSEtqSjk4dWRiaWxZMisNCk55elNNZDIvWjZNOEJCVDJ2YkRKSFFBaXcxYjBiRnk5TXdCc3laU09ZNU1yRkJKK0tLL3NHTVRyd3VQNQ0KL1VZS3NuS1hYQ3hMNk15N3Mzc09BSDBaVGFNTDhjUGxTTzl3Y1JpQ1Jwdzl4aFhHUUFRY1NkeEo3bG96DQpxZVg5QlF3VG5YL2VTQ29jUGNwdXpmc3ozMlpRYUI5dHhtTWVNTVg3RmZ4UU5NdHBTQ0NnMkhBY3VSakgNCkZudThRL2FZNFFIRWZFMVlQVnBQOVlXZ1JPSW9hY3VJSHdXN3loNTNOUnkrbkppRlArUHRWNGl4R3BDVQ0KRlF0Nk1jRWlYQjZxczEwaCtsTzdiZUVRejN2c0hDc3lGc1A0azBPL25sRjVLUi9UVUY0c0p6bHRUREpBDQpmQ1BFR3JoTlBXQzRjQnEwS2d3K0tydDF6MmMzUWVUL1RxMThpdThpSUlrS0xZQ3NWTUxiU01IYUlybFgNCmZCd0tjaSs2MWdOYTVkYTFwbVQ1UmRkL2tNMWNmVTUyK3BEbG1iQWppeHhJRG8rN05lM05rREhIeDNDRw0KTDdEUDlQc1BiOGw0SHlJY0Vka0g0Z3NLQmEzOVc3b0RZS0xYR3IybCtOMjNPVGhUcFVvc3pXV2l5dThBDQoyMU9rb1p0N3dJb29xYVJpbWVmREp0Qm4yQWFyMzhHL3c2ZC8vUnJzZlZzdnVhR0p4SkE3QTVDMXl1bngNCmdlTjdHZlc1djhGK2VGU0hXZ3hSL3JLM1FOZVowV2R3MldYR29TYkpwUmZIbWRVNWlwd2ZqcitiWGNtVg0KSmFFM0JIU0RaeVZuUjVPczZ5TDRvQnhQOVY2NnRMQXc4L2VMeEp4b3JTTXluVDNDRDZJc1pFREFmWnhhDQpSMnhZankyQVpaZlcvZTVrK0lzdzlwYUlrbUVxTTlHVm5OWDhuWWxadTFPbE93Um9EZVViTGkvc0EyMWkNCnBSSllTWG16WWpzQ3lpL0RaT2t2NWFzNkpTMTlPMWVISjJFbmwvMml1aUpLZ1NGY3FSdHJFQ202Uyt5dw0KUnJBM1Uxc2N1T1huSzBxMDYreTJpU2VabHVLdHZEUDBzQUdIdXhKMEhWK0lzRVNTeFlmQ210Mi8yTFhuDQo5ejRadEZadG5WK0lNUVptRWpmRC9FMkd5VG9iQ0dESUJlVHA5UXJkYmJqRmVhWGtlVEJQcWY4b2JFYXINCnNSNEFWNjFQTFlPbzJIelFkOXR0OEhjdk9tTWhDc2JzWEdtbUFEQmlyK0RtN012QWN1TGRLN09BOTI0RQ0KT0dIdkdKcWpTZXkrQmJkdTRFOTFCei9seHBxK0tvV0ZGQnZGR2IxZHUwWTF5aVBMTHRvM2xjbzAwU0NoDQpHR2J1eXZzbU1qN2VGZEwyYmJHWStubnVsbVZFVXF5T2oxMTVvVlpCblc0Zm9aUjVzL2g2NXhQcTYvSlMNCnAxV2ZoaXIvMlpqcTk4VmQ5eEhTU0JQN2hsWHVEMDg2S3ZPY3hiT1JjWW1Rbi9BSWlaWEY5cDE2T1RxYw0KMXVwNjJGNWljc2hLUUFBY2pXajhIbjlXY2lUT2tTdmpXUkxPSzY5dGpZMEhVUUw3OFdLWlUyNWZhaTdKDQo3d0V4M2cvNWM4ZVl2WE9ESlVXcXFmV1hoK3FLTmVEcnRGaEZuOStFQ0cxUGNpMjkwbEFISmgwWkFoeGMNClNHSDE1K01CZWg2emdPVXNqTlhQd0RLVmhjY1o1czFpamRxOXNST25XVUhnS1UxQTR0Nk1CZ3lhV3NicQ0KMWtYWGJmUEJGS0NiUW9Ba0NmeGdrdDdqOVQyMVN2MVExK2RIZk9BY1V3VmZSUG9wbUVUYnhJNmNiK0FMDQpHYkZyQ0crY3doMEJnWlhkdWp6OHo3L2c1bmZYMllFdjVGdkUwa3FLQzVSU1ZDQW1MZmdhcWtrNEJ6TkQNCmcrZ2pSZnA3QmRkN05wSDczNUhHMWlUeHkwL2pxVTlqYnRHOTVkUlVpaVZ6K0gzbXVOM0xRUXpxajJMMw0KUHU2dlRCMm1LZWR6RFNJNnhHMy81V2FZcWJ5NUU3eEFqOEplbTNTUmJSRnhwODBaNWthUkp1bkowQ0oxDQprckN2KzNFOVNwU1F5bHArR2x6ZFlzWngrTkVHWm1Va05RSzhvNlpRTDB5VnFIaWg0c0luTzFZYkMzamsNCmorUlQ4UnJ4U1pXdmRlL2k0eXdUdkMxRUcvVUlLUittQkdjT1UyY285a1h5ckpPY0xkMUR2VUpRM0VZaQ0KeENYcTYwL2wyODJ6cEVWbC9PWmhMQmZ1eWxUdzR0aXdPYU9hSm5Kc0EwbytzcWgwU293VGR2WnNuT1FTDQpKSnNFU01aUGhxcjdXb2sycDUvajA4c2tFVjlJRklNTzhWVFdBTFNPeXVSVXhkUGZkek42RUxqRUszR0YNCmoybmtlNlJpWmN2YVd3RWxxWXVlalR4dkRsaENlK3V6clZndVlUYWphaUJ2Y1o4Y3FyQmU5WGM2cFFpRQ0KTHhmcG8wb2tyYVB6K1Zwc3dMbFgvZURsNU5vdTBuSUw5UlF5YTg2U25iVitQOEJkNXAwTFdnbFV4NlBoDQpRaExkOXlxV2F2eXUzelZXcUxVMEZ4ZWtCWkJkZUVSQXJyNFRFbXAzcnZrK2xQWllURnYva2g2ejQ4T28NCm55MzJCb0RUOFg2TU9ZNkJURHFpMG0yRmNzaXlRY0lKWXpITWgwZ2gxZ01IMGtLOWZVSlZHTzdTeVBWYg0KWkxGbUZQREJaaHYvWHZiQmlHRVQ2UjZMc0F4Z1lMbGMvOGdyMThIZys3WFdJNTVNRXUvWWdENGlZKzUwDQprTmVXWmdyc1FFSWFuYkh3RklZM1JBeWlRVDA3VjBBaUFGYWgvM0llNzdLdVAwQk5aTjM2Si82T2NNdWgNCi9IN1FUcHROeVR2eXRKdnVPOUZOZnB1N2k4UjhYalY4b3RMNGhMMXI1Z3owbHBUYnBWakhvdk1sSE1HUw0KakVyQ1hUZ3hiN21FUytvOGZ2T0JzT3ZEWmwyaklKelN1MkQ0ZWEvU3lnZGlVeFpRT2hPdUtFSFVXMGFEDQpDb0ZTVkNCdEdWb3BtYS9VczdGRncrbXQ2K2RGeG80UjBUL09PV1pPYWRsWnFva0RtaENDaW5qRHd3ZlQNCjJOUFgrRWN4Ynd1WmsxQzFOMmVuVUU3dzNvdEdLWjU3dTY0UWxyRUFBNnFORy9qakJwSFlXdVdRSFlwOQ0KUFh0dXBtV3NhdVlyckVJblVOa0Zqbk1XUTdVaEY5dUsyVHowWDBjbWJ4bER3cFBMV0Fqei8yeFpSOGJ0DQpjNzhBR1praUpoK0c4MDRqcDkxZjRUeENwUHRlV1QxcC9rS1dUZzdOVHZJMUFQTVlZTC9QT0s5R1JnangNCnVsOVRxZHNXODdVZ2U5dkNGL2FCaUtLelhxNnIzMWtHa3hDVm5UNnNXRng4OTJFK29PNjhwUmVaUW56SQ0KdUJCajB3OEpUR1MySWJtUGVuVlJ1Y3NkZG8zTjJ5VWJwRkprQ3FDZUJjaDR2dWQrY09Nd1pRUTdGck9WDQpORDVYR1grTUxlem9UMkdHd2tVWVhVTk0ySzkrK1RzaWhmQXN0blBWOTRZcGlYSFVpWjc5MlJITS9wWW0NCmxLTnFXbGZBL0l1RjBLcis4c2JlUDdLazYrclMzV1EyaWlURmNQWml4WStZVUJHb1V0VWJCb3NvZ1NEZg0KWjJOSXk2S3ZMQy9jNEJDTzl5TzVGYzBUeTNLekJYNmRjbHdpUDdkVXBwNmJDdDZVbE1IbzRCS1ArcVNRDQpoTVJicXNES3dkb092ZmY1RmhkQUkzakgvN1lPbGpSVW11OXZNaExHL0JkcGRMcTFIdGxjbnlJd1RVUVQNCmVlR3VPWEZKc3NGa01OSS9ZZE5RMjB6YWJKeGl0K1k4dDNJRkhvMk5NZ0xnZW8rYW5namdsQm1pclQrUQ0KZ2hZb1pOMTNmV3VUZnRwT09KYUNVdzllait5NXBhQ3N5K2xPMktjUXR5T0g5NnNid0NoQ3RkdEFmWGpxDQpwRGNwSmZXeHByODlGcGhaSzRjblBsQVIyTmMzRm5DU1htWE9nRmtXd21sdC9vQVY5OTNkUm84UjRzaisNCnpSWURnWER2dy8wbXIxSGhiK1A1dFlHUXNkaWtPeHZ2QTMrOTZwOVI4RjlSNmxkUzlFSzQ0eUZXNjRuSA0KbVJmVVE0bUtTUUhpa290OUdBc2FZd1Jsd3ZpSStaYnZYMHZWN2NVK1p6eGxTRzBhaS9MUlNGUWRWdlRODQpwMFZoTXRWU3dXNVBpZTdnckx2YWZWRG1WZUs0NlJuYUVhQ0ViUGhyeWZmUE5CdGZ6R2NqdDNtR0VDNkYNCnNPRUZLbEdHbHU1c3VEc1hLQjdRREVUZ3lvdVVhTmRSKzNkSXR2QzY0Sk5zVndJcVdvYmkrUTBxdzlVRw0KZTBpU0djL3JSSTFhWVNVbUdkMExjSlU3UkErVTNxajQvc25LejJ0bnVYTzJNdDFxMFZDRldVSVpxcXJ0DQpOYlJINk9WV3hBVWxpYnZVRkk0SjVxN3BlQW9JRzMvS3p3eDlEZUpJUGVnTmRsOTVQbG5iVHNOd3loaUINCmY0REo2SmdHSmo0cnRxYU5OeUE0VEtUdjhTT1VYbXJmMWVyZUtpRGNDdFgyaGt5WkJQQ090Ri8vWi8rTQ0KOW1mS0F0YmN4STk1OTIxcHV3YWttTzdFQUN6UXRMcFkwOEx4YnZiVFdFUHNQMXpQUEwzaDlFbWlUbWMyDQpKbFZIZ1BxbTF4TTAzMnNKa3BzdW5mTjFKcWpVS3B6TXR5ZGtjV3ZJZElCVlJpWktjVlAxeDF0SlhVV2YNCkR5c0xDY1RDTDdpNTR0U0J2NUk1YzF6VWtSWHRSd1pPeGNUVTdWNUVUZXlDRHNRWENnazFBNEgxOHJnOQ0KY1UzaVA0YkNmZUplRnZwQjB0NW5pN1NtQmZLT1FmRVVzMVRTNitENk9lMVlBTThQRWh4SXZJaDR5NEV6DQprbzJ5ZUJva3U5R2Fic1BFRHptSnhJYmVDQjZic3JHZnVuWFdOYWViODBITEVGZkNYOEwwcTFiaEl0dXINCnJJUE1nT1lqTHFmdHoyazdacGhHcnpvSkl1T1pUdTJpd3lLbys5RFpJMEZjRWo2L243ck56SElCYmkwZg0KOTQrZ1VhZVV3aTZNbDZJK1BaK2NKdlBlaHJqckEvMW5sS0hUL0VOVHdBZmxpWi80dFk3eFJnMXo3M1N0DQp4NFlhSWRGSXpMQWJnTkpiNG9EMGxXVEc0TG5MUEsxY1NZdEIvNVg2MUo0V1ZSeWI3Z3V3bnA2UEJyRWwNCnhhU1pxa2JoZENUbHcyRC96K2NZY1Zxd3ludVdGTFc4ZVR2VXdjT21DK2Z6emtyUk9VK0prUWEzVll6eg0KZ3FuaU9uc1JpcmZvNnZhNWhaL3RPaDlxYUpnUFdka0VRZFoxNVAxN3hheG1vbk9wQ2ZTVGZsYmY1Vml3DQp4azIxamdpNkozTW9ieWtwVDdPbzdQOGZSaFdvTDlSdTlKL240VmxmcnFCdGtLa2duZXZTc1FocXBxUk0NClBBbEFSOTRQbTV2dnQyVDRybnAyMHZ4dlpaY3RVYmZPRDVmenh0ZnN3cEl1WStSSml1ZlpSTVJ4Qk9NMQ0KMHNxb1RDeTN2djJOcndyYXdsaUJSa05VZnJsMVBKTDQ2Y05ZcTA3QlE0bE5rQzVpVjZrYjQ4bkl1c1NQDQppTWhtK1RkcmpPM2xwVlI5TC9EK0lwWjNyRDVFRjhUWUEzUmp4WjIzMVYyZHRpaTluY1g5OFN4c2IveUUNCmFNTGdlM0hnY1AwVzlIZXN2VUVyS2xUU2hxS0orNHI5d2Y0eFFxUFFYRWh0bUtXait0OVBVeVk1OTFpWg0KYzQzbU1yY0hodlA2S3ZEM1pIZjQ3Qk1RV0NnV3YwS3hXMmxkZDMxZDAxY3k2V21ZUlVVOFNiSDdPR0MyDQpNd3ZiTkVrcFpsTlF0OHRLQ0JEKzVWUnhENHFESXA5S1BOay8vbjQxcHRMY2VPZHFTSkV3czl0UDlOQzkNCjY4VW9uNjd4dzZFMlJMcnJuamQ4TE1hQVZiUlVEQXYzdVpEN1FuTXA3QXVoWjVFcGowRGRNZERWL2RhYg0KNWRKU0c3SlZJaHNOMXNOdGVaWDY4aEJzZUF6eEdRTDNWUzRDS3p5bTk3eTFXcVNOVHhmcTlndDlYZGZsDQo2N3hyYlAxNVFBUm42bVcySm5pM1JORkdHOHVzSVZNM1F5NFpnQTFYaXEwaDdpeTdDRTNPeE1HZVR2aHMNCjAzWnJOS0pHMFFVcUF2dGVLbXpxZGNQRCtyTTRZaEYvb2ZKV3hWYVhCUTQ2WWE5ZmhzUkRUSVkwYTIvSg0KWXBMMzIyaUdzc3pOM1EwZmxycWVUR0NjUC9zMGx6bS8xb0c4RzU4RGtFNWxQc2hjTEIzNGRPeWxVVXRwDQpEdm1BTy9jVmZDaWh0bUpiMGIvV2tIUEU0QlB3MVAvMVo2SEUrN0ZIQkxPdytUdXZjaG92WVBKeGZJeWENCmFIRldWSW5oME1Fc0QzMUx5cCtTM3ZGNjlScXJEQWdjeCtIUTNMdVNYdmpBMWNWUDgxUTFlOXFSdFJENQ0KTjNGcWUyOUZnQkJ3QWMxbVZqK3VCbzNSUi9Fdkp4SWFpUUFBZU5UZzdTVXNFcGVLSStlQlhhSzdwL3JUDQpLZHZwUmhsMnRlbUZDZFZHdXM1QXlGMTlXMituUUltczdtWXdTdzZ6dWRSUkZaamdCekpoMXZwTVNIZ3oNCnNtZFhaMisyNm1wTWM5YjZYWkkva1ZDNXZXK0ZIcEltNjBLTjJNUmoxTkxqbk1HTXFVU293NGtSQmJLSQ0KTGc0VENpLzZpSTJ5NkVsU1M3eURCaDk2a1h2Q1RRUWNsd3kvck4rSWlOazNHSEhYTFpudnk0dHRRaGs2DQpzeUFhbUgzNHVhSW1aOTFyYW5oMmM0K0sxaFZaV0RpczAvSGp1bitYTUorejJESnNLODh6Qm9yUVdSWVUNCmhadzJYSzJOK1ZOeU8xWUViejM2bEVNYUVFMVdob2lUd1F3eEN5bndHZkNObmRxQ21BN1F5eHJLN2JmUw0KeW0wYk5oTEFsVlRYTTg4cndIK09UVzJsOUE5YzJJMTYxeTdscmxnbkdKSlFacmxsOE1nbVFyUHladUVsDQpoUHIrOW02NUVvellUaXh6ekE1eGpMOUo3dC9rNWwyV1puVEllcEt6SVFQVHEyYzhCeVpueGFmUm9sNkwNCnJpOGt1UzlnZ1B0MWNNZytzOC8yQXhmWTVIT2h6bVk0V0o3RTJUeUExTXhidjZaN1YrSTViL1FKSnNrYQ0KbXg0anZlTmc5QjR3dmxyUnRPd25PWGtVRDJVQ2NKMDFUS3JJODdWOXh2TGpNM1BMaU83NElFZU1ZK0VZDQpVVzNtdGZ3WG1IOGdJdVk2L2tpdGRhUy9XZlhtTUVUQlRHbXVoYWxwTi96M0xqK09DVC9BUmVnTjlnOFANCnl2UXEyR2p3dW04UGZsa0JxOEFtRG5RcFZJVnN0SE8rNlNJQ2JpWHZJaDN4dStXRjRhaFg1LzA1MnpNOQ0KY3BuUllPcDFXWHRIclNLUjdlYXI4KzRqdm1JQ2JPalR1VDBBMXJzeko3Rm1scWxab015S1R1aXo4UHBIDQpYcXZ1UkI3dW9mOFI4VFZwVGo4NzZoZ0J3MW1KZUd4MWdETjlJREx0ZTV6bnMyQ0N4ZHpKR3F0MWFCREkNCmJBM0ozajhmaHk0bzltNjdnOGhPQlRSREZiZTV5ajYzNXN3SEdVUlQvTTRpOGNWaGRub0R5VHIxc3VHaQ0Kd0haOUhEUmRKK3ZDV1Y3dFlqNFpPOHlXSytORW0yREVZT3QzZm1KVFNmR2dZeSt5ZEhueGtRT3d0VERaDQptcWU1MFlkSENDRWM3dURKT1laVkV4aHpJeXcwb0ZNbk1nZnY3Q3ZMK2lJZElhdWtydEFlVVpxMmNaOUgNCklYQWVVQ0JETGhQdzViaEpBQTE0ZjVzbG15MzNDNmlJcjN0T2hzYi9SNHUrdjdEODlsdk5EYTk4T2lzZw0KQ3hVc0l2aVJPaFhXTmN4b3QwUVIyUzhqSDVPeWtXOG42UlJUYnFUNnNlWTZNVVVWcVRkeVo4VEFmR0RuDQowN1dnY0xMTWJ0SVRRUUhvSFZaOHI4U0szVzFYcER5V0EyckJPYU1qV29QcHZBZlhldUtLclV2QUxUU0wNCkIvRHpiTWFWaFdCM3YvVmQvUDBrYlhSZk53cHV5SEdtMFUyYmNpUWY5aTZGektTTUJLN1ppTkV2Zlhuag0KVVZmUEtSMGYvRkZoNlh3VGZvRHNTQVAxQ3FwdkJhK0x3VjkzL05HMmptcFBMUm5rN2lXeWJ5WmhHQUpLDQpDdmFxV0lURWNVcHdteEV6RlZyeHEzSEtOaytzMzNhN25CRWE1cmQ4dDVJSlp5Kyt2aEZpUDU0UmI0QmQNCllHRzN6UDk5MVdHYjhBTjVJeU1CellINlFNcytQNWtsc1hjbVRpeGxnVi9pRFd4TjAycUVsNVF0R1ZkNw0KemNPRVJEaTVwVUVSbDFlbTh6V0lsVkpBTkZpNVR5MnhwdzNPWUN6cXp2UUxaZ1RKZElIdy9KN2JqdGNyDQpZUnErUzFXVFQ1cDMxMGl5SDhQRmpUT2g0RnV3dUJZcG5LSlB1dG1HT3VVUmMvczFyQUdEZmpFYlZPdnkNCjBNejUzYlRXelRhdFVpVTRvUit4ZHFvTG5UZ3p5UWZRZzdvcnU2dEM5SHlJM0pTbElic1VvRXFpSSt4eg0KVGJUWk9zTWxZYXF3NDF1SjdLbG1ndC9lL21KY1dFaGlOa09EU2R2Y1lmdWx6bE9wWWtIT2hNc1JkdTBoDQpYenI5Z0E3dnEzRS95SmVzdzBxeE40eGExQVQ1U1ZHM3VVcmhFUFJkRVdpZkNhLzFvaFplcitzcnVoc0UNCml1OWJGNThKWlF3ZVM1ODAyM1g5Vmh0b0RDWTdNbDJHbjg3VTkyaU9uSjBUdWJpbkd4R29DU1NuR1hCZA0Kb3FyOTdMbzZGZi9DRVFGeEVTSm5pVnZTZXlpcndtSkZsc1N0SVlXVS9UMHArU1prb3RhbHFtUk9DZ0dtDQp1MXJ1bnVQQ0k2OHAyUjU0b2FyQ2dWTWJxa25LbmV5cTVXU283YTZ4eS82OU1NeXRuazBSdTg2cDczazkNClljUW9mRG13ZWY3ZGRFQzdJaUxTWmk1WkQzVlgrV1pQRUV5S1prbWRLVUsyMTBmQkQ5VTZPNDNTODNkdA0KaUVHUGp2S3V5SzI0cVJuMEFGWk8zZHo1R0hMbWJQOWZaVTBpSERGakZRNDNKOEp3c3NMOU5TOURSUEU1DQpSRzZsUDgrTDhramNyM29qWERaZ3Njc3JEc0dKdmwvU1J0YTZ4d2hESkYvbHZ0ZjdYNDFRcThtSUtiWjkNCjJlNldTeHppWngwcmpQcFd5SlZ2U0lYcmVJM3NyQ1M3Y0RIblVRMWxKVzhIWUEyejJjZVdpU3R0czRKbg0KRlZiRitndUtucDFMbk44TFlaWUtLRnhwNkJtbGxoeUpNUlpnSTJhT0VBUEFtYS9RRUNQNkxRYy9iSm9hDQpqL05ZR1FxaWl4Z0F2SmhuZXpRTy93VXk1K1FkYnlUZ1FjWFF5MkF6N3Q1b2lzS0gyNDdoQXRCWm1BWE8NCnE5OW1BQnBhbm5YUUpDR242QitFTXRqQnYrUHZ5dzFSMENaUm95bXAycUp0U1AzTnE1YWNiUS9FWjhwZQ0KM1cvMXFweEZDa2VKTTJUZ1VDSHdwNTFvWHpGZ2YwM1ZkVzhYUmsyaGg3c1U5cnlWanIxL2dSc2RvK25YDQpuVllLSHY3Mk9DQkxyclpleHBVZURsOWF1a1hSK3YrZW8vTlI5QisrYlJ6emZtZTI0L0hlRXlpWGpLSnENCi9QeHJzMktRMENoQjBHalJGUTk1SERUSGMxK091TG1qdVcxd2p1YUFLaXF3WW5za0VqNkVLeUtFblUxRQ0KVTZGZEhFSTh6cGRWSkFFOFh2dkxlamUrTG9vZ3FLdFJDMDdEbzhuVjNTQ0NtSGZUbUwrd1R5MkFUZnMxDQpNRlNrYTdLUmZnL01oY2JFc0paL1FTeDRXdDJqVVFqRG1FMUNFdU5KN0Q1cGFlWC80eUF6ZjNjNDlRRzINCmhOcC90YkxZalgwdUNVa1ErejZ4NHJtUEdidTFuZlk1K0RZMzY2QU5MdndaRzJlK1JzUzZHMFFPT2RZZQ0KQ0dxTmxvQTJCdmsyQkJQQkQ5UHEzUkFqcGE2ZWNiSnRFV1BNQlF4VjY1OE9OSWpUeVJNbnJlbkdiL1Q1DQp6L0UyS0VMNFpiRk5MZmN3S1l5UURwU0NWcnM2Q0hhMGlGVjY3ODd6S0NWTUE5bm5BZG9VcnVyellvc3ANCmtabWd6YXNUYXhST1U0YlUwYlFUWnlYRjNUdnpkb2RyR1I1WElJdjAwUjlGdnUybWl2SUgzaE5YZ3BqOQ0KdHBMUk1LeWMvT25XTEhMYUhHL1Y2Qk1yMzAyVSs2cEZiS0dkbVFIS2htbEpET1BZVFhPaFJycFpGQW1tDQpON0tmWFRscEhlL1E3WUNJNG0zR1lMcE9vZnIyWFNCQUJwZWJaYmVTR3Y0dnN3OXQ3U0RLRFdiN3JUOTkNCkl4MkhMNndNbDIyeitmdkt1UVFtdHNVZVhzdExVVVVPdzQ0WmpDR1lnbXI0cE4yV1hwSkdua2Z6U082eg0KUW1TODNTSmRRMWV2dmdQUDJ4SWh3MExRT0txb3JPQWVveG5VR2p1a3ZWbVJxa0F2TUZkQW94eHFaUHBrDQpGTElUYWxUeDZlMXdTWXJKaGVJQXZyVysvQmVtRzZVbytwK1lSWjh3OFlxektGWUQ4Z2RGN3paTHBRUmwNCnFMRU9rRHlGZ2dTaUo0RWNmanhUaE1IMy9NN3NNaDhZbTN4N3pMN0ZCMHl4dG9idmZyUUFJUHdsMkcrYw0KVlhWZ2tjWGE5ZTFhaDFtM1FyZnExTEsyTjdzTnJRUVpocFp1VEY5Tk5ySEZ2Qy9CWlVydW1SVUNPdlQ4DQp1ZG9ONEJQVU11YmNlYmhIL2NQek12VTRFYjZ6ZGF0NFB1cXZKcmFjR2lVeS85dVJ1eEphSUlZeG9VWDgNCkt3UVlYUEVqVk5wQUpjTHlPb1NUVWU4TEYvNWtKa0RRZ3BLN2hKWXU4UTFCQWllQXRqcU5LeEdOMGRRbw0KTHo3U2k3eHIxS1JFQlR6SExpeWRLVUI4QzVqY3FGUEtTdDhSV2hBRkhTbDRRRnVFd1lINytESXFxSnFPDQoxVzdMTGl5V1JKQ3A5ekd6Wmc1U0kwYVFCNDBiUSsycnNrY0tvaXR6bmhPWGZZemZSV2xZZFM3YkNZakQNCkd3S0JGR09WVGcxek8xcDV3Q25QUzJIakd5T1kwYWV5dUxsd0NFcnE2b1ZVZ3ZSdFA5bVVXUDRBNHplUQ0KcHU4eWczb0cxR2RrNEJCTlg0ZW5ubnc5NkphZGo3cEpQWWpEcWdpUDVSUzBMaXNiazBPMmlxeUVkRXN1DQpId1BHRWtla09Fb08zVTBoak90V1gyVHB3dmIrdWR1Sk9XWEpTam45eElYblZnUlhKNnFCbHVIdGxpZksNCldzNWhQSzhnM2hmczdORWMyVUpidU5Rd2lVbkQ0NGNjcGwvVFBhR1ZqRmMrZklQcExDUkpBVWdLNmE4dQ0KWUp3K3pDWURVeW95Z1ZKaEtOWVlra3FXcW94NmljQVNsbjh1SXl2VlR2ckZqT2E2SlFkQmZFK1EzaUEwDQp0VUNlc3BONVJUV1hGejRQNWxiNWlBMFl1TWFLTXp1T0h0ZHdqZXlpbHRUY1J4c1NLVTNTQW5FbTRVdHkNCmVISWdqUlJDenYzR2xjVDZZcnlaajdnSlc4REE4YnBTbE9lV05Cci8wMmFnZjFoK0hIeUVTNk1jc2EycA0Ka1BLUUJTYUFMMWhWL25GdE5mVlRCYnUwNjJycWswTEZTcXBCZVFYN1J4dFZKOVB4ZGFQVXByV2ZrSDBQDQpOSjVOTjZDL01telNLelo5c2ZjZkpNcGdkL1ZORTMxanpkeDhYQUJrc0lmSGZOVVhBRENzWDRIT21HWEINCmMxeTVBdHF4QjN6Y1R5MUJSL3krZmE0Sk4vekU3Q0k0ZWdVcGNWZlZPZHhwOE0rSE1QTXREVUFscFpiOQ0KcHdUa3pseE5NRlFyZEhxWEZwN3dGWUY2U0hDdUpjNkdQTTdhTzM4UFArY01vZ1EwYVAxdmx1UzdkWWdDDQo2MXVFKzI2ZytIaEdocGZHRlBqYW5ySzVNYzZpNk5YL3RXVGhxdjhNOEJ2TXlUbXg2dHdXWk9ZMlVSOUENClZEZERPci8rWWtXTWtuMkpPNVMzdUs3NVU4VGtweHlkdmpScEw3TCsxNENWQm9HUlFhcWNYSVhZT2J0UQ0KaWsxWVZwcVJFb1dlT0JsTzluR1J3ZFpFa1VUQ3V1Y3pMaHh4RlVFQUhORURmYlY3Y3R3RU8xWUZmTTVWDQo0NEFoaDhHSjJDc2VNYmNBazVzVUxkdVExL1FlSmJYRXhTNnNyVkNybVd0Y0NjcXJ2R3ZqNjRkNU5JN0QNCk1aZEJ0QmtGVW9hajFPRDVUbXhqZ3FsUHo1dUJBZmVIRkNBSUJNcEgvb0Q0VnIvQUhhV3lwOEZtY1BveA0KaVdUT0ZxcVJ6aUIxN1cvR09KNGlGV3ZjaDM0alpBNHFGcWhnTEtwL0FHNGdLbVZrZklOVmdMazNCcmRFDQpKSkRCK0dObk56cDlWSFIzYmo2VjZseE1GZldNMjY2UWhxaWdZZlh4VnQ4MHdJUDMwejI5Mjh2MEVLMEMNCmtZbitDcjZ5dzEzRk91Y0NiaTVhYjNlcjZNV2xybEI1NXJsMHhjckxvWUNLQ0NkZXI4UXdTSWVKaVlwMw0KY3pIRk1kN3YxVXFTUjArbVR4N3k2Z2JpVlNXbW1ES1pNdHJIUHE2ZFAybjNDbDN3ckcyY1liVVRwTitHDQpDNDBDaUdyWndCS2UrUVEyVWZFbGZRNm9Mc0xTdTFmeGM3ek5lYUFUWjVJblhTc3FCck5QbFZtVmpmbW8NCjBpWnE4YURKc0ZRa3BUWVJPL3RKTXpuQ1k3dGJ3cXZ3WlFSenNBamFvalpCRmxEYUJNZGYwY3JYVjFSTg0KTFpmbkdSTDM2MkF0NjBPNytpWDYvSGxURUI0SGlyaVhkMDJ6SXQxVmRsaFFicHdrTWxUMVhQMUFHMmo3DQpSRDlHYll3c2VHRjdZd1YzRWU2RzhyS0trMFkvbC9tUXZuRjdGRFZEU2lSZUlweU5HYUVHSFJEaWZWMXgNClNpeE5icVJjZmNFUFcycHNpejJ3UGpWR05yNnM0MW45VFdDOUZVcXhCaXVQWHdkblQ1RnpRTW9iREhpUw0KMmZScU5adnFGakowbmxzeVFUbjBUbVRoNWF5dXF1SkhTWUlQTWFMWXdZQWZvRVFBekxEN2w0NDJidEIrDQprbkYvYS8xbUd1MnV2Q2U1Tzl0c0VzSmNUMVJzeHB3YmxWeU5vWDRDd3JOTjZmRTQ5eUF4YWgwZGovQWUNCnNXM29rcXJ1SWdudW9jR2Q2WW83YldPbS9iZ1RIbFpKWmFiVVFYaWdnUUNWVFV6bmcza3dnOFF3T0lSNQ0KRTB3UDA3QmlGRVpvQ1pjZVFzVkpMMmVId1NLTThEOHVVbi9HYzM3aWFZMWZhNW1wUVdZMmZiNGFvTEpCDQpwbzAxSldIQVpiSG9sbmNvRjF1eFJidEMvQktYaHlRS0hDT3VDcUNrVGw1dTN1VGdIeW1rYzdRRExHQUkNCkgwTnJ3Z013K1A2NkQyQjI1ZEs5ZW9PYlpPSE9HTVM3RmR1VlAvZW5CSTBzZDZjWTk2VEJzK1NYbjlmdQ0KcVBwSjdDZnNDd2xuSFVneUlOK1crYVkzY0hHUzhoM0RnNG9rWDViMU56cFFvY2paZUpNZG9BaHl4aDVsDQplQ0I5K2NDYndjQzNtRnhSc3NFbW1UNkNWUnF2NEVqOWlNaG5uK3gzVDIvaDA1OE9scXRnVEFMNWJxbkgNCnhONzFsVVVWOCtXdVdLMkFqaUNYZVdiTSsvZG9za0ZuQ1E0dFRkeXQ0S0Nlb1hLd2lmK2h3MkY0MWhIcg0KYWpjWDVNTTZ0ZXgrK0FvODVISUo0ZDB0NTd0d1VDUkk2UU8xU1c4SHUrbjBsOXN6U2l2Zit2d0l6eUV0DQpvQ25zUW1IRlp2ZFc0N0JYcFlrelpzU3RSbnZSR3NiQVhDTXRscGdyNUNhR293ODFOUmdzZ0pEWUVSZnANCnRnaXhBU2RPNWdhaWpwYnhoTENBeFBHRnZEdVJGSmU4UUZ6WWRrR1pFN1p1b2M3VlBpRlJQZlFVNVFYMw0KZWhnOFRjaWZFTFdIUVA0dzNmSXJSWXdKbFRCM3d6enhMQXIzTXFqeUhkVUxVdzR6VGIwUVpOb1dLK0NPDQpPMVBFVTR3M1hBOXAzR0JEaVRtQ2g5c3NvdzNra1lBYzFjb3ZESHpSTGlNZzVoKzl1K3UrR21tNlg3OGMNCkt4anoxcW5haENjcWRmcGhxRFRDVnVWWlZLc1V6TlVwNzNjekJlOGF5bkxwNS9KSHFqRmVleldIZlhLNg0KSUl6T0NJWjl2V1ZETmdOQWFGWDEyWmxvZXBMcEJ0S1ZMS2l2NXByRXVDNTRzUlRkSnpIWDB2Ukt4MzJRDQpHWHJyMGhYQ1BEVlJ3SG0wTngxQ0dObFpWVUMyZ2xlZmpvbGpid2FaUml4M0N1YUhuMnhhWVVSR2tTMFINCnQ3akpScHFtYUd0R0d1cnkvT3hoZ01TVXVEMFYvL2JWcitoamI1L0ovcVhNN0pJS1UxcHh6bFZrdDgzUw0KMTRCUnlybXJ6SGhIeHlaWTF1RWJ6Ry9YZ2dMb3ZmdmRmSnZaNzNJTFRhcm9tZmJlajV4bXlsVUJlRHpvDQpZUi9VZmpiWjhPaUQrKzhqMmdkeDVxV3JJNnVTNG5UV2FkWWhBbnViOXNPejkzOVpHRmJsVmlwdFY3Q1ENCjFvd0xMWXJCRjU0TzV6VXc2cFNWWEs5Wkdta0hha2syMjlMOThkM2NYN3Y3cWhkd3hBaWtJR1NTeW5Ccw0KVzJDNmF1bDB0cWlIN0VpM3hqdXh0eDhZSjBua0N6KzFuaXpUc29xNlpvbmZjbFlxNUhNdXhEdmNtRTZqDQo0VFFBczk0WU1KdGhwMjFCN2twYndJdC9GRGtOR3EybFpTMlJiREtoMUJWMXp2ZWhacHRvVGRhMkpLMEUNCkpLWTQvdCszZHpvM2JjMS8wTHljUmFmY0podUN6ZkZqaWlYcDhnTlA4MzNjbXBWalI4RWlNOGRIUEs2Yw0KbzRFdFVrMStKS01RdHhOMVdGa1BETFA4OFdvV0h3bzc4cFEvdk5OOWVhdWpPV3h1em1Nc0k1UXdIMVUyDQo1YWFrV1UxTldlbE9jWktKSVZ3aHBlcHpIcTFEQVRZd1c0cGpPZnFqWmhqSWpVcEFVN3FIais4OGZTT0kNCm4reHp0aWNub0h6dGNScXRVUXo1SFY2WXNhdng3UkpIT1JDTmZGZGJPVHRaNXhRTWt4d3luSHQvTmdNUA0KbTRVWS91WmxpT1Q1YmFJeGRmdkFjRVZ3Mi84VHIwZVRSNHJQZEpBVllEL253UGlENDI4NTE0Q1hXWFRiDQpRVGFaYlFBL2h1dWJqZzk3dGU0UGVEQjY4MytIYlp4M3NLaFV4cFZwTCtnM0tPY3JseDBxd2MxYjg0ZloNClF5YlVJMS9HR0syRURIeVhaaU5HVjU1UVdZSDBSZlBsT0FBMUc0QWZCOGtCL1I4UUVNS0VxQlJFNmZqZg0KNHhmbGZGSHFyR1MwMlg2emZpYVFmYmlBNEJtVW9iTE5yUzkxSlEvc25Nck51cVUrcmRBT2hMTSs4bEowDQpvZlhFWnZWbW9RZVN4ZlFMd2xZNzBQVVFJaGIvOU5zTURvTXNJek16enVjU1ZoRTl0YUdCYW5nOHl3V1ANCnA5bmNYRUtCaGpHZ1UzSzJlWjVweG5aRS9tT25Na1hNalFrMmNBWVhzcHBDQm0vWkdYalliY0ZGa01seQ0KS3Qwc1NJcHVxaGN0MWUrNGowaU9Hd1NZL1dSQWhnd2M2d2xKaSt0aFlsS0N3Vk5iMWxOWEdVWmZkY2FODQptdElHZXM1ckMxUkp4R2xGY01hR2JicWNYMFVWNWRyRVBxelZNR2JJRXBZbUdrSEllSkcrOEgzc1p5TFoNCkFrZkRNdE9qbUtxR1E3Yy9mRXRmU2NqcGlpdWhyaUZCZDBSbDdGN1lYekIrcnBFaHJ1U2NIb2w3bHZsRg0Kb2RuMUFScm9tZ216alRsUEtzVVdhYlY5SGVTWUdPaEdjNUlGa24rNEpWakpwSEFxa1ljcVY2L1R5ZjJDDQpKNVBiNzc1WDJOTFhVcUpCejFZWW5aWXlqM1NiVGRmcDBYU1JVWlIrbWZzRVlMQk43RzA4MlBVLzJrc2gNCkI2K3lPK0dhdUFMb21UNEF5YUFmNHQ2VDFWODNnUTBRS1BnbHFRbHdiWkFWK2lhODZTQ2ZYTjRVT2NuRg0KNHFDZEtlVUtpcVgvdDNLT1ZjaTkzWEErUUJJTWQ0eXltVmppYURnSmRPTUpKak9Sc1JVM1h5anVkWEc3DQpTU1N0M1cwKzAwT25JZGk2eGQ5TTJHcE4rU2xoN0tFbFpXM2k4YnRQSU5PU0FURnUxSHhRWXBhRThPeEUNCjZncHN5QU9kRHpyeHRCZjZpRXJWK3V0ejk3d3grUktOKzJPNUlDdUl4c2t3TXhBWUNNNTBxa3h6VTRmTg0KeE5TUTdjbDRnSXpUUUNTdHhNN29YTjJOeDk3R2E2dkhBcmpENlM2bFBTMU5NTXkvU1oyeVk5OGMvOENMDQovWHdUSitSajVqL0xhZkZTN1k1b3g0U2JaS29CU3ZXeUFLcVYrL3lBU2crcjUyZkwwdzE4YnNmeDZpSEYNCkJVUjRaVEFQNXNma0YwS1FEcHN2SjMxWklKY1poSklybGtlY1JPZDVVSUQ4enhBQTU2V1k4MWFRVjM2OQ0KWklPUDBJeTNIaGZJY3BMcldvQVp4R0pGTG40VVNzQ05zektZS1dKYkJQUTJNb3Awajc1ZFd6N0RxYTQ0DQo4VEcyUGtOYXJORDdwMW9xYVJjU0t2eCt3ZnpBeGtINE1ILy9CTTNndDBoTmtrUStoSktBTXN2bzN1a2wNCjUwTDdsemZuSFptR2pBYXo4OXVwUlNnQXJ3L09XZDBubjlFZU1UUUh2TjBYbmhhVVYxcytFZklIZ3FYdQ0KVjVTQnpTTnBBb0xMV2crLzhmdUt6eHBqdmN4QkJLYW44N3JaTkg5aW96SE02aXczZFZvWGlnQ0tiRzFYDQo2ZHZzUjBlM0J2aWpENVpzVkhkdUJlUUs5NmJiWndZeVl3eGQzZ3pQY1dYVXQ3VE91bytBeG1zWUtsdGwNClhubWRDZ3lsNXlqcmw3UmV2R2RyOFNVMWs0VzcvY1FTZzJ5NFRjV2V0ODkwdkVHWUdPNFVzaTRqOVZ5VA0KZUlXeWlaTllyTlBZTXRCWDRSbmpYTGNrSGdaL2pkbUpuZ3c4TkdQVGJXc1NUUGJTNVBvZ3R3T3pUcVB5DQpqdHNGRHhLWEExaGJnMEhTUzVTMWpXMXhHTktaQ3VSOEhOR1RWeUJrY0tYdDRxZThIYXhTaHluV3NsVFgNCk1pZ0RDcmo4a1Fpd0VGNkloQ1pDZmdJUDhYT0NrbHBDdWVQRFc2WXh6cHhKcS95UUFNUmFqWkREMlJmYQ0KRWJrM0dlMnorcDJDYVdHNE5LWldxQzQvREE5UVBmeDEzblhMMmdsNWtDMUx4WWp3K3YxRm5OaWxrRjBIDQpxOTlyWEd3UnhzTjg2QUhIVXU0MngvM0tCb2k1RkxKMnVaVTQ1SjZyYXZhTFRPWkhzc2t0L3VXdERuV2ENCnJZa01QVmRhVndrM1BYcUxzUDJVTVN1ZjlxKytaZEpkRVdRYkN3WUJ3RzJETVhoWUZPL3hQdktDenpKNQ0KeGVhV0Y4UmtWTE5yR3R3cVhlY0xaWW1uZjdtbFlIamRGRi8waGJXYkhCWE9iTnViREZpNmZkNW9KazN2DQowR2dmaUIxMVd6WDhDbEp4a21MRmNlUG9vQ1daQmlOQ1FrTUdyTnNpclozUGdSZGVUNDZFWVJWeGNGb3QNCnM0T3g5NnZiMXpTQmNsenF4T1dseGlzUkMraTlPYXYxMG1TUm5iNW5FSnE1c05SMXQ4RUdkc0FTR3hBOQ0Ka2JmWFBhMDBiaGpzVlBQQVBla3VCaEhZdUFZNWRoM25BeGcyVkdab3NaQkFsNHFNSnBpSnZ3M0l6OUlyDQppRU9TbzNDRGNZOEt4aVhTdnZMYjF0Q0R5ZU9KY3czUnFCZFNmcWxVYzQ1RjBnQ2FyNFE4NUJRMTdPOVkNCno1OGlwOE5sTkYwNkRSVVRkVHhCakViWEtUNFJaemVqNkhBWGNwNEtFWTBSWEh5SmV4YmV2dzMzUWtPdw0KdGFHM2d3NFdsaysyUlNQeWF6TU1HdlB6WDd6TVY2TUFqZm1WZ3RNN0V1MGMyU2pIeXdSOGVuSW0yRndFDQpLMlZmdVNsZzZzTkkva3d4cTRzVjFYQndYUDIxcmh4Ylp5UW85YnFhQW1VaVphakg0L2VqczlHOTF6REsNCnd0Wkl6YjAvR2kwcE44a1I5bEtkbG91Umt4MTg5TmZYN25xbCt1a0VNWmE3S05TeVNpTURBanhGaG1uLw0KOUVGei9ucm5yNjhOOUVhalJjUDQ4cGZSMFFmb25OMDJDbFpZWnhwQWdHbC9taHpsQzdpL1FwKzJZRFJmDQpVZlJ1dS9EZ0N1TDlDeUJRRThzS08vZ1FzaWJ5ajg5dVM2UXgvTEFnUjJxbTZPWFNaMHJKV1czaXE0NnMNCjl3eld2b3BQUDVicTAzNkZKR3R2d29KQUJkNC9pUURKSHgzTXZsQ0JTVmtSVVFuWGk4dDdUMENrcXNNWQ0KcTE3QlpYUnFHUmJaUlZNaVVQQVNPZUxkMDhuR3d3NHREYStCQkZxRXZ3Ny9jQmFLcDhSQTJsMUpGSzhpDQo5UHc3N2tIQVpGdG40aThZbW1lVGtucHU5dlgzcXpOd2YrSGhLa1YyYXB1TFlnVTdzWWxqRW85N3J4ZGINCjdUczg3K3UvaDBiVzB5VFNSNmI3b3g2NG5FZ3hlSTJJVFlHODZUNjUvaTYxbGVsZjl0NFA3M0ZKaURRRA0KamJ4Q0R2UXVvTnVLVm1OZkZYVW5KUmNnUnlZNFdkUndJM0VOU3pick56aTFrVHdZNVJZbVYvanZsME9nDQowL08zekR2bUxFRTFXckpFZ1hTMTQ2Z0NRWUJ6YUxXTm1DdW9zSWN0SlFDMERjelB0TkhZMHhaTnQvcHQNCkVaWml6bE42Yko4TGw0WW9weHFoNkJveFozLy9POTIzMFJTbUZYbE9Kc3RYSGExSlRMNHErbnFrYXhDSA0KNUJkK0dlSFlKWStEbXphZGMxdm9ROGk4WDdZVWk4VFRHdDF1RE5NUXRRY1U5ejVWdThTYVp4YWtUcFA0DQp6Q0NZK2NPOW0xOFhRTGg5Q3J3MXZscm1LM1lXSEZOeVNpWFlWVEg5Nm0rTGhXM2xJKzkyQ3dWeHkvZGwNCnJZRjhXZzVPTWQ3c253VFYrNHl5TCtpSGMvdkk0OVA4WVdBUFJFMnNvcUVIL1ZwSHU2aUxUcksxcVpScQ0KbUhJL0Z0OWkzcE9xamdia2ZLb1ZDMDVoellSWDJqa0tYUXlrcXB2aU54RExqdzR1RHZtWElmenFza1hTDQp2aTE0RFhFV2lXQ1Bxay9aL3k3blpLR3NIZHRBSFU5RW42QWZkZERpM3RhV1A2b2l5bmFRa01FVXhERkcNClQweVRpeFBjQWkyNktYckw5ZUVlR1BZTjFrUXBzMzZURlVOak9FYTN2S0R2Q3JJOUFtYXpWM2R2cE1oNg0KaWFZUXJHMUxrK0FUTzBoMUZwZ0xVTkt6WUt5Uyt5L09vV0x6M0ZLK0dMbWVqbXNIWDZDM1h6WlhUakdaDQpHMTRZd1QyMjJYTmhwSksrRVFYYTV2eUNvS09YUlFleUdYZzVObnZFYWtWZjAxWjMzcWF1a1pvMTdSdzgNCk5TQzVrTDNFcy9OejhqWTNDWllBNzdBR202aTVwZ0NFZmFKMEFzOHFLd1JDcTRBYXVjZHQ0SDZOcWk0OA0KNnd3enNNczRUK0I1NzZIeGJRZUl3czFxbFNrS25JUkxta21pdWg3L3NLaC9FenN0SlRIZzNWbmpzbC9nDQpDYmRRN3M0NU8yMUxUMDBrajNUQ1ZITERlZU5OVnFCNlRXRGpRNDFRd1dVend0aUxhb1BmczVkeEN5Mm8NCmhxSCtTazIzaHNZQmoxSjRVKzFEMzE4bFhYaVFCMGFaYW5iQmhHa2RFMHFoaTVEUy82c2hQQ0hMcUdKNg0KTXB3dWdSOVdPSzdpcWVmOGlIakcrRUtPRHlNSVRqVVk3WW5MekNnNzA1ODBpcUM3TlZLT09DOGx2NnlrDQpOZ1JYNFVNM1RoTTRaUTZQdHJlVmhDVWVmanZFWU5qN1BRQUxGa1o5MFJKclpkTVhOQmVvWnBweFlrV2YNCnEyVnhEQzR5Y0E5NldFY3piME15SmNHaGdZazFzNy9LRjBkR1dBUk40b3JwL1pIUlN4TkE0OG11aGQyQw0KZTBPRm5FWVAreDQvM2x1c1pvWE04RmtXeitIQzVTdDNYNm9KNktJWXpHclVPOHhNRWRZQnJtdGZhV2pqDQpmS3pxTVNaNXhTOU8xeC9FY2VSaGV2ejRtc1BnSThxVHh5ZFkzeWMvNVE3NVNSRkRYY3JUT3Z1OUQyMGQNCldZTGhlUTA1elBJT05qVzRQTi9Jd2xpa2gyck1JTkhBQW1iZElFb0lxWWlyUnI1MlhlYitlZ2Z0a3p6Nw0KUzB2cjNWaldGU0wvOHQzNVA0WjN1UDRGeTl0anV0eVZTOUYwd2owalFiK0o2b1RpL0FtTGc2clpQWWdXDQpMUnB6RGxocFQ0L0dLb3Q1NHJHcTA4N3hkZFpNRGtyYWg3QzBuWDZaMHRiSHZZemFRWTRlbkxBYXk0R0ENCm5ndUZUNStmL1hXVGxLVXIxdmY0bTdFTVNsWjRkaDRJb0p1RC8rTjVwZGptRHltdmFxZ3ZaZE81UG04VA0KWGlySk56SDhTOGg3STdHVnBPQTJlU3FkTnBWSW1MeTdhWXhrMnpzODhJV2p1VXhVWW05K2JVeWpTbkU4DQo2ZDR5TktTNUxjZjBvQWxmanpIMlVDZ1ViRm5vcHpOUmdGUUMwOFpIbzNRTVo2eTMrOWpTYmVDWDdaKzgNCmhaa0trUVJHN3lRQ3BXY1hjZGNkcWF2eWVWQnBMWnEzOXVvSjlFaEJjZlMyL0RGRFdpZnpmUE5JU01ISg0KQ2V2bTFkcXVPUm9jbWsxNi9OZEQvQUM0bkEvWHg3aFBoc1hIeWxWNGpKYTc0TmhJd3g3b1Z5djBXVHlLDQphMUhZQ09DZ1Z2VzVoT2I3elZnRk9SUzBGRzIyNlJnNFp1NTFYWUQ5N21jb0YvV2ovU0kybmtZMWdGdk4NCjBzQVBhMDFWek04bFpyTk5tc2k1V1RSa1JSWGJPWE00d2FHMURuNXFOcEJSZVZSdmZaZ3c5dkI5d2lUSA0KWjN6eGhSYzVHM1lDMWJacDRwb05lU1ZlM0ZXa2xSNFp3Vk5Idlh0Uy9uekJKcERac25ZWDJ6SnRDYzlnDQpWeDFCUnNQTnNqd09JRUdiR0VYUXRxYmVRSlNmL1pRN2V6ZjZFek1EZmI4ZnFuZzVuTU13bkZWdm1uT0sNCms4Y1VtTG9YVHdCRG54MEo4ZUF6a2RMWmZMWFNGZkdCaHdGSERQN3FhZURNQkVjelYvTkV3clRGMWlZdw0KMDFOQy9JNGM0Y0d2dHoyMm9hSzFrOUpvWE92bXpEODcrOFA1cG1WNURTeFVYNExhQlI2MjdrNGFIQXNHDQowMHZUbG8yME5aNHNHSm94NnBYTXBUam8wTGZlVzlDZy9sZnErMkZ2R2xyNDBvVWI4TmxsUEptY0t2TS8NCkVjRkZxckFCWDRiZEdETTArNDd3andhc0xtTVdsK2lZdWFlbm9LSEJ6c1h3RFNvV0phdURLWWp2YW9PSA0KQlBxbS91bWdranlJKzZiUGhwLzQ1NTlqdHJoUDg5YjNmVTVyZUZNcnE3OVIzTUZuY3g4VWdiaVhhWFpMDQplT043OTYxODVodUVBMWRxb2VrbGxuazRndmxvUzV5Q2hNZDg5UGlnTCtITmt2VHpnRTBhbTFGQ21CWE0NCnhCYld6OFNBUEVISmk2SjJyUVdwWkl2M3J0UWFod21vdHIvUHJlMjljVVV6aDg3WXFCUytINHJBc2RtOQ0KeG9EVE9BMVB1RjlNT0xuazlodXN3aW1oeUZTZTA5dTZMZGVLd0Nwd0k2S09ScE82Z0Fna3ByRWVUM1VsDQpWRUJ4UlNJWUlCa2J0VGRCSWhkZDFrNmdaaU8zaVU0RnJQcmJtbnpVY1JqaXE2eS9mNFQya3JNeVZ2c0UNCjJaeVl3M1VrQmdXeWtPeWhCT0Q3djF5ckZjcWxCelJLWE5rWG1YZGhIZVhuNFkrNGsrM2YxTVExak9KKw0KQ21zK3VacVhBdExPSDlvQ2xZK25ZVTRDU0I2Wk5iclpya3FBMGhLL3F5TmhwS1d4bC84bTJHQzhjakE1DQp5cVdPNUdLeFFRMEcxUEVjTGdwRFN0Ym03VldEMWxmd29XY1RRVTIwT1RWdjJ4RVFTckVVYktnQ0NEVi8NCnlTYmsydWdJaHlDQnkxYVA2MWJSQUsrdStDalR4cUx3OGZmdWtqQnY3anFvUHZwOHlhbWhoa29rVlZxVQ0KMkhqSFlxWXBDMXVzTm42elB3dDB5STc0ZTgvVHlSMnpLNkNGWFdiMy9UdFl3VXFNeHhlQTlIc2hDNERzDQpvRmh1eUhSc0VHc2I4bmZSSkt2T0ZpVVBhMTJpSDBMVnV4Slh1MkxOejFYTkZydkdJWEZMUnlHWHlsMlMNCnZyODQ0Z0xvc3k2OHZIT2RyNFNtVGx4YkpTdk1ZY0tzQlF2bG9OLzRzblRzLzdjdVhJNTF3bXFUc1E2VA0KWTFXUm1yeWUzeHVUZzRtOFVtS3ZWb3NYcENUZzZWRS9mQ3AyZGVPd2ZINXV4SjdMVm0vNFhaRHh2dDFZDQpNZllyanYvbVdaWW1WQWNTa2hMRVE0Z0Y3RGZubUxXL3RDTGdodWFQUm03ay8vQmZQUVhxdnZzT2dnb1QNClBLbk5COWVESnoyWk1VWTMyZnVOR0xFcE5mdWpTR3ZDU1R1eUorM3g1U0VvaVJ2b3lSS2c0L2dpdXMwNQ0KVFFnMjRQV2VqS0dhNVF4Y3pTVFcvZkR3T2dCcnJwUHZHVTh3SmZndGZKRC8zYlptUUN6d1ZsRG42ZHRDDQpwU3djdFB1NjdtQ2p2VGhjdmFqWVFYdnYrajc4QTZGZGQwQkRiWHVsdXFOcDhrNWQyNFBra282ZnBwRmQNClZ6ZVZLajBRWDFoaDNjRWRGaXBRbmQrNTN1OUUwS0UyS0hSbjc3RStnaHFTVEZOa05LSkRLcFdxcmpmWA0KU3c5TzVhYVZ0M3d4YTR5U21qS1JWdHlONTB5Q1E3a01EZ2hyc2pLdnFKbjRadVlWeThaVWlaODZic3dNDQp0UmNHdURvWEFaSnNsTTNudFhRTUo3bituczJ6QUoyMlhuZ2lTUFNXSGVmRWdvcW5UdFB5ZnlWcThicUcNCmNKVmZhYzV1dzNZTWQrSnFKcVRrWUNhcDV0dU93czN6WCtxQUhRWStIdkMrZWhoNWJsaHB4cFFJaXB3Mg0KazlNVVd3T1dXOWtpQ1R0ZkNlZGRZMDJLQjllTENyd2FkU1Rwekt5NTBzWEtndmovUVZkd2pmVnp3QzhKDQowTWRyYkF4WEIrOFowdmVEVGpKU3hDWDdDa2VQTmJwUDhPYzg4WmZQejlFQlpsdUp6MFkxeU9MWGc1YnQNCkNvWHY3V2lYVzBjc2tlOUttbmpySHZsczNWS2paTXJqN0Jubzgrc3A1RjZmTnkxTytNTmxqQm9qMEQrWA0KRER1eTg0VWFyd1hXd3M4WDFyL1RPbW84aCsvT1I2K0ZCbXNUOGhHZUpNZllUUzEzVVBYNzlhN0VTRTlhDQpqMnVPNks5UWsrUjlwVkhMZU9YRXpDaXpNbkF0Nzh4RC9mcEJmdnRIbmo5MWdSaHdKVUJGNXdhSDVSemMNCmttL0xxMmpLTUFOTWRSR3RvcFVkUWx2TmRsUllHcVNQdU9IUTRPdlB2Yk1vcS82NVlNdFg2alRHVjlNaQ0KSE5uRWh0RFJGekhNMTNvL3EvbDJsSm9KYkFjOHFrZ2psWllWcUZUdkRHZjNpM1owZHlHZDZudWZSZXp6DQphQkZFSWlaWGtvOEViem9UelpQZW9UWU1rbEtTeTgwa2tMS3pUaVpCQ25zRGlETHhaaHZybktuSWF5dkYNCjQ1eldGSUhRbUxBWUhUQThOZllrQVpPWURzVzlMVUgrd2J6ODJUQzhUNFgyU1N2SGNKZFo2VkMrbEgyMA0KSjI1VmpSY1pIUmlwZW9udk5rVzBrWUtVQk5zLzZIU1R2QVg4WWJYVHliSVdlQ1VKb3dXdzl5bWRDajVPDQpneHU4SHdiOENBV0lTOWZwYklYdGh4V1Q0Sm0xRWFvWkhSeTc1UUlYWHcxMWhqeStsMmhkUHlweWNuQVMNCkRCSytsK2FIT2pSSGw4SUc2bGtRdzgvOWhWLytDN0VQVjVqd1ZqU3pFTkhSNnYzYzVHdHEyT1M3bElyRA0KQmpidm9FQ3NhajRRdkdLdUJtVHhWQUUzTUpybnlaNTB6REYyc0FWcGU3ZzdPWlV3OXdZWDkwc21sK3FmDQpOa25TcFlkNGxvODNZbHcwMWV1YU5JWnMwQmVQOTlhOW1sTEFFWThGb0N4R2JWTm9uUy8vRUJTbm1DSmoNCmNEcXUyM0xrU1hTNUhQa28xeDQxNDZQQWJzbkZtRmgwMGp3S29xUStsTXNsb0tyd2hoUnBDRlBBM29jQQ0KanFqaHpjejBIMG1jS0NQRUJrYWcwNUJqZE9URzdHa2h0WEcrSlFVQ1hYWWpvbzFvWHVsU0hWVnJwL3FzDQprbkkwVnprL3VaQlpLOWM4VHl3QW9Nb004MjMvVmhSc0xpU2xaclB1WUZXUUcxOTF2aDJQMWJOQndFZngNClNOYjRxdjUzU21ybmJmbnIvc0VjcVhFUkhEUWxjQTNGQWUwajJsRjNqZkY3ZjgzRTlIdEFoc0pObzdHVg0Kc0ZkKzdHU0pwRVBCTUUxTUQyOWRVLzdrekRxcjkrZmU5cG9HVGR4L25WMGt5cWdIVnBIYUovV0prUWNSDQpNdnJKQThFajdoY01hOHFaMzE1czNJYWJZaFRkNXFRUkFsbjlvRWNRdk96WUw0eWQ2b1Uzb3IrTm1wRnANCmRzamgwSjVCdUlFS0FMYXlhM0VreDNhQ011TjFLakh4ejR0TXB4OVhoTzZRY3NGR1FxSjM2UVNhTkUveQ0KNlI0SDM5dm5tenM1aCtJUkptTTN4eUtNS0pMUDZyaXlsWVRhUzl2cEVoeXYxZHk0KytVcXpIV2hxTExwDQpIem1UUndwdTd3UDR1VkcwZ25CMUNJc3JvWVlZekdadjIyK3RHS3ZxWkg1MG5zMkFaaTVnS1pZTk1ZWEUNCmtwV3N3V2NyM3JHZzFEcTY3RG9hQ1A0NTlNTlFnSDYrd2p2SWtxRFpOZEdTZ1J0Q214bjlXcEV1S2NZdA0KRWJjK3V6VlJaN3Zqcld3YTJ4aWJOajluYjBBOXAzS2Jkc3hBd0RqWkgrUXNSamRhYisrMTA0THNEZ0VFDQp5RmZUZmhOQmd1WHVnRDk2KzlJVHRaS1VYdmc2SFUxWE82UXF0NXUzTlh5UjVOY3dJaTJvVnZsU2ZMbXoNClZNc0FaV29TQjdxMVFCMVl1ckF5SWhTZ2hqcGZ4YzIwTGZQUWY4MndhUmxZRDl4ZlZQTXpJek1qOVpSSw0KTURuTFB6elQ5L2RyTDRSSW9JN0tFQjVCb0tjYk1sSndVNk1CdUFyVmR6a0NWL0p2Q1dYcitwczlicEUrDQpFdi91WlVtQlAwekRKbDRPYnVxa3c1TytUQXFTdklUNlV2QS82ODVhQ1d3bXJ1OFc0ZVlPa0lidXpjaVENCm1jT3hCMEZ6S2JvdWZqTW1zMmUrVlJUYmwyR2c1WCt1T0hPTnd6MUF2K0NOQ3NzT09XSWp1UnpjeEx0dA0KbVpHTGpmekJUQkltbmFEd1NaOXRJUEZrNlhzaCt4b044dmp4ZnhjeXA3dndYejgxb3RTWFhBemRiWll1DQpERFFmWmlWeWxNWDFDS2srd0NPWHMzZklnUi96VTJyQ242UmN3OUZaMU1MMkRzL1h4bVhFREFURjFpOGQNCnZVTVNPT0dOSnFkd2JYNytKbk1KVWJ4ZGdWb0FmcXdjL0NTZzB1disrN091VUR1aDBkTkJKWkxueURmWQ0KVlp1R1NDMElHWkg1Ym83bEJmMjZudkdNeXlhNlpQMGtmNExZWkFDTGZwK1luTzVZcDF6bE9xWllKQW53DQpGYW44TW93WGRDbWxLODdySmdOa0dkWVRDRnE4NDUzZDMwQnBITUFWb2QvS0JUNGxOaWxzUVJwYlltOCsNCk03VGZ2eXJsYnJENGdHdXNPR1N5YXdwNWF4bVkzRGV2bWpzVEJJOWVmTlR2VDJ1S3lWdDlrd015cm42Mg0KOENuNW10NUVYVk5pejI2L2lSa3U3enUxbU5SUmRrTmpHWW1vbk94RHFncUM5WUZQWkZaWlpmUUJIVkdTDQpuN2xXejVvdENDbHoyWUN1dEFwYkdYMWxJd05jNTEwRG9CQVBxVjJIaktiZW9qbklaRURKUlV4eHdJcUINClMxcEJUSFIwbElqaGtMWkp4Yi9ObTFKSXRLV2VNNHRORHlHeEtreHdVZUtyUVhMTjBuZW5mVXVMbEFvSA0KT1ZIZ2VGMzYvQjd3eFlwUE9NYVUwbCtWd3lQUktIcU5oTmErNVBpYndmYkMraUpqNmtWbDlWT2dqNUVZDQo0QndjbTZERUNKallCelladEtsZGZ2VFFBdEpub3c2SG96SHZ6RkJVUTVtTHJxQmIyb2l3Y2FxczJxT1QNCkVnMVRabWluaHdha1RPNEdOenh1R1hVTVg3T0JiMGljTS84dG1nVHlmbTBOQWFNNFJUakkyK0dZOFdGVQ0KR2FyNEVmQ010a05NT2NVbHY2RkUvQkU0OG9mclNWMzdVdSs1UEcxcUs1UXZ2SFgrVnVWZTJqZHBaMGpGDQpkN0NIQTQ3Z1BHaXI1MVlka2w5WmJ0TkpHTXdkcE9kM0N0bjJvL2c1MWRpOW84MDhmakNZUVhtLy8xeXQNCjVRNmRmV1FCZXpBTnN6bjBPRlJYNVhHMXhMK1hqWjh5RTZEMmtMQUxtbnd5bFp6aEtUZnZoUUR6ZytxKw0KNE40NmxxQTNPMXY3SlpkQmxJMlprN3IwcmhmWVlkTU5HM0cvNERBbmdKSG5zQzFqcHkrdlhpY0xablNYDQpkaFRsWTdyRnNTZldNZHhseWNWaUx4aTBmMzBXOHRqMTZteTdvL3pJZlJ0dnRYMnZCcUNsQTRKMXhhL1cNCnhUNFF4c2ZFOEdjcHhPVnlZK0IwNkJ6enNtNlI2VTUrMi9pNEVPcmJqV0lPdFlpcE5JdVZNRHR1RFZ6VQ0KMDVodFRDc1NPeUYzeUpwRUV5UFJkRHU1TFdwUVY0UjlkKzgxeDBnY2t1Vi81Ny9uWVBkeEkyUFZqZ3hqDQpOSGdxWVNQdVdkOXB1MUpCeXRWOStVZUlnck5HU000d1U3SkZpaUJRL1NZL01IZzN2d1E3SW02NTBSSDUNCkVJRUpNN25LaTJ6UWYyWVRDRFBHTW5YNUg1WGIxZElzTGs5V0haenR5dXh1TFdOT25HdVBqdkhha1FUNA0KYzVMNUh0S2R5TEtCa2djVGNoRW9RZzBUd0JkUWRWcUQ2ZnFqdkVqSDFRY2lrazJtOTdNcUNJTis5SGN6DQpDRGtVZUtpdUxGcDMvOTVOOWFBN1BYNGtaYUtEOEdmalFTS2xUaCtFQ05kVi8xRHJYS205V0wxMi9sNlYNCnoxWktNdmFxckhMRHJPM2tnUlYrczVuaWhJaklGWWlqcWhhMGpscTJlUFhyaHBUazZReG1jSzdmRWhVOQ0KUUFFb0JKM1NuSzRmbFlBV29nbmttZE1SZlBlVUNKRE9VeUYxK1pUSGlUbjYvT3ZkTGwvdFIwb2ZUMXRFDQpIeE42Sjl6Z1k4QklYVEpOV0NUOEg0RGo3bFBVM2M0U2VQNXRTSDNrSjc1b202VFlPNGtTT25BeDBGczINCjJKY3lpVkZLNFJVdkJ3Y3diS0RvUXNjaVNtQkdYbTU1VUVJU0ZFRTZxcEdBVHZHWmtpaG4yTUNxLy9HdA0KWFdCN3I3cGVyaFlqL3pjb1lvY2I4QlFQMU9jNDlQQk0zZ0d0M3FXRUtOd2ttVUpUZTdWT3JxVStiUko2DQpNbEJQUVJ6ODhLUERRSk5rZm91Y3M0TUtQUGRkdXBUVlFUOXNwK0NMdDEyRGhMeFp4ajMvZ0xnT2RPcU0NCnppN3JieTBvekx6b2ZoZmFxUERMdEd1ZHFpMC9tTUU5TlozdWU0LzRTRGdVT1RIZHVvODVpQmZzc1k0Mw0KZ04wYytGS0UvaEN3S0FCaVB0WnNPbThNOVh2bDNGQnRrdUVWbDd5ZnA1bmNRNktGZU9sSWdxOUl2Z1pIDQpCL1oyMnJCcXZCUWlHOUhEbG56VnAwK3FqL08yQWJ2VG13dHA0TTRUTWV5L29BeDhseFVCVXlxUVRtYlINCkhtTXU1UkRVUGcwR09oc0R5OE5JVjhNdlBWajg1N0RxRGJvYVREd0dIdnpyT0RuL0cyejZLOGx4TlFKMw0KWU9LT3F6QkVLT3R2V2FVNngyY0F5cTMvL3BmZ0JQMG1rSTVPSHQweWE5Q1NIdkRhbUVNSWVRWE9CVWhJDQp6WWV5NFZZRWNNejZ3MzBtWjlIQ0p3d0NtR1pRNWN2M25lb0dBYkd1bWNJTSsyaDNUV2pINTBId0dIMEoNCnhVc2ZwTloxY1VDaFhma2cwZHdSV1lCNU9YSC9lNTV3bllBSTRQZDUrVGw4NnN3dnFaTlY2c0NLWUpldg0KSVY0Vmlvc20xdnIyWkI0QWxKbS9tNTR4SVV6Vk1Pb1VFL1VzZGpBelNPa2JKLzJvaGJXNmt6V1d6Y3lwDQpOR2JWOVV5L2dkdXprWWpSbU53M2x1cTNzaUo2RktjZm9JdGtMSWhkb1N2eXNncmtHZFBHcmlzTGFhNHoNCjV6dk51aG9jZHl3TW9va3RqWHcxV1VXWFhKK280VkJKcC9Ea3ovbmMrRi9BMnF0RUdNektnYUhjUmZvcQ0KYVNCK2o5dGR0MzJmcE1BSnlFNTZCbFVoRDROdWFoWFdHWldCZTlORlVSb2g4MFI3VmZLSFViNW1QQXp3DQpDWnFPNU5ZbzRSM2o2emFIa1pydnVxWW1yblFNV3RQOVVWN0hMU05TVlYrbE9YUTFzMUh5R1EwU0RSNnENCnpma2IwakVTbjZjOVZ1SkZtVEU5SDA0b1RlNjBmS2FwcnZFSWc0Z2hpMzFqS1dxYWdEV0FKOS9rZGxScw0KcnFzNDFkRVViYVllOExkMmZncCtnc0Zpc0lOSjRWMU4wbXNSQzRHTkxsb3hQdW9ZeGhaeW9GR1lMVUViDQpZSmdXYVlGbmZKNHpUbVFzb1kzK09rR2JaL3JkSlpRNUVTazFYNEUwaFRTb2VMVGdLZ1hjT3ExVnRtV3YNCng2bXBEZ2VUVklqU0pISDRIT3dkQVlWM2p3OStYT3pvSVBIK0RuMGduaEhNSmlhT2hUdVpLNE5ieEE5YQ0KQUp0QWpxMDRwZ3VISkdUVjk0eUdMZG5EOWkwcGQvcHpGNUJzTmlNbzcyZlZkWkp0UVBPQzdFNjVZbXEzDQprSmJ4eldQREhZQU0wbDlBN240MGtQMFlQc0x3eUhmTTlsTXZVTTNnbDlRUElBUWF1dEI1UTN6bEt1SVMNCnU5YWJ3bGtkOFhWTklKT3AreDJacy8rYVkvbmd2bVNJQlpIMWRZRWJLV2lFaStkV0hrVlZ1blJsWlVvNA0KWmd6Z2JoRnZxZ1VjbSt3eUtqcVFXMUNTTllGNmFkLzIzS0Q4VFd4LzJFbUtIeGNmbVNaMEF6dCtMbFVMDQpIMnNJbm0yNlJPK3ZVbEhQRTFGYndjUkFOOWlnNlpIS043ZEZYWEE0R0pYZWZnRWU1cHBYMWxiRHJKajENCjdKRHNZdGgyaXFoUWxpRlVyYjJLUkFBaEdJWWw1V0s3QlZNWW1acnBYb2ZqYmpySzIxZHp4Y2ZBekNjVg0KRXhMRFFJOUNWdUtTMzF3R3B2SDlxc3hYUWR6MnJUR0hIeGJLMXJHa0QvVVdWMzJ0K3BLaHAvY09ObWxJDQpyeXdrckF6NGtqY3E2U1V0dEhhOGhTN3JlZktwdkk2SjJGcDVXbjFVMU9ZVGlObStoaWVCZVNoaGtpc2wNClJicXY1STFjVzRmTmliT29rL3dNUmhwcEtQNXhmb3FqMFFkbk5JUW1pU0xOaGlnVzJXM0RFMDdIbTRQVg0KRVZyYllMQzdjR1MzVUpncEJTT2lYWWk1eHArT0RKczk4Q3ZZcE1XWXJtN201Y2luaXhpbWIycE41WC84DQpsV2hjNEtOUnc4aWNHWFd6dXhOQ2o4ckVuN2ZXK3pXR3hWUmJGbFZVUFhUU1gwTHA1YmYzNTJpS00vTWQNClhkaGdLZDlxL3NKdEk0MTRJL3ZiNi9Ldks4bmdDaXJ2Zkt6M3Nrd3Z1MDRXSWxBRkNqSFF2am9JVjkrLw0KRHVYQTM0Y2kvNHVyQzlrSUhGQ2NUamEyYlBOTS9Wb21CR05EaDYrR2NaZjZiY3liVFVuTDJ6L2ROVW41DQoyb0hYdWdGQTJiYlpibW9uVDZqUzhqMkU1bnZoNXVSTU9CRDdaRC9XNVM4Y2F0VFBtSzJPTzdsOHp3cVcNCjdMR3BrS0ltdnFldW1hY21UQjhHRmNINkJtRTQ4L1lWOHBJSmJCWnpCRmNnK0F0MWFYZm5LbU9BUTNEaw0KQk5yejJXL0hWSWxFeExXcytXUzE0RTZveUZkQ2MwRjdTSCsyM2cydmkvVmp1amZNdFVWVEthNS9NdWdhDQpBU0liSWlBMjFwWWJXdHhmZ3NML1BYRjEyZzJwSFY2eFRDelhUZW1mUm1RbWM3ajdjRlFieE10RXFQcDMNClpXRHNPYWc1N1Bjb3ROdDhMa1czWk52NmZ6aDNIR2tuK2JITlU0d3hZczYxY2haVkFCenl5S2wzOG1XWg0KOW5sY0tMeklKUHZxcUUwUzYrYkV0Y0dCNXVYb3EwRnRtUm0ybWMrb2FzZE1RVDRxTkRleWE1TEQvOGUrDQowdUswd0JnZ0FlWHBEczI0QmdkVVE3WUpiTms3cjNrdnFuUFRoNzVyRUhjNmpEV0J4RGxpSGlFN2NJL1ENClUxR3oyWmt0MHliejVTK3E0dUpYMmU0NHhGMGF5UE02MUdYSzNuekNFOFhxK0hFTkRNUnduZDZwWlNHag0KM0FqOVFvNUIvY0QyaXRjbmp3K2FJK1pqdFhjaG4zRG45T1l2R3FxNDBZK1ZOSGpySkJPeEg3WTZueU1wDQp5NU1QczErQzhpQjlBdzhMeW9zQkZTMHVtdmVwQlJxSytnSFNvTHdhKzBOZXRQZFBDNkZoZURiNXJkYVYNCnRGKzZCMFd2dW9MOGRpZTRORkh2aWtmUVRzWUFUcHd0Ynh0eEpmcDFFdm53YmcvOWdKMmlhc2xjcU5teA0KMWtFcWxDcWQwbWpBZWtNQTh3MkErUHovNFZoWmVWdEJTZ085ZFJKZ25za2hmbEI3K2ZxNzV1cy9WTVRKDQp4TFZycmpDdlE1clZhSHVjSm9GUko4Wlo4ZS8rcG9oMVVFODBsdTlKQ1NjTWd4MFNCYjcvZmJDM2IzOEcNClV5T05iRnZtZWtiTktPVkxwb3ZPWVlRdVF6eGdraXQyWGEyVUxjV3VrbnMrQ1NqeHJnT1hQY2lXWktWSQ0KdEtQUkRmR2Q2U0xOV1A0UCtPT3JCSGEvL1VTTHpLZmUxdjhYWXlzYXB4MEJqU2NpcHkzTVBFSXp3Ni9YDQptSXFrV1lhQVlSQytpR3VKa0FHVFJyb2RCSmZyNFFDRU9FbnlFT050SUsrOUQvamxRY2xSRTZKM3pCWjMNCkdzSHJpSDVQenNiSlFBdWwzb0pKV0pkN3dIVkxzUStLU0JyWkJLS2prUkljV05INVZCeWZiU3doc2FpUg0KVS9xYmQ5TXd4TzhOZlJGM0NKc1FuSm4waWVLdHJZeC9BeWtjeEJSVWkvd2YzK2Mzamd3WlZrbGNQa1VhDQpmMUYrTktva3JuQVBzRFEvMW5aUmN4UzN1NThYNjhhQW1tdk0vRHNRazFzVm1CWjJLYi91Yy9vMEwrUTINCjlTTXBCS09rOUN0LzVKRUJEZU5FQVMwVzM3ME45bVl5VmxNT2l5WE5VTDlRNDhWNFA5NmNmc2F5bU44dQ0KSTc1WkkzejBKUjZHcDB6S2ptb1dxbXA3NjNOMWJKclpDN25aaG9vRTdDZjA2TWREZ2tHejZoMHl5ZGQ3DQpBakFEV2NmZTNkMTFWdHlDUVFFSzlPaHIzMFM4YXhzRHdhTFNmZWNqWEpmM0VUYnFBTzRNTmsydkQ4aXoNCnRReERBQmQ5eG45UEQ3bVpnOTY3MVAzV1BKcEFvdVRHNWJ4bkdRZ2dyd1NPaWJlazZObFVwU3lJdGYxQg0KYjdpREh1RnowWGFTNXhaVXRMUm9TczNOVC9PbUFBSFQ4R0xYNm50Z0E0RjZPUE50cmFoRFVmZnpXMjBoDQpwT3BncTJralB6RWVMMDREVFVDZVcvYUxEcWorQStDblB5Z3A4RXBac0xiRm1EK1ExTldlSWhrOHU2aDYNClk1WXAwdDNuWUJPLzdYRGhzZHhZR0lja000dmZQZ1VXU2poRXRML29ROC9XZjY2RWhGMWxobi90dm9qNQ0KcUZNbnZrNnJhL0xmT082WFZHWUtBdFdvQkpwNXNMd2RBd2wzSVFOR2xlakdxKzJSaWpzNnZIRFJLTUhODQpTMzhEbUxsd2NYdGdjQlMyVVVPc2wxd3hEaXBXYSt6dkdXek55SVNabGF4TjRaSnBZNlpuQVFjaWR6ZG0NCm9lYk00RW5sOENEVUVuaTgxNDFzS3dZOXBrTnNFQ3Fld2sxRlRQVFBnZHErQ1VlQ1lKWmdjby9WYnd4Yg0KeEFTUFZLZHM3aHpsbTFZV3pKdU5PU1pEZ0FjUnhRY2pVNGlJZ1NhOStrL1lSbmdzdWNPd1VBZngvTDgrDQoxT3N1YVpyRVlzUkFmTEFQWlVMZXh5aU5oQURTWm1lVWVyQkNZMEVDK0E0RWoycHA0K09oNXYzQUR2VWINClpTM1lRL3l4ZTh4dGo1RVFDSzVtdTZjNSs4T2RxelFPdTY4aERCTVluOFprSk0yQjRhbjZ3Z3RPQ251WQ0KZFVWMmhYeWhuS0RuVDcrOVl6c3hhVjNlMzFnRW9VZ2ZtdHptMEJUOWZnV01MUHVpQitWMm5VMWxyeVRnDQpRamdCNXpQV1ltWFBMaGNHQ1dnWkVXOThIcmliTXlVb3VTeldDTnRlcllKZUlRSGgya2JZVXIyb2haSGENCm1JRkRvWjRnRzNjTkdFQ0VyRXRrMFBZbWtadUNpWDRQTXZ6cThGbzlVZXd5OEZsNjE2ZzNVbmUxY1FERA0KcUpzelRNQzc5bHhueG5rRFhvN2E5TTdsdHU3VStPdEZSZVFmd0RoeWhIcENUbXRqOWJHWnZZR3R1cll2DQp4bE1jMEZtNkFOZlpIWi9RVGhzQnpCTjBPMmhQTWlHTlF2Wk9JS08wUHM3S2tUK3BGaFFjeklZTFhTcjgNClZXSWtLN1NuckhqNnF1YkFGRU5hbW50ektkM2wzNndwZGhBMHNWemxxSWhtbTFKNzN6ZFEwSmRCbkxINw0KY2VIU1NNYkJJSXJudndHclRhcE50cEkyZE9ZVlVYalFjeTRpQW54cDVCYWYzZFdvek9aRTJsL1FXSmZYDQo1M1NNQTdjZ01NOVpvbHVucmxwK0Rrcm9ibGdEUU51Sy9QRldlaGdFTFVZNkxTTHE4czhNaWpIU21icnANCmNwMVV4ZXVyUnRiYnRwd0hWSE02SUkrRHhYR0svMjdidzdUQ3BiWnVlbDgwd1htK3YweUg5ZGRFU0dGcA0KZC9qQkl6cmNhZHB1c0lYamMxems2SnA4cUlpQjd3N1RHQVNTQXI5dURaeSs4SElmS3lIdWRkZVNwMWY2DQpIdm1OM253cFVqY2c4d0Y3VnR0Zm9vN3ZHblVHc2k2TVJXTzBnWllsSnFUMXBqUU9hUnAreU5xWmRYWHENCmdPekhPNlV4REkweDhFeWhLTjR4TXo3dUpnZlh2WW5CRkxxbGEvMVRvUlFTais0QWJrZlplWUJrZnFWUg0KcWdEVkxMUCtwVXFJSUtmeFZzWHQxMXdyMCtnRllUNG8zc3ZJaFVNTDZ2dmpXNVNDWmMraVlHTzJzZnJIDQpsS3l5dG5GTVpIbXREdWVLK3VlTmVJRUhVOTJxT016dExiQ1VoNTd5dnR5ZU1xVjdNb25XU2NnckxKbE0NClFLT0ZwUnljdkRkRng2a1h2WWhIWXMrYjMvRElMd2QzWHZKOHpJTnRPMkx6MEJSN3B1Ymw0Zk9rM1dNag0KS1dPd2w3cWQzVzhTRkRZTm1VbDJWRTJhQTVMSy9MVzVUODF4VXNUeHFSS1JaMCsweVlBUjgwTFpaTUJkDQo2WGxtMThsM3VaMDRrOW9VbERpb1VwU2p2LytrN1hyY0pKeVBqQVFJMTJrdEZVNHFlc3VOWi8zZjAvYnUNCmJ1dDZDNnREVEdaUHJDaCszRU9jYlp6cHBzV0xrSGJHYXZaMWFNQnRETFIvd25ic3FZTmx3eGFXQmtJaw0KSXN0eVZiM1VmYzF4Um1jR2h2c3ZTQmRjSlFQVHJpSHIyVG5UdDN4MmM1S2hvZ3lSNHV0dlB6dTV3NVQyDQpVTVpza1FJRGhienVwdUpqVWR5c3M5Q29kcjR5UVErYVI4ZjNGV2tHbm9MZGEwOTk5dHZtODZ0RzEyY1INCjNkQlhvOWdFNW1JUG1ZVUxCeVdLQkRkK1J3cUlpQ0xxdFA0dWNHUThKZ09VdVlabDNrelJxTUlqWHRHYQ0KRmdJQWYzUk9idmpma3RHTEgzKzViaE53UDdsS0FFYjNJc2E3b21ad3JHRFVETnRJanZsM0QzRXFNcUs0DQp5QXJnWHpmdDhNSnRpeGgxMjRRY1l4RENRMVdkYUNQM004RHZBQUcwTkU4M0ljNndBbGg2a0hnc0g5N24NCk5tbGpBdnNwaGNRSnovRGhZU3huTm9uMTVTSUYwb2F5V3dON0hJbU93R3ZpNEc4enJLUll3VUoxRlpEbg0KUTFkSE9xTGlrSjhNRTZZdktkYXY4VFI1c0tRRS9HQit3QVZtSXlEVEZrWEFJb1AxR1gvRHhmNHcyaTAzDQpSWE1WU3lMMXd2d3ZEYThtUE1hbS85WlZLNk0xRy9zVWNOUDlWUGZoNmFaV2tzMyt0TUJjVURZR3ZQYnkNCmRVaVFQQjh6Y2dNeW4yZHBLSDZmRzdtTXV1UkNCZzY5Y01KdnF2d3I4elFmUmRQMlRMdUpWeEd2eFFZbQ0KQThiR0NOWGtWcXRnOWhyR3diRFJCMHpqYmR1RFlkOFJOMkZTS01kNWEyNXc4ZklmNWZrVlhCbnFoeVBMDQpmVGYyUkdmVnhQMklROGpuUVlicDhqYUl1cW5wQWJjcy9FWnJMWUtkZ082bjlPSVhySFRaaUtNc1ZlcXUNClBJV0pkYkVtbXJJRVFiMkVQNTNPWEFlOXB1NktremlmRGNhTzE5SWpYRXljYXdKRmo1bGxFeThINThYcA0KUkUyRE1FSlp6bnBlMldZQjBUT3hrY2prNUsrSUhQWklxYjRJZ2tmSVlKd3V2bEwrNkpUYnl0TXBabVhwDQpPQWhFNTJnaThRWWc1eStxUExRbnFaWkhyb014TE12NEd6ZnAydmhIa2pVTjFpQ3dzZW4yYWJSaG5CdmkNCkJnTEtXYTJsY2hmZSt0MkFvaEVQbVBjTWFaNWdhVldKQVNPK3NCbndJRG13WkNSbkdKZ0ZTc0hnZ1JNYQ0KckVnTjNkNmRqd3E1OTFjNzZNSnIraWMycVhaNVVXanJ5SkdJalA5OTdVdExTVk9NMGFmUjZyR2szR1dsDQpvUEUvRmdnbzVsYjV6OUpRZStzV1JkcFIxNityN3JmSXFKeEFwaEVST2xCOFV6cS9jK1RuaGR5TjQ2a1MNCnNETHcwbDNIOUhCYmFwTWg5cGhCYWtWSEZEL1g1NnpuZkQxUGpDMG5BblhBWStWOXNSRzVRVitxS1BBNA0KeVI4elRZdmVJUzNaMkpmVzBqdlovVEdlMElLN2hxYkJmTHZxNTZlT1JFZjhyUUE5WXRhb3RqSFJacXo5DQpOT0NLZEZ0MHNDZE5abmx2Z1ZYMW5XSFF5RG1hbHlOZU5SOW44QVpTcVZQb3VEUVdrMmdtVVBUZnltc1gNClVNSkYxRXQwOWYxd2dEckw3NkdVcXlFRENsTUhJcVprVVlydjBrMzhZeUFQaEM0MkRHMFBPbFhZVE55MQ0KRGZEVFZ6SDIyTHZDSkliT2ZnL1NqcWJOWFJRSDJ3K2NiNlM1K3kvZFBnbGFVa2EwdXRNLzEwbXBTejFzDQpJeXJtNWp0SVZqOVR2RS85aEJvamFyNmhTcWU1TjdyUnFHR0Q0bzU5dEJIYVZkM09xVlJCckQxWEc2T3QNCjhqMGdiaXhra1N1T1dJOEtnUEZqZGl6WUhndGJ0bUc1VXhucllpdHJmQndicmFGYWl1NjlHSDBjZkhxWQ0KWU9STXpuaWtyMmg5VG8wNml2YmdSN284eHVJemRNZmJPcDlnbnVnR2QvWUFnWmlPOUQyVitQT1J6a0FVDQppUUN5d0NOaG8xdXZQOXZ6bnNGY3FnUXd5RVJ1Z0xUeFdZOWE0cWRVSXp2ZER2enJHSGdOaHB0eElHSnMNCjNKZ0RyTEc0eEZrbTFlYzJvUEozNVU5bm8zbENRNXU4UGFRN2Z2c213SmZrSThCVGV5NTVjTWdha21peA0KTmcrTnpxNlFlOTh0VlE4MDQzL3g5cTg2eDAwSzRrWXV4cHJtY0l2dmVCa3dyUmpTTVdhWElEWlV0Z3NODQpiMjVFTjRkbDlOZWlhNmNpYi8wNGt4SjZUMlhWT2lnME9kalN5TWIrYU4yaVVGejgzeUFKNWxjT1dIdnUNCkdyUE9vK05PcnNqMk1lVGJBcVh4OWsyNmh1eTRXbnRDb2MyVksrUm1BRXIyUjBpb2lWYXMrNC9SWUpGNw0KWHJiZ1lFQWNCNVVSOG9MOG10ZDZONEVXSVh3YmF6YXBqTlJid1lGUUFxdE1rb0RCenpsRXo2SHdNUS9CDQpvQ0NudHEvcWY1Q1YrNjducXlpWDhTS1FQZ0poM1lyTStuT0YvVmU2VjZwYS9nbEUycDgya2xIRFZhZUINCkFUcWJiU3RFbHlNY293Wkkxa1BvRkovcEJLZ0ttelY4V1NqYmNxNzdBRFN0WDgrWHc2YU1oZmtGVW1FQg0KR2kxam1yeUt4UEhSTlB2anBZek5ML2t4Q29QZWtLSG0xTHJkK1g1TkJHVS9Qb3RZVFd0YXdCQndkK1hKDQphYmo0dER4am5teWFWZ0dLeGpSdnFYb3Vjc1ZqaDJxL3pFTWR0WWVCWEJ4eUdaS1E0blliMzRyaGRZbzANClNLWFE2TlVKejNWci8yQzlTMm5uQnRHR3JJWnVvUG9VRTlIWThESElvRmZGUWU4bUxhU0hXQmJsaDFSMA0KYk51bUFBVTB6Y2JySS9MTzRxZTY5SXlmcmNuUlUzZ2N2dHYxZG9UUXRRcGkremZvR1F0c1NJSlgzWGNzDQpVWnVzUmZMdlRFZ1hURDFyblFwTHgwRHBjRXhZY2VZd0FYenFkemFyN2FzNFBnT0hvMlMwcWc3R01ucysNCnEwNXVwTEJnenlrM1F4WnZ2Tm5PMzgvelgrNm1iQjNQQ2RjeWhNQ2I3RHBTOExIWFR0aGhqTjIraEVTOQ0KaVRvUXlIQUMxS2hSbmlvZzdBcjUxblo1elJ4V0ZtSjI3VWNGVW9QUnBlMDhDWThhZHV5YUhsU1lVdklODQovZSt2dVNFNDRncUY3ek1Md0hCRE1iai9BNDVjbHZCTGwxZEJmMmc3cmc4aldCME5vdFhqT21SYllmSVgNClhEbmphanFRcWZNUkVJWVl5R3V2MnRlTm9pdlg1aE9WSnQzZmdqTFFSYWc3MmtuemRya2xLVFpsZ29uRg0KMysxZGZLYXQveFdGM3dZQm1GVGxLeFN3ZlhNZVhNa3VwU09RblE1a21LTjZIeWt0YlF1dDRleGlFbW5zDQphU01INzBqblVtaG5LS1V1a0R4U1M5YWgvQnN1V2V2cUlPcU8zaW15eGdsR3pTTkVLMzVIQUJBLzN6Y3ANCjZWTWMvMHJSU2hNaXFGcVl1Y2lVTjVXSTJuSStVdTBqd3duMVRLbU9aVzlTZkZNaHNTUzhsa0hySnNQcQ0KMzVYY3R2TmNCeFRNZm55RU9Gb1JMQTBkWENLbUtZMFdrMGtSN0Jja2VYMEUwaXdoS3YxQmNsbmt4VDd6DQp0YnMzS21jYVdvNjNFSkp3WkJsemh2V04rbVRRazc2Sk0rT1BseEh3dVQ3d1hXQUxsTDZKdWRGSDJDS2gNCnJraTdRejRxd3l5OGRYZ3lTZFp0NGpaM205bk9kYUs5M0VzZ3FvRzc0OGNZTUt2TmI3blQzVVA3WU1QVg0KVlgzcDZBR29kaFIyRVdVbEpWc1huV3VrRGJWVDIyUStUNnd2eklxeWU2YzVDaHhNbW1HUHRJdDI2SUpUDQpnR1NNU3BKU21TSzkxWmZzeVB5c1RHbGlKaTBxcWRBTDZ3dWcwYVVGeTRQc1hVM3czeGhsOURha1pIRmoNCkVxRlhVOGt2Z3FDYXZNU2s0bXN5cFIwb3NiMlBEWUNHVlVHbG1XclQrY0ZoclRWQWllZWRUaWF5M0pKNA0KVlVZR0lrQUNoazRyL2dlVVVpNWdIN1l2Y1duNjdaKzhkcFNXRjErT2VPYlROOWpDeDcyakx4U1BocVFUDQpwT010aUh1Vkc4TnpyVHlOVXN2MnZaOGZKY1ZGVE05MUg3UlRVY3lFNDB4WEQ5ckROZW95OW5IUHZYZ3cNCjg3cG1Rd29JUFUyaEVQQjB4TXRnTkwvSEd6ZWxJYnovQ1lXUDJPMnJ3QTFqQnptUS93RjU5eTdGdlo0SQ0KMlVzNTh1U2hveXV6RlZMYndmclI0VUU0ckZDQWo5ZkE1OFlqSFI5dHdNT3Nka1B3K245RWU5aFQ0eUY2DQozOWNnRnR6NFlhOE15Q3VtZUpNUTZZUjBHUHhUQTN5ejd6M0RocnVqcXBJMk05eUR1TEVtVzFuaEtwMlYNCkZLay9iUkJ4SDYrcEluZ3hTUytxNnRWNERKWktCUGwzQU9ScDBEZzBwNlRMZkNnczI2V1NTZ1c2amdMeQ0KVWF4eXluV0IwQ1k0TDRRcVJlMFo3ci8wbjZPSldtd0ZMRWtzdS9keTErWTMybUY4b2dacXRNTVhtbjNYDQpKNGpNb2ExS0VTb2dKTmZQemhZU1RGS3d2U0hFaWN1bDFFQ1owdlB0SDhIVUI2cGJVTlI3QVd5UG9CTlcNCkxSU2tDem5tU0tyZ200bzFDdGt1TjJBQ2lNbndld0VqTDY0d3g0ZzBIZHF0L2xPSGdxVkRXYk9IZW9pag0KaEFCZDNCZlJpYkFPNUdvRWJjMkQ1MjlHczlmZHJpUmFndnlOUE1qN0xXK2J6TjZJUXN5UXRIT2pVd0pGDQp4ejIxRnllU283VHFtbTBUUG5FWFZWdmhXeHVYKzV3NGZDMzRSSXNSWU9ZU2NtY2JnYzVGMXlSK284OVQNClRxbmtmMnRLWVE5RGhBWGxHbzV5TnJ4Y0txVkhMelp3b2x4QkhhaW1DU1RUTm9rWGE2aXJJcCtrUGxxOA0KZ0JjR3ZUZ3lBUlJneEFOYTNLalkzemw5Yk14eGNYN1NqUU0wS3hZOHp0Y0hoNTQ5bFA4cG1DUmM5L2tIDQpZQXJJMVhxYi9PK2k2ak5GR3ZmZlRXZTZiUE1nWUtmV3dHbU1sMWlhVTk4K1d1dU1Ka1k2MXpKS2JWaFMNCnhZbVUrdXFxSzVjaVNqWldPanllUDBZRDlnSkpPbzZpdzZ4SGtyWFhjNENqYjFsY0VIOEhORTZ4RjF3Ng0KWnRsNC8rQ2YzWUpvMlhEeEQ3Rm8yWW9pZU9sQkRPNjdudUN5NHNzMnJGVDZHa3NyMzRBNFNRZ3ArVUJsDQpkYTVFbS9wRnpsVUJrQ3dJSFpHYTZPYWNJUUd2VW4zdTJlUkZxdkVmdjJiRDh3ZnVITlY0clVlNkpueDANCk5DLzV2em9heUwzYVBONTB5RVdvWTcxaks4Um5nSkVTellmdjFKWUQ3TUNpeWxKSk5MMzBrQ2IzR1VsVg0KYk9mYnAwTEk5dHpuTXA3VEdjSnNXZ0JzTmdldms3MnhQYWVNVUl3REJWUTJ5eFBVODgyNldPcTUvWEk2DQpweGRVSDZtMWhVWTl2WlQ1Y2dNV2RtS3M0QzIrN0xGSHEvM0lZc1huajh4M3RxM3YyUUhsVk8wVWQ0bXgNCllGZTNSK0kxbjZ0Zm82TlZYMUhEMHJVTEtDVTRpV2p4QkpGL3pNa1BEZlVSR1NKRU04MnZDR1c1cjNjcA0KZDhNaVpTVWpyd0U1YitLSm41UjdsU2dBU1IvUGY2aWpuSXQ4QWZySzZyUmZiQkF2NXdsaG9tMUV4MzBpDQpNanJWdllpbUVFOE52WHBBcEN3SmUxUGk0cVZaMENXM3BsY1ZYb2tkZUZVWHczeVNpQ1VXa3ZxK0lDclQNCjhENmIvSG1Sc1M3MHJKZnFtTmtmM0NBcEEyOFJQRFErcXhLZjVFTkE0QWxBbGhkeDE5L2RkQUZUb1doOQ0KVld4RmdJZW05VkR6YjJYanFLRS9UNndCOFJ0dUlKZGNFdzRta3FudStteHA3TXBobjUvVU5lYVNNcFpkDQpFbzc4cXhjQ1FGWVVZZzgzamhnRkxyWGZFYVVMWmFLcVBzRlNuVWkra2FJcmREUW9Bdklpc0JGN1dlOWUNCmkrTFU4aXJPbklnYmI5TjVPM285dGh0dzhuRW1wYTRYaHpqa040NWJPdlhmRzBEUHg4Q2Y5WGZLdjJWQg0KQkUrUFYzWEpDaVZaS2F3QVNKTGR4b2Zsb0FBdmVGWE1mRlZQbU5sQ09GMVI0aXJqRHpueEhBcVZrRXVqDQpOKyttbzdnTlY3QllFc3lvaTRSeHpJeW0ySWJURnZhR1FRREpHcFZYNUYzc2xyV3RZanBFVGQwL2hYOE4NClBnUW9iMVV1MEVyWlR2Q01GTVN1V3FMTEVYRWhSR09ScmMrUTNDZUgyNkp1cE16RkdzVnJPRmgxMyt0OQ0KeUNnNjhSZ2Mzc0VXWWFTQmNBRmVQd3RoSFJlZmxwWUMyYXRaYmVUWWJsdFYyeW05VWxzb2g3WUplaXFrDQpabUtIOGltNUZFSlFEbWwydjR2V3A0ZzZSYnFGVXJUby9EdGtyT01OR2FyMzlyMjV2amZIclpLUkFvSDgNCnJwTXp3NnJPUytWV0tFWVRKdVZaNEIrRU9FYW1nS0ZjWDA0OFdpUkh1a2Z4MURzQkZHUTJHcXQ4cjlUTQ0KaWp0TldQai96NWh6YUhNWFc0L2h0cTdZa00xbGZwUmZuY2RxelViZWhrNTU3REJhYUF1ZURTZ2drdGlZDQptSXp5M29aKzNPTDV5blhLc0pjbFU0dWdLU1BqVmVxNjA5Sm1BYytmV1ovbDBQRlVrenp4SDJwRnpZdkINClFrV0dBdzFQY29lYW9WcUptK1k5c2ZnaFlxb2NUUlZJVkNCbzZEV3lZMUF4T1dmeW1PemF4VjFBZFlFaw0KRmpDNE1nalZyWXFXbytUZTlqTlNhMjhrVVo3VXdMaVpjWVdPb2lDRjFzUnRqQUZsQmZCSVdHL0QwTGhmDQpqSWV6VlU5Ly9pUVVkQnorTG9kRjBWTTV3NlFlUUVHNGNlSXdZVktRQWRhTlRpNGdmU1I3NmZTWW9uZFINCmhWenRaTmh5WFpZblMzVWMxNE9UQS82RXJCKzNjaERFeVFWS242SE5zb0cyKytBeFA1UWhsTzV0SGRZLw0KSUZTUFh6YXZmdTBiTi9tU3hiL0o3YWU1SUxpakNuRGFKK25NSEJ5eTdaZ1BFVWVSenlJKzB3NjRoRmhhDQptTkFobkpZS05Qa0RSVWxaclVPMktqZVVIcnYrR3VkelZTRlJteksydVgzamxlSGZRekxIeE5BVzIvVUwNCmRHcTF1ZFhFK29yRE9zbXd1ZEhnWFVrSitZUGYva3EwVUpNZjBqZ1NDMXlwSTM0UGZDUXJadHdHelVTcQ0KNUxxMjRFTWpJbW9BRU5EOHFLNE5wQVUvbmhxbDhlK1pNczBMZVROQm1VeEFabHBNMHpSTXMrSkcrTEgvDQpQRUozMWI1c0o3YkE4UTZxMndIRkVYOEw4Q2tMZDA4Y1p0dHc2RU9ROW1KOXc2VzE2ZHVWSmRxQ1lOcFcNCnBYK211NW5ITEZJZ1BIWU9CRjcyN0tCdWQ2NENZcDBaMXVSenJmcFB0d1lEdGtFeW1SbjVsVk53V0d0Sw0KcUppKzVnaHg2N01mOHlpd2JmQ1VGODYvODhXb0ZTS3RwbjN0NG9OeG85dnBYVlA2VmZpc2l5dkZMZlhDDQphUU4yQ1RWc3hCbGNYWThGVU1Edkw3WSt1SWZVblFVZ3g5c0xVUDYvbWMwWEYrUzlwM29JSmcxSVR4cGkNCk5qd3g2MndCUENzQ0tqMUNTRkJITEZpejNQWnU4cmk4bVZaSC9UTkdvZGpQa3EwTVdjbktQcW9aYnl4Uw0KMVJaekJRaXhOYTBvVFZ1NVhkOWV1ZmRjeTNJekVEc0NLaHhsLzVHNUVRMGhOQkZ0NkNUQVZDU2tPc3pvDQpCSy9NMG1pWnEvNWJhU0lrbm1YcnBOVXNaT3hYeFBSdFE1RDVjT0c3akNLMnVaQlNMbTJSN3prZXNuQ3gNCklyU1FROVNzTHhtaWgwb296d2pZbGs2UFVHbVRBNXpjUnhTMU5LSHdZekEzRWd1QjVrSVZsK2Z3eHo3Mg0KZ1NyNkltV0x3L2hsVmdNaFZSQVcvL2YydXFqYlV3Mm9NQ2RERThEem0rczlHZkFJLzBzWmtMWkV4M0YvDQp5ZnJwcnRvbjFUQnVySTIvZ1VnN3pINU0xL3U0Y05RaDFscnVNV25maHYwZkl3eXBrSmlDVmRQdXNFTDENCnBUa0hERm1rWXNtNWhQTXZ5MzR3Y1FxSlh2VmNvUXhkclk0ZWRqV3YwQTd6OGg5WGtzOUZGL1RabFRmNg0Ka1B0ZnNIbzdXaUdHV1JEMDBWQXVBMmdLcUEyUlhlenlHR3lIU2EwU2VRN2U2RU9JL3o4eTkzTUV0NThYDQpjdVhuc25hVXBwVWtxMEhsNEwzRVBwVjRDMG9TMDRjMW5RVXVXbTV6S0RUVjVmWEkvNDF1VWdZM3lMc00NCjBhZm96Zktod013a0pRSERZQS94V2wzTmVJMnJtQ1U0THU1SXE0K05pZEFoZnVwejlkZXA0cVpoWFJpeQ0KS2wvc1pYSENaRzcrdGtzVE0vYmZBcllHQy9DSmFLVkg1SEtmUW5pU0sxT0hST3pWRmlOR2t3K096WHRODQpzL1BieUxmdGNINmdZOUJPT0w4STQ3OFltR0Q0NUNJcXJXekFWZitKZWtzZEFlcHc4WW1WUFg5aWZGUVoNCmdobXdaOE9XUFNJZ2lhcENBemtuY20vU0tPbHhxallkWjB2YU5kT3ZLQkRVbEFBQ1ZlQ1c0VXlGN2srZw0KdTdCTnFFaHlyMXJBQytTTUh5L3paRWFad0g5dlF6WDA5a05lUlo0SHhjTFNLRm5UaEp5Q2V6a2o4RGdKDQphV2N4ZFNXbTJBZmdxWkUxQXJUNkMycGhrOHNreTJFN0crVlZwVzEwUlBGcWpaSDJFdGRFQi8rajJLb1QNCjhUWnlxcnJRZ1U4RFp3dER6K0VpNTZPR3loeE5oUkZhdk1hTWlORWFjWGFaQTRFM3BqNkF3M1lybEkxdA0KY1hKUTZNQzczN2hzNUJlRWRsRmhkK1FYZHp6R2QwdlBZQUlIL2tuK0h3UC9yQThOVE5TdStnZFNSS1FuDQpoU1F3UTczWlQ1dlEwd3RFN1djTjlPLzlJZ053ekpWMUM1b3o1YU5aUUlOYU02MFlRUVpoOG5HQitGK0sNCmFYRU1FaGpITzU5amdTUXNZdmJVZ0hTUkNIMklxMEl6aFlVcXN6VFlWUCtnd2lmSnVDbktISXlyYjJmWg0KVndsdjNKQUZQOUVqRDBETEtycUprdUtIdXU5NndCTEVqaGdqbzl0d0FaaWs3T2pQL0dNNkpoZmNwdy8zDQpCSUdWZ3g5bEZwNGlKY0tRakFHeGF3a1VzNzV5ZDlSUW1IZWhzZkRyTE9ZYWU1V0hjUmNkZmFmYk9iWUYNCmczNENkL0VBa1g0Yko4ZVowZlNRbEZweTNJWUhJZ3dFUGg4REhMMzFSQkVRL3R2VlNGTElndmlXZ0EyTQ0KWGE2Zm4rVkZIalcxbEhyVGpLbjFtVXRuY1Q1bmd4NkE1cUYrWWNHam1ITVk1SmFEbDEzRmc0by9ERUVjDQpoaHlpNk5pa0FHbjdBR29LLzY2eFNCcGgvTVFYK2pNVjhYUzUwc2hPT2x2V1k5YW1veGR4TzJtbVluMUQNCnJWT01nU28zeG5BOWR2d3oxS2tDa3dkRmdHbDVsMXp6V0Job3Y0QW1YT0pVNGdWQk1SUy9xay83cmxiRQ0KSC93ZVV5ZndQSUc3QW81Y0xtRENlVzljazRJTkFwb1JIWk9zRG9JSDNLcnZGd0pmTnBrTkNOWWVraFhHDQo5Y0hCQXlwNVNyMHdZT1czT3ZiV21BM2FObTltM0VPM2dKVXpVRi9PUnIxNFV0Y0xIdTJ2SjNsQ2p1azcNClU2aTFFVlVPWDJqaXZNMTdYNmVXMmdzMTMwbmZFdk9zS3QvNGVaQ29vVFZvQXhtNHJwZFArSUZWcTNPaw0KZHMyWUt0TEQ4L0E5Uk9zNWx3RkRQWE9iQ1hsUXpzZkpFb0JzUU1jR2tFWEdOQWhjZmNiVFJpYjVQYmVODQo4Z1pra1FudUdrOFRHc2ttemFRUzlkYXZ4UURVQjBRSEoxZmZRUkhibjVnaHlVTW05Z05DNnB3OXFvSkUNCjMvdFhOVEpveXBrWGoxZjFqdUlTMml0Vis5Vlgya3VLMDkwY3VMSU9nOUxiR1pvVzV1T2hqanBGNjFRNw0KTmN2TjNITDN6MXpyVzFicnlzSFdxbzhaaEVvcS8xc2k2RWpTeThGRzE1WW5VRVdoRERQMEJmL25jQTI2DQpQK3lhZGc4VU56QTRBdkZ6VHp5MmNVZ3ljZnBtcTlvL2VsbnpmL1h1VHVZQmlUWTJVeDh2MTJxcXk2RXQNClhVWGV4ZkNKMm1DdHJnWEFLV0R2NVZvRlluL3Z1THZtVGRzRFZCbXEzRE14MjVLcTcxMXErTFNyTDRacg0KWVZ4OFA3U0o5UVpXbUpyeHhkQUdDdTdPeGJYeVBKY0tLY2tHNTVQOHh5OHowL1U5OXRsekpFcU9xalZ1DQpKTXhDektvVkhab04xRWFaYng0eUR1TGJzdUhYZGdvYTNIVXh0Mk42WTQxdVJ4elA4aUdxaFpPNGU5SnMNCkpmUDl4S2VjVEJTdHgxQnZYbk9lOFVtSXkzR2xNb3pWc3FRQzJsTzRIRHFYR2ZTTnM0dDk4cGY5eXVjZA0KTUFCYmlqbC9nb0NhYWZtRUpZRnRRbDNZL01PY0NydnpPVmFEakJheFJ2T0I0N28wTUZqeXdjMTc0UXpSDQpyWElISG9WUEJQWUw5RFdoQXZIVHQ0MTdGVUFLaC9QQUhYUzN3bFRhbW5iY2U2QllyTkVDdjNvckhjWDMNCkZUdnNQaDNYdEVneVpsclpid092SFI4ZUx2SVFzVUJUT01CSTNWRkFnTWlmK0ZVS09DZTRXeWRuVnRVMg0KSksxY3Q1dTRUMHF6c25mUFk1RFdNUUtqTExUWHpOemNnVFNZQjdBMW9xMWdvSHVTSFJwbm5YNC81ckVIDQpnYXFxaXNjNm5sVWVacHptSWt0a08vTXg5MmxqVTA5WFFJUW4yeXFLWUw0dm1qb1ExbXB0dVFMTEdFMFgNCmxKM1Zva2duWW0zWWpRT0tOZ3U4Sng2eHlML1Q4aFpPZlVyVmZLOU90eDg2SHd6a1hXN2t3OXROaFlhdw0KVmNxMUFTMWdHV1p0MUJIaUR3eUxJQUxQWUVBMmZsVmxZKzNyZHZmcjRORFU4dkxDdmhNREZHV3JDbU1LDQpZWkFEMlI1d20wUjUxckZJSkR6aGVqemtQbDMwRmVxMUJYTHlKd2dRZTdjUXYrbWs1SGxhbzR5Zk81NDcNCjRRZGZRQS96cEtwY25jNGpSMmNSY1NOcGQra0VrYVZocW9TTWNJRmZYRFlUMCs2V2RHZ2FscWs4ZUdaTw0KSmFYdlovamY5U0Mzay8zN3BaeVI3ZGtLb1NMOXcxcE8zNVg5SVliak0yTFRpdytmYk51aEJ6dHI2enY0DQpHRE5NMVZ2bFZXcW5QUjlKQTJaaHpvZjVrcHI3QU5CUEFPQWViNzNaQldtWitwZGxsdHROZWczd2Rjb1kNCkFYL3M5NWlWVFVXcTQwWlVjNm56U2dZSDJDVFNTY2tOYkwzd25USU9rQ0JaRU01Z1djajRyazNxU3pqYw0KaXVMbjAxZDJYWW5iVWJQOTB0UEptRGxycDMrMkRZZFd3eHN4c1JZWENJVzZsWnVtbzUzSkdzNWRibk5LDQpTalYxUGVjWnBQTldFRjhUM0pvOC9TdXhNRHQxSFUwWis5VWVuR2JETTRXM3V4ZnE1T0REMXJWSmVnT2ENCnhFVUhLWmIwaGVRb3RTalN0NVRPOEpUc2IzNXFqNHRyakhBSU54dFpqdFRFM1ZSbkJGYXZkblFtdnVyVw0KanQraUN5enBQK253NEFsL0dPaDA4dkUyWXVmT1JXbVJ1cGtDMWY4NE5PdGFDbDFTa0NzcEIyTDZJb2RCDQpUYlpwKzVDN01RSUlqTFdLSWF0M0VrYnBKMnYwZ0xzWGlOM3dPYUJxZWRYU3FQZXpRUXQ3VlRYNTdSWGwNClFrNkhZcE1CTUhDTkFiNTFFVk9MQndVMWR0YzZURW9iQjcyWGJJSXM4dHZqQ3Fmcmdvajk0SG1VWVJ3cQ0KUnFSQzc1SURSNUpmTnQwVHRHY3IrQXU4SVlsU0E2Vko1Sld1WlMwNkV2ZENlQ09JaXVhOE9tZmtUajZsDQpuU3lWMjdYUGxJRzJTT1hRc3piMlVQbkdXd3FxY1ZyM3EyVGxsUFBlL0l6dFhEVEwwRDk3TWVIaXNjOXUNCmw5U2pyRWhvVUZNZEN0TEQrRkFZMndvOXhJc0JEd1pHRUtLc2FlUWdDM0ltQkt5QmVUL1M2WFVsb0Z6NQ0KZHpMQkZrRHNkb3ptR1ZlZTRSbmFLUW5OMElEYVVpZy92QmpITnNVYXlSbHJhVytGV1JGRzNUa1laSGNYDQpsRnVDVHVUenpTc3ByUlNYSjBydkpVcFZyb1kwdjVoRlpJVExKeXpibFpUN2cyUE92QlR1ZmhPaHMrLzcNCm9rL0NVbEdNTk1XK1dBajRiVkRLRFppQmFPVWN2a1kzN0RzSUFXNUM0dHhRaDRCa2p2L2FuY21adWNtdQ0KSk9GR3VOZk5pVEExUWxxem9HcW5oM28zalVUTTNZSlc1ZU4rN2NNZnlmVEVRaDJmQlZocXY4Q1RmQjcxDQpnYnFDcElGcnJBVFRxRk01TGQ1RjIySDdDZjBwUHR5UVh0V3duZ0NRY1Fvb0FwRXFmbnZQTytxSE9TVDcNCkVjc0Z2NjVoOXhIRjIwWWJJMmdvSTdzUGMrNVlWaVh0ZDdlTG40NXU2c3hRZXQrYzFtQnNsWFVUSktGbA0KTTBzWnRIK21GTEFPNGpxdVlZQ1kzSDlSYVM3NG1KZ3A4d1d4OE80N3B6ZVhxLzRUQWJQTTI2cC95YzgxDQpJeDZ5QTB6N0FxZmFOeWFhR2JTdDJoc2xoRGlGbUx5Rm0wMldYb0hrNG5yQ095dmJ4eVp2eUJ3dnB2RmMNClcxcE14M3BoNFhGeHo5cCttMUdMTVkyckt2amh3NERpQytncDlyVEx3U0ZhNjQ2TUVLSGpaQ1ZPWG0wVA0KbXlKSVRUSmZZVXNteHhkYThmNFRHbEJIeHM4Z094dkJBdXdJUzVMTEcxOGpnc1U0SlpLNjBrMFNJMFNYDQplaU9GUTRrZ3ZjbjhvZExGMzFFdXR5aEU1ZXRydjN0OW56OUltWFV2bDkvMytvcG4xN0cxUUNBVm9TUFUNCkxQdVJCaitGR2RheGl0R3ZIZDJoTFRJQ1lPYkNxSUlZZlVKRDkrbC9lSE1OaHpYZkt3bUFCOXpneWNzQw0KZk5ZdTlNRVUxR1hEWi9aOGhlWkhVbTJUVldyNFk0NnpyNjJWTWxUdEV5U01ncllMbjdtb0NKZUc5NWdTDQp5eThvWVR5L1l1bGFmbGtQRTZ5T2doMUJ2cUh2aXZuZDQ1TkxXZ1BmNU9OODVQcTlnM01OTzVKSlhsTncNCk5OZm9Cczg1N28wYVpHOVZaSVRVV2grR2NSRGwrZHJqUGx2emVSdDkxSFA3QXFrdjkwUjhCNlcwUGwzSQ0KZ3RjeXljU01ORHFhK1VjbGVzV2JFNkYxUGtZYjFpMEoyNytDSU9ITjh4dTZOZjg3NDFRQmk4dzZMTE9GDQp2LytzYlFMV1czc29nMmY1ZzZDcEhpUlBTNFgyaFF4VEo5Z2JFL1RvakNYSUlsRUJ1c3U2VUcxNkNNc3kNCklOQTJVZXg0clR6WElCVkc3dEcrZHRTU0xzeVJMdmlVVWhNVUhrQnlsVTE2WnE0R0RFZUdHQkhzVzJXTg0KNDdpSFdoaTJlYUVSaXdIREFHTDkyQ1JCWE5mc0dtN3FkYkFrUmZFZTF6cGpOVDhTVVJkY1RDam9IQjhRDQpDWnFQeUxpeXRGWWZJVnl5SzZiWXVzYUtZN1FzZThEOXlXOTZINGdnOXVEdldKNVRnSit4dU0ycXNjTk0NCjZBU1ZyZlVQK3NaNjVvcHNZUkdiTXVsb21aZEliN04rSUplcGJQTEhUYTFhSzVhWkNUMk52c20xN0JUSA0KM1AyRGJ5Yk5CNFRWSVFBSmVzOUZkNnU3QlNBN3BJTGtLbksxU2ZzT096MkZDdFBHam0vTmhzMk5LQ0RLDQp3ZWJ1UmpONmxjU2RvRlpXNThVdUhuYlI3REkxNFkxSTR4eW9sL3pnajhoNVc0QkhUOFdtZHZJTHlqR08NCjFXaFlkNzdHOTZIVjZQVHNGc3dnN2kzblhTRzE1N1Q2Q3FwY0x4UE1kV0daOEtGaWRjU1grMUlQazRRNw0KTjRjMGRvaENjeXVyekZmWGhQZXVPSGZabE5nY1RSZWw4NWdjWnBiUkU0eW1MNjRoWHE1Smx5SWI0RDZaDQpVTjQwcVdBaGhUVFlQbTgzOWNPUDJwZGt5akhQT1NZR2t6UUY1R29lWkxPOUFwcHNETEgrMWJnWUF4NEkNCmUwODFhTUZZS3FnWmplY1hRV0tXVFpteFRrdndJTGtnU2FreDhIMmxab09xc3BVUTlNS040VjNTelB1cg0KTmw3Q0ZOSnZsV0ZsR0doNTdib2RrVitsa01WZU1BVlRwVHFqN0FOUW45KzdYMkJYT1JXMXhwQUFSRFRrDQphbEVXcmVnS2FaM3NxS2FIRzA2M0tNdnJ4Q0pLM1o2QVN4aitlVzV3ajVHQk9Jc2RXYlBzQm1DbTBBeS8NCk1jWU05SkJ4STBvNUxmdHdqaTZZY3hEeFhQV081OG9GOGRzbm9qTGFZTWRmaHRiQkxqMVpxVndyQmJmZw0KMzYvMm9mengrYmUvR3VocVhYSUkzMXp4UGFabXdPRGJqa1ZCRmYzQlpvR1ArQ09HQVBqNDZkd2lMZm5nDQpNQWpwTzFhZkZndHprbTZvQ25FZlhCQktGOW5WOTl3RTNRaUUxUjlMZG0wU1ZVSHoxYWhrTzM0RXJ2MHQNCkxkUHd3eGJwaXNncmxDN2NWQXk0eGZzTDFPZ3hNS0I0WUx6QzYwaVkvbGJyOWEzQk1sVDdHeU04OGdPUg0KRzdXdFRRbFNQUFIrN3JLZThlYlR5dnVXK1NmdnZPY0V5b3JpVjRpMHQzUERLd1Z1OFFPVjhUR0tUc0N4DQpnSXhCQUttd3hicFhZcDcrSHFLbmhkcURoVUZoQ0dUQ1ZTZFVLcCsvZEs5bjIzY2o0L2R1TUh5dlRLQlYNCmpySmU0QXNvU0d0M0lmMUdiV3BWTGx2ajU0R1czN2U2cXBsUHBubWJBZTlMTmczMm52c3pBSEg3WHhsSA0KVnlRMlZaMmM3aEpZSUlXeW8vb29uMCtxR1RSckcxbjduUlMzTktMUVIxdHZwbUNieHZTZm16N3IvRk55DQpTQXJJODZ1S0tNR3N0OFFDWk1rU2xMT0hhNzk3ZWFrWGpWbkh5bktOSy9uc0JjRG1TSGcySklGRGpwZXENCk56VVNyMmRrdDZ5TmNkRFlPNTBPeUtNZkpoQlBuRS8rbFZRbGxPeEkyQU52KzdReWRLWFJsZGpWRGg2dg0KL1BTcUJnTUwrZ25PZTZqcUMzNjg2SnkvVExaZnBKdk92Q1A0UnJkZkRLSU1HaUtveWJKKzUxU3NKcE5mDQpVODlyZzVaVU5icW53bTNLSVh6UGFjNEdYelNCelFRcDBMemVJandiSjVWK2FOd3Rtd0dQSTU3ZjFYekMNCm0rTmM5RmhnVnRldnN6Zm13aWZQS081SFRIM2U2WGhENUNkOVJHSXA5UDMxV3Y2bGtHVy9NMHMzSVRIbw0KVXovY2luOEJ3WXo1eDlYM2llLzNGdzJKY21ldFpURml4SUN3L1dMcVdidDBWdFF6K0xudlJXL3Rqd0c2DQpsZXNhOUhYb2tSQitZTnpMQzNCazRnZCt1R2JiczM5THpJT1hMZXpVRXdqV2VlYzNqdGlyQ2QrUFRxOWkNCmxyNDNSOXBPZmhNaElVc3JQOGNkNFIvTVhvQSt4cjlKeFB0SU5zTU9qVXRLZWJHNnBzTGJwOXhxRlc4bQ0KSWFwNnVRbFZva3J6YjB5YW4xUDFjVUVHc1VIOFBjakJHRjcvL1ZTU3hkVnJDMys5YzRzNitPL2pDNEl4DQpTVUdaSEVKTkNoUHhsYW1ZQ0hYNUYrTlNYN2ZGbFJsZ0p0MGJoOGRhcnh1ajBpVklodmxNZVVSYXVIL08NClFDMWFqTkl5N2dCR08zM216dzlXR3ZoNHh6MEIrRzY3S1FKNEsxakpseC8zY3l0TGxhSWNEREMybkxQQg0KZ3RDbDVDOEFBN1cwQnJ5R281djhqeUhhU3RyaTZSa3JzK3dRUDRON3VORE9UUGc4cE1EL3RXbmszN2c2DQpYZEFtUGpleUJFc1kvOEF5aHFZUTZEUEcrUHFUbEFobVBqQzlBQmRPRnRQNW1IUlk5QVJrZXNaWWw5eWQNCmJic1dsZ0k0MVd2d2FTMWY2TEovSlFSRUVmNU9CdmpJQ3Z0VXVtM3BocXVFRUhOQzR1VjlIdDBNYm9ZVQ0KNkhSYTlwTzlmL1docHFYb05rRTJVWU1HUnJDcG9WSSt6cGtpVUphOUZlSGp0Tit6T1pjNzlMb0hHRkMzDQp0WExOcHpMT0J6YzVYMm1vUWxSdW01U0hJZCt6cWxNOHNDUEp5V1lRTi9Pc1BDQ3RMb0orL3VnOTV0WGgNCjFkbGZoWFNjZ3dNczJsQzNiV3YxYSswTis1djBFbVQ5ZjhkVy9iZldoNDJpK3pDbVRmbUhJdENvMmRrbQ0KK0hxaGlwQldidUdpVGlQeDBHTnNvZFhJMUtvL1ZJWUlPWUZMajlnTnlPbFJqNEQwTjZ4bE16TUJnYVFvDQpEUWl0MVBXMm5uUUJRZGlHLzNtbnZ0UVVCWFpEVE4xdWpoY21DM1BNd1hTOHNDaG1odHc1Q2lSNzEzNncNCjZOS3Z0cVp3NkRKUm9zRlYyZFRlSGkvL0g5d0gwdDhXTVBlS0IvcmtBdmdhWVBkTkNPd3ZUZXk1TUY3OQ0KNStpdUFETlRmYVFIWDkrd3VSbWFwRlM5c1pCZkQ0WXA5TUpONEQ5SXJIaVlKV29Nd0ptbGM5SjJvV2JYDQp2Uy9XQzlXOXBDOWFtWCtlZW5ITlhweXBWR1craWs5ZW9sdGJkMmliOXRMbEQ1aUozV3BsR0ZNQklmYnUNClN5Y25tajFGWHd6ODhpam9scWZjQUZXck1WNnZGaUtTYVkxVzl1a2pxcFM3RTI4Ui9LeUNibnZCM0xnRQ0KYWY2OFFSMlNlSWFDM25lWG40S0hlZmhpSG1HSWpod1RlQ3JhblI5YXVpNk1sNVJSdS85RzdJZ3U5V2F2DQpSTVA4RUNlM0Q1cWpjU0FXeFdiSldNMk5SVTdBRFh6aUJTWTgrVW54aVRhS0krWXViQXpsNTloWXdCTVgNCmtTcUd6ZStvODhaeDFzNUNRa1p3ZDFxNnhWOTFmWTU5a2tkRlg0emlxYjRCR3huYWY5Y1orTThVTW1kYw0KQ0U2VE0xRTFYTVBjUWNIMnd2aTRlUG9oeVFFYS9oM1N5WFYzRlVXb3NxZWdQVzVIZmdhREdiN2JSZ1pPDQpnaFYwNWxZTVBtbWZLTndPdWI2VjZWSG5MQ3JoNlBlZDB6eFBsMGc5aWdYbTlKbkdqQXMwZDQ3NE1sSy8NCllUUHFESStEdllHNVMyYkluNzZ3Mi8zN3phU3lyUDdoVUo4eUNJMWNrQzhsTUQyUWVKczJXL3hYTUxRQQ0KTW9HQk8zRytKeTZQejB0WTVPd254YnlYUWppQTdmMiswVjZUU3dEVVFCdUxvVUpaL0FpZWY3SG9ETUNDDQo1Z25CSkJoQTRNV2JjZTgrdFhiVmhDMnNCM1RzSUwxVzRnZGxSQkRFRWJtRkIxdTVBR1B5emhwaG5ST2wNCnZhc1J4YjdLOGQ2OVMwWmRuQWFtVXdRWEZkZmI5azdQNkl6OUJNb0kzd2YxaGlXVk5jSmc3RGQvci96eA0KL2lDN1N5bEQ2K1kwZCtZeHdZQk1ZM2xIZ0kxVEpTSWQyRUZUUDhwWnZwWFdROWtrOGloay9PS2JFQTRpDQp6R3ZHcmdGdHZhOFJBWU1nQjFKZ1cyZ1NEbXJ5MldacSs4eWF3Rm1pZFd0Qy9oSElaQVpLSGVSRUx6MncNCkRwWjAvTWlOS0kxeFNZOXRkWkdFbVN5TmNiVmFObWZ2NmhsNW1RR3VvTERwcUlhSHZ1RCtJSFJwNWZ6eA0KYTZacG0zY3FINGZ2blBjc09RcGQ3Z1dqaC9IMnYrOVkyZzBaUkZlVm1HeXdzT0NFL0Q5MGZwSWMxaktODQpZK2ZPNUtzcnQxVC9RblBLUEJBaGxHbkFCS1pOYjlBdFNMZmZXQTVWRlNDYmlnK0UreVB4RUVWRFhENTgNClYyUUhrTlNCbklzTEgrc1NQVXE2ZFU4VFJ1NS9JeTJVck8wc0dNeVhhbDRCZmY0M216RUVCRG5aWU1FVA0KWFZVcU1ZUkJzc0tiL2VmSHkySnIxSGhTVksxM1Q0UkI0dmQ2d00wSElHMlZXMXdIL1Zpb1JkUjk1K1AwDQptcEdpeFdJWjBJOFZGRGNVbEY1d1pvd1kvOEdaRHZGSUVpOXl1cHVkcWkwbWlVY3AzRjBmL2RJN0R5RG8NCnQwbXFIVXpmN3RhQXowbS9qLzFkUHBtdmFnNUFSaTAzR0NVdkRsc0ZhNjBuNmtlUVhwTk1Iby9uNzYrVg0KakVzMjhreTArRXF0UTRTdzJUYll4MmhVcEdBemNUUncyaTNXS0RnUkpWbFlodjdLdC93czgzcFpRamp3DQpTaGtTakkrV1prdjBiRXZTYmZocEFhZWp2QklNL2FNdFMzS1BUQWljV2xON2plTUVRbW5YUXd3M25yZTYNCldFcEUrWEQ2bkZOMmtpRjUyQ0pod1ZvOEt5YVNkU2QvelR4RlBoQkRSc2E5ZFNsWlo4aHpUUkhxbVdkaQ0KTG5HYW9HYXpGMHVaSTBWUnkrdERXR3d3SmxOY0FwNVZxUENsV2FVTnY5QkdBY083R3pHdHZHb013RWd1DQo2UlpkRjZnMWpJT3Y0NTQ2RnBxN1RBdEN6LzA1YmV4QlNhZGs4SVJSMG0xQ20wRk55RHFtbHRjMkhZR3kNCk4wajhrNUJpbk1ZOEU3ZHNvT1I3ZVZ6VktOUjRZWS9ualRkMmdOazBlTWpPaDVxbEljaGlEOEdqUlMrUw0Kb2JnRjFndVpvd3U0anV0dnFoMWlSUjl6RHU0TU1QQjFXSXZ0cFRBZ1VSRCtvQVFxbE40ckNLUGptSmpsDQp5TURVclFFRERVMkx3dElEcHRaRlp5aTBKdk4vRnhaaVc4bkhFdnBRVVJBdGpJNm9EaGFpYlg4Qk5SU3oNCjNKVHNFSUdSTVRLTnMvaDlSbklnNjJzUm5wMXV5a3ZOTTRYRUIvMThDbFUzLzNrNStJcys4LzNNNS9TZQ0KL3JLZE9UZWFxTGliaHNtYmYzUUVRRkppL3c5dU1DaG9qME9CN25DUU5LdDA3R1dGQjVLUDd0WkJWTkpuDQpzem1Jbi90M2FkZ2lOQVp2SmVpZG1LRWVMaTBQQ29ieHFkMVJDcGtwem1hb25ONm1HdEgxYkkxOTI2ZHUNClVKYTlGRFV0UlYzYnk5blMwdWNoUEQxUlNISjNSbTloNzVvWmlMS0RpbXBRV3A0ZDJkU2pRcTlrWmFNOQ0KQWcxYk9zOHo3cnFrWmRDWjJYeGJtQ2xsZ3d3cEJIVEN0alBkZlZiK1U4dGlXdlhlQ3N4QTFGdkhlMlJPDQp3LzJYVzA2cHpRZEpwaEw4MVJqRHJ5b2dISzJPVE8rVXRRdnJXUG5YbzV3TzQvM3V2MElPVVFCOHNzQU4NCmlwb3k4OEF0VE4yc3lJSmVrZVUvc1JaSlhlUXlPQVJ4UHlTVDJ0QkwzcjUzZk1DNHRYTUJMbXhnSWEyKw0KakZsMG80YTE4ck5xT1I3TnI4ZGJFTzZkVHcxVm1VN0Y1M2Q0ZkEvRGRwcGJUR2pmRThSL1Rrd0d1cHVLDQpYWDgzdW1QaWthbkZBaElaWkFIcGdMUmk0WnNPZHNvdDhvcW1zeTFZNTdtN2N1WGJTWHJ3TmNxdkxXYmINCm9RNUdWcVorV2ZEb2lnVit1eG5GaEhGMndKZ2N5Zys5VFF3emdMcmVXVXI4bjRsRzZvVjlRVjF3STdRSA0Ka2FwQmoyMHAvYlEzTnFweFRERnVaaExyUGVESU9zQ2ppTExxZUQ1bzBKQUZoZjdLV3pPTDhTc3FVNXNPDQpIczhaZUhHam82U3A4NFZHSzZ6bzZ3TllwUjZYV2ova0FaT1B5a2Y2U3ZTcDNQbnBPc3dXcVlCRWVBZW0NClNSS2JPQUpRVjY2TllrQ3RDOUNhT0hYQ2YrOXoxVWl4ajRUOFFFODB2aG53TStIZi9EbmdRUWJwYkNJdw0KQ3FuK0RUdzFDWTl5RTNMekNQdWQrbmZxQ3hZaHdKY1J1MWx5OExMVXZiZWl1OU5ITkFvY1liRDZUa2pzDQpZbCtET3ozbi9mbkJGbkREOFlwZFM0NUNTWTZzb0ZCQW5hWndpWjdRR2Z4VXZIdHY1R3ZGU05admREaGcNClhvM3h6ckp1U1lLQk90eWE0MlRMdFZ1eVI2dG1rK3RuQXFRWldCcEZoUWtkQVZpNStHbDlJVGQvby9YNw0KMGo4ZDNFeFNMd2IvTFFuOVgvQkdBZktkSzJTell2MThhVk9rdDhCK0xYdHYwaUgrdHZoMUlEUTBETjdUDQpOL3NjeHZkQ0JBZ2FKUWJ4TGxDaDdWWEJLMWVUL214Vk9WcEhsN0RpcnpWeFgzblZUV3ZoZEthK1ZrcDYNCmtKVUFiRlpEb2FReVdmTzVBY3lRdHlqZGRudGNleHEwTmlIQzVySStyakpyYTZDZE9YTk1aTUJ5Rlozeg0KbjFNUEcyakp1eDNnL0tSamVOR3N3MnJLYVQyMThid1lTU2hJbUtFRm5vK2dJbGhoNWZMOXdabkdWemQwDQpxMWZJb3BhaUVsOEJRVG5aaG51TUFhTjFIR1BremxRTFRvVFVNVzZYYzV6ZTZaT1VRaS9ITUFqTUM1UEkNCkhUeTlpSmRTaktZdzRoc1VxeWNPRFFKclUwL3ZjL2VaeHVGdFRZYWVHUXFrdmNQT1ZJNEdtS3cxRUtEMQ0KNUt6Z2dFVzJNN29vYlg4ZytVZUw1NGlLQ0t6THhXaXJGR29NQTBGSlBiVjlrQzRmUkNkTnpIOGg2Z1NoDQpvNmN1dTN6dUtOU05HTDNOWEVMcHBHRlliSFErNFlEbWNQT0ttSjJRMmhvVy9XbzVPYVhhRXo4SG5HRHYNCjZSVC9la0ZuS0pRTEhmdjhqbE5HOFBXS29FRzB4bm1hazh2TU9ScU1JUEk4L29HWFRNZkUrdW5lRGdGWQ0KZlQxUGZSQlJWZVBuTnhwbnFZTm9ERmlVclJyWFlQRHdnOS9mQk4zQWRkdUNxOUJkeU1GQ0ZrdnYyUWtrDQpVbWNiajlKWDY3aHBFL0lKcmZ0YXpsQVkrTmoyS1NtODc4RWhtSU8xUFZ6QXZhWlg5TzB5K0p6WURLSXYNClZOS3ZzdUN3TXJ0WUMvWHRoRU1zTkF2VXhuTExLU0Z0WmdEeG1tMEJpOEJXUFhiV3hJMkt6SUw2ZER5cw0KeFcyT0lGai9mazdsdVZ0eXZKMDFwakN4TzlYblBYVVAxeVBHcHo4Mkl6dWJZTUZQOWJsVDFWS1BLK1lzDQp2QnRldW5ReTA0c2dTaDFCdllzUFBhbXhHd2w1V2NyTUhUM0wyZHNvd3ovdmFwR1Y0V0lmVnR1WFkvUTANCk5PTE9kMjJIMHJDTlJ0OTNETTVCTit0M1dYTjZtNUFhcnh0cmdlWGJxUmxZMExwTnU0K2llWC9rbWliTA0KNnI2YzRuQU5RVmFra1MxMXpCL20wSHI2ZGcxbE1DaE9yb3NCdDdLSWFMWXlMV0s4V3VRaWhBby9jMWtjDQpiZEt6OXNnK3gvam9Udnd3TkwxT1RLclRWVW96OXQyZENlR2hKL01HWnlBbDE1bXozbEFKK0srTkFISFoNCkg4T3MydkhWT21qdjhTMmoxSFk0ZzAraVVtS3dxMFZvREJNR1dmcDhJNXNzTS9jZUZCeTYxcUR1TVdBYw0KM1JWK1A1VTB4anhOOTJoTFFVaE15V3JYUVB1Nk5vSzJwU0ovQ0xlcjBadExlUEVtWE5PK2tncEh5WFFKDQpGd2M1VncyRGhSN2QvSXF5eGNNMlBSMHhjZ05YalFxc3loV2wydGxKcjFVdHEwZHB4Zms2RzlvdUdRVXgNClZYemNqQlRvVCtnSmhLRHcvdkhUbzRZQ3pvWSs2WVJoSFdWWHdvclRxVGNFNWx1WkJIUDNscjdoblp4ZA0KZkhKcmJEaFUwVW9BMVlZeTZIQ2NBdDFSUHYyNCsvNDBIV1RHMEFFbG1KZlFWbVQwdHJxY3h0eFoveG5nDQptck52bkNhT1YzbnZSdGlRU1h0K0h5T25yOU9xVTFVRmJ0SWU2VFcwZ2VCa3JnMXpDR0t6YlZpaFhucmINCnZLUTU4OWZDRCswRkNXUDVjc3FvWmFKZmZqYlgwR0FCcXRLSHB3L1VnNS9mS2tCUS9NV2pwdkE4MFpLeg0KdmVKdUROZmdrdklod09lUmRSbWRzZ1pYelJVU3B3NFFOVGN2cWhMUWsvU0pKNWl0UEhubGMrRnFvZitjDQpraEY3RTZQVGVYYmRNOE1VV1ZDalNhR0tnNkx5Ry83Q3ZjbFpEREVKMDRFLzJtUFVuOEU3UjJKdHRGYi8NCkNpaWNTVWh6VHl4TC9WY0hKYVcyUGh5eFhMYTFnKzdHZE16cUh0MG5vNk1iYTZEYU5PcDlFSmJPOTNFYQ0KS2l0TUN1NGNPRklVTklpaSthMFlNZ21LTHAyWEdGSjZXUjhaUGljWk5HY2c2SGNNa2hqTDVzbzdoRUYzDQpsUDYxR1h6T0RTVjVhM1hJRFZFOFpOYXMvbExtdWp1WFFKZEw3UHdaOVFJVDM3RFhnVTY1bk1EYm13dTMNCjMwU1pjT3ovSm16MVdqeHNiaTFnZ3MrYjM0R0xSK01LR2hRTm9qck1abDhQc01oQzMybVVjU0hiRlZVcQ0KYXhOUXVWWGFKZ3cvdjFMcjF3S0Jpc1VGS0IwNUplUWlwMjdQR1NMVXY3LzNHRGRXUENJT2hLbWh0L1JrDQpBbGF3OGZZcHpydTJRMDgvV25XUzZyUzBqcjhIQkNmdlNFK2xFWFlUdnVxSHl2T0xjTTJ3R1VSamhlUysNClJHdGlHM2lpZGttYWVJbEViSEp6cVZReFEzRlM3MUY3SGYyZFo2cW4yeDhoTWEyeVlCM0xIQzhlOHdRSA0KcTBURGh1UDRXQ0drL0REL1hNQldUdVBtUVpVQ29FcDQxNGZ5dEpXRkFIeUIxR2RmUlJoa2VaT1VCVHExDQp1by9XNVVqeHQ3V1Nwbjk5aUJld1BvTnVIUEsvUkhxY0JaV20xbTZsRXhxdjlWWnJNUVFYeXQ3TUhiWmMNCnVPZFJacnFRaUR0Vy9jZjRKd3VsSGxTdlZpTGNCU3NxdzV6QWUwY1Rrb09nTnVNeTVxaCtGNWUvNm5QTQ0KcDNYR051cnF5WnBDRGpOdVBudFdaSk5mdmhTb2NHZ3JObjJOVERHbEFicEtYRHB3WTREL3lVTFpSZi9iDQoyTDVNS3B5U3NOMVB6d2tUcHVURW1jZnBTZGR3THc5eFlqTSszck8rNUF4UHVBc0pJZXFCbnFkRDFJY3INCkpoa09iSHRLNkxPOStSNDFFanlHclloalRDa1AvdVlRRVRZRXAxb1JTVFYyaVJYUEFTTTJEWXlDM3NMMA0KQk9DYkdjWUl4OUZqSzl4WCs5UkE4SkpCVUgyRktQSmQxK1hGamZlbjE5NFUrTmJLUEtrencxdVR6ODluDQpLOXUrSXRpS21VNUdicEtTb0VmRURVWmFOb2lkUDUwMjAwZUFSY0RSRmRpeUNUUzVTSVlhWXRjYkE2YXMNCkdQRzFRamJzdVpYT2ZhUERkM0R4ZHRMZjNQZ2xaYStGaC9UUjlWWlJ5eFl6ekN0ZzhvTUlMYWc2MHNXcA0KYVR5OC9jc1Z3MzdhUXFWWHBMTU5qVmF1QnZHaU50dzR6THFjdGh1aW90VWJYWHVkakl6VEJpN1N1a29qDQo2UHhXZlh2N1NKNVhHRVUvQzB0aDJTUHpzMTBScDZKcEhiT0dRNmhBU0xxNTdONHVRenI5VWk5UkhsYWYNCmQwaE1lR0hUWVdNbHF3SUNuaHQzNkRPUnNXVk1wU0c4WWdoVDR3dkhrSGdpTkRscVVYc1VBTHd0Z1p1Yg0KTEErTjdkTWdKM2g3QU80YXlBWlZXZzV3cFljVjZIZTFNV0k3RnV3ZnJmVDFVbEdzbUhKd29KRjNPRFdqDQpBQmNuUnV0K3Y5RXEyOWtDbWpxRU0vTERvcG5hRW9VT3NPckx6cWQ4Nm1Cc0x6K1c2QWJ3aDRQSitDdkwNCldRYW5QSmxrWVhSaDJXL1ZKYU8zZHFqNGh4U1paMWxXaVdBbzU0OVZkOXljQ2RvV3h1MHVpdnJ6cnJORQ0KKzgrVXNHYWptY0JwQUhGUFk2R3AwcGQxWW55TWd6RFRLdktJS0g5Y0xhd05CVnJpZjRvZU1tcGdHQTV6DQp6eGRabG55ZUN2c0Y2dm1hemc5ZTVTMTNmeDJqdFVuYWQ2UnVOZTRwT2NtWjdIcUkwaXNNajIvaWhuSnMNClNjdU0rSkNwU2VUOXdPQnJIOEMzRzNTMk1PNTJLRzlOcXlmYTNzNXp1Q2dVT3pnQXRMVktOZElMdkZyYg0KV0lnK0tlMTB0SDU1N1A0UzdQZ1loOFFXN3JBRk5rbEFRcHdKay94MG9vN0pUQlNKSTQwVUQrS1M1MHBTDQpPdStRTE0rZDQ5NTBqVEVZNUpJbXNzU2kxbHBmZjJwMlI4K1VKWjdsT2pXR09xWUVqUE9Pb1Y5S0hPTkINCmI4VTRXS0hwMEpVL2FzUDdUOE5iQithSjA3QTFaajExS1R6S0ttWmorWHViS3lxd0UzVzdqNDNiZWQ4bA0KT3R2Q0VRbEhSdGNBUTVmWERjNTBUbk90MXZ6c29wNXR6WVVvN0hBMy82Q1NaMTlJcTNrMXVreWRsMEFwDQpIZitlcSsybzdlV0w5WG5Ec29saVZWTGxLaUlaeEFZc0JZVkpPa3Z1d1Z1Q0JPVm1HdkU2WU52RkxDVk4NCkh0YzZ2UzExdXcydTJBWUFQclFlSjFBRlltS0dsWFpuVVV0ZWc0cUpsRnB4SG9jNktCK0sxQ1ljeE9OTg0KTElObFk4Z0lxd3MyNUZsYTBRTGtDeHd2UHF4TXhwMDZ2WXFqYUtrc0FGdkdIbDI1a2UxeS9uRElDcVNuDQp3YmFrSGFKTzZ4aU9IanVUWXg3ZmdIcmlGWkdrb1ZVZEhFdXFxV1BQZ3Y1UW9Dd0hjOFIxWGZUTUZIbzINCnhJKytoaU4wRzFxeVNqaHJQTitSaTdTcjV2L0VBRVA4WDhWbndwY2MvNHA3TVQxamF0NmF4QWhYRDNEbA0KRjh4cVpKd0o3UXhHMmQvNFIyVVlxTlBhRDNnOWpjNTdrSnlmRnU4ZTlYZ0JhR3o2VE1LeTJoc0VsVndwDQpvTWx6RmFFRnlFaFVHaDV5TWQyRlhEazhIdWxEb1BscWRXQVJBNHZNMDEvejAyZDFCYXMwUUtFSWNkQUUNCmNzVGsrT2RFVGtmOU55c0FyMTNlTnZpdFlLOW9JanUzTFpvRy90Zno4NmMwMkhaZlprQVJNcjI5NFl0aw0KeVlOYTBQMFE5cFp0bjFWWnJwQWcvRWNDUnZqdmI1bkdRODcvQW0wMTQ5MjdDSjU3QUtJME1Ea3FFTTlIDQpZcXlDMDlLWjNYRWhIaXJwelRZU0xZcXZwNTZzNGg1SmJTeVR0aWlBS2xmQ2I5T0t1anIrUUxBTUhjdlQNCjMxY2VZUDdZeExQZnRnU1RtcURHRjc3U3pmdW95eEZ3SEFzbTBRQmpSQWk5eGdaNlpBcGtZQzFRbUhmMg0Ka0dKNUFUMExURVYrdThiYjNyS3lkcDNDY0RjKzAwcjhxd3pxekZUandRd2VSakF1QVovWkpLSzVhNVhCDQpwcy9HS2Uwd3Rlblo0dkozYklUU0dOQndkbmxjOURqNkI0QTA5bDRBZDRXYmwvSkdtMHA5ejNWSUxqSWwNCnV1ZTNqNXBRY085WXpOL2RaSFo2cFhxN3RYVmxvb3dlVjJGc3pXQnN5OExvZ21uWmVISGFkcjlkbmw1WQ0KWDBzbnhlOUMwR2lKemNLK3gybVhseUhSM0FQS1V0RStJWXNiRHhncTVaMy9ucmc2bFlnNzFaT25HWnZXDQp5RUV5VHRGK25mUVF6Ynl2ZkwvaWQwQkpvUDN0WXRRS25QTEprYU4vS2VwOUg1c2tKWkV1WHU5YkU2REUNCnRIanRNc3JTWUxRa2lTN1pmSWVTTFJxNktEbVhpVkVQVE85K2UrcmVVb0hGa2pCWThBWUVmamNBRExDLw0KRzhZanFkY2wxRjd0YnZGNlh5Y1BHd3BvSlRYa09sZ2xtbmo3RFhnVjBySXhBNlNyS0VER3RPaEtJMUpRDQpwaUxNQkQ1aWFac0RHNSs5Ti9HMHZzaU5MNTNxOTNSSDdKUzBDa2lDb3J0cktoMnFRTE5rekRwTVo1M2gNCkVFcVJGY2VsWFFkbUJaQURPMm9nQXA4czdJWWFQTmZnMlhWbHRreXZVRVZEYW5hMy9GVGJtTDQxNW5ibA0Kd0pwZXp0LzA0SVJ3NnA4RTJEbUhqMUZPWVl0UjlJdFRpcmM4c0pNZXNXK3JUMG85SzNySnhyUkVubUtqDQpXS2tMVEV4aDZPOVp3OHFiNDZFeXA0WkUwVmwzR0NQT21ZZmRJNEJZNnV1QTRlR1hWVi95QlR1SWtYS0oNCkluN2xic0Y5c3I3U1V4U0NVOE5MbVQzcjlZUUk5eW9WOGgycmRwc2JlOStGMFo1SEFGcjVBb2tuZjBDcg0KMzFEZEg5QU56ckdNR1NKU0VFWi91Tk51dXBya1Z1WEtkOWNYUEFHN1pQcG9WWVpXaGs1M2t3ZzRWKzV3DQp5bXorV24wVVlnZXZEVXRxb1FIcUpyNkpBVDl3RzNLUmxFMndVRm9sTnVMelh0ZkhZSlB0d0lidDB0TkUNCndCQlFMblZkL1Bya3poM045c1BOOUZsM0JQb21qclB5ZlJGdE5va3g2ckFUaFJ4UXdTU3o3MUlMcWF4YQ0KU1F4eUxZNkFYT0RCL2RiZ1MraXlrMFN4V2hma0tQM1pXRzFHdVAyWjY1RnV0OFUwQVcwb1ZOeUE4cGZsDQpla3djMHl6OTA3ZmhXdTRwN2w4MzFXU2daMWhXTUxrMDZsTXdyakJLN0lzbFVNbXk3d2tVOElBZ2dPWkcNCnZwM3Y4c3hKdlloaW5rKzhsMTVWbkNCcDhXcHl0cjJlbkNZeitNTFN3bUgxaW9ILzBpd3BIbEMrQmY2ZA0KeGxVNzdtKzFOaEYvRFFKSUhuU0FYcnJXbFZHZzZuSlNKNlFwU3lFOUNOajRvbFdqY05WVTc5SnZKSUZ3DQpSRWpqMlN1L3pIV2tBZERLNThkcDFwVG1xcS9ydkZDR0FjbFpXMHNxYW1Da3diSFFkOXA2LzlZbEJQMk4NCklkNXFyUysyZU5MREtuMHBrcW5zQWYrWHN1R3d0S0lHQXl2dTdFeldpNFIvSG13OEZlVTVFTHVoRFBDMQ0KT0VJazR0UzRYcHZPTndUMDZXaWRPWVNTdE9qT1RMUE1vZXd2cGxwcHBESmJWYWp6MXZMVHhMeDhqRlRtDQpSVThhNXVNNHBXTlZOMTg3SmR1VUJXS2tJdUZsbGRad3BRc291enZsWDBYNzFTUy9teEV5cDRLSVc4M2ENClgvcURhdmRPT0NzdlNZcC9pMXNSelpYd2lrcEVKc0RnNHNEckxrZTMvTDk2TzhkNlN6SzRuQ2tnWWwrYw0KUkFZUmlScHRXamJLQzdMK2JEbXp6Q2RtL0FEOXplUXR5YmpybU9uTUVFYUpGMkNUOEJ6U1FMeVRKdGJXDQp6bWJqakxWUUkzaUdMRWxzNUJKV3huWi9Eazc5M3JBSldZZUcxUEI2cEFOLzY4UC94LzFReVZOcnovRXYNCjd6VnQrUEpLd0YzZkU4ZXJObVdKRURlc3c2dVZaQVk3Zk1aR1BCL0gyVE5saWxneTFEdkIrSVNIS1lDRg0KdlIxUEJKNDRBVGRrdkFuOVFSR0ZSemVROVkxY3FRckJXdkkvazdaNzRrM3ZWdTU2TGY2N0JrdlVyS3NNDQpmKzUxUnVYL3BmVWUvM1RMV0d6aGkzUDZRRGd5a0lYOGx5eGhxYksrSFZGR1h3a2U5bTBiWVI4UzhGekcNCitjZ2duSWF2bEF4L0tnVXV6YVpISmJrSEUvKy82YjVmc0VFaUN0dXVPenpmZ2piakswME1UdEZxeGhFRA0KcEJZZVE4WFVYVnVoUHlBQURJdXVwd1BYaWhOcEdwZlQ5Y3Z3N1NSRjZFbTI5OFBDVXJkR0lTYmRDVnU4DQpOL1pGS3UwQVJFNS9uY1ZkM1AxZVIyR2prZ3JiSGNaN2w5SFhvNGpWMU1vbFByekR0WDdCSlFKN3hrd00NCnNhSjhCS3IrYmcxejhXVzRacW4rTm5JWFIxN1h0bVQ4ZU44Wk1mM21idWlIa1NDUkl1WDVUU1FZdWlhMw0KSTVMaklGWFZIY1dkNWxnNHcrR093aTFPN3JwZCt4Z3lPSHI3WVM4Skl1b25BWWowOE93QW9yZTgyN0lpDQpYeFUvMk4yTEVIY1ZiQ0hJazV0RXZ2eFB0WFFoUkh5WFFodXB6L1RvZ05qUUpuUU5uajhsUkFKVkJHQ0UNCi9XT2xwMzVKTytDeU95WEFBeU5NUlVsT3VOdkkwc0VRRys1Q0pZVDNYSnQwSmUvcDJoVi9sd2w0TkZURQ0KMWwrUnNCbDNZNmhDT3hMLzdaWXlmaDJNUVRPTW9mQWEzNWdwWVAzREc3bGYzemVvV0xzWFhKSDRLM284DQpKaTJpZCtoU2tTT1NzYS9UZnBKTTJ0M0JsakZnSWgyQS84QzNrdzZVMVBLdmhVRWVFMzF1bXhaT0tFZXkNCnFQaTVSTTNLWk1GaHdOZkhCRUJRU2Rqa09aZXVRVGxsclBYaHd2Q1dsWlNIdUNiMmQxTGdVUWtaT0JLUw0KalExNnk0dEF6a2ZKd3ZFcEZjRG9SSkhvbDkyc2VkZjlJaUVKSS81WG15OEZIQUt3L3R5K0RXYkdrcGwyDQpxZ3hCdjRJN1pjd2xXalAxTTJFVVM3NEF0d2YrNzd0bHpEcjh3VnNjTWR3eE9JZnRrcmlMZ0k3RkR3K2kNCm9nWnJycDdodm4vSGZRVUR4eTBwL25MbmxLRXpMMEhlMnlNRWVhaTVLRGljMStDNTlXYklFK3pWUVE5ag0KNlJwdFNDenhvSGJhMkV5cHd6WjA3MUhBak9icVdGeTdydzFMcVB2azRWTC82ZUdNQWpETnJqNmpTSUhYDQo2MVVwNkgrR3JqT09KaGxEZXdBN3IydjhINHRSR2J5Vi96c3p2Z0hXM3pONGlQMkZBNUhpQ1gyeHlzY3ANCnhrck8yd1JaQkVxQ2M0dmozV05zNk5tSzB3QmV5c3MyOFJZczZXaEVWd21pa2Zlc3NWVmh6N1hqYTJLSg0KazlYMDNxUFg2WUk3THpaSnRscGFPZVFPNUI0T0Z2NHdLMmd6WnRVMkg5elNMbndjekpRMjJMdG1EQTJJDQpkU0tSNjBCOEZkUTlPM01iS1YzNXJoa2Fwb1hScUY3TEVJQ1FnczZCS3dRdlJxQTJkN2NjRDdKcCtTU3ANClljR1F2dktaQ2tTRDhBdkJZcm8vTnkwUGlPMUxNckhWZzBJb3FLRTNLbDBZSXdmNGxkWFUrWkVLV2lSQw0KZzJNclU4cFQyV3piMnJRZ1N4RGRvQkxUY243WFVpK0JZVyswRGhVaXFqTzFYQUMycjY1U2Z0Nm1QQUlsDQo5YS90Qmk0cS8weGl6ejFnci9CK0lWNWd4S1JXb003YUZtbDhWaWF0eFRtY0FMOUQ0NzVKcDY4aFFqM1MNCityd3UzY2tFakVnQnh0MjlOZURiWDZMZW9wUGMwRnN4TjlCdXhpT3pONmV6S2F4eWduWlhwbzFjZTd0eA0KaGxFSVFMWkVvb1VSQVNBZE5BK0QzbnRUaVZGZTNJaFlKeThIN3IwVnExSVl3OVRVbUVqTndBTXlyRzRSDQppeE1STUNReDMrZ1NJa3I0MlRnLzFiSHpHYWh2NmQyQkVNay94UHE0QmVJaVRMOTNxVm5NUFgyd1BOZXkNCnV6NThQYitBbFNhR0hBcG5FTEMyazhiRHRJZkRwc1I0ZE5OUHlydXpxcTVsSVdhdlI2MlB2Vmt1aTVNZA0KUmtseXBuWS9pY2xRZitGeE5CMk1OWVdpSldUZkIxYUkzYzRFQnFmc1dQSE9YQ0oyUTlZalFKMTBRVERHDQpiSVlnYmJhVHI4Uk0vNytGMkEvV29oRWRzWWY3OEVLR0RBUURhaG56c0FoTFZpWVptQ1RCYmtkZDM1ZXYNCkRZWXNaUndJT1RtbWhVRk5CUzcyckpUTGpGN2NhUHcvSFF3M2RBczdyM0gvZ0dLbHA1K1Fkc2NUTC9XTA0KYkYyK2RpQW5seGVaZ21yeVQ1eXd0YmY1OVlobXVVaDF1UStXMXhBeTBHOG5jR0xXTWJCdkg4QWNTMXE1DQpyUHhDZ0VVN1poU3luaUFQNXNPN0dkeS9ybk56WUlwdW9aRlNyTXJZUGhQeWRlSno3UVlwaDVwcjVReXQNCjZlN1ZLcGVoUE95QlhKOUVwcEJZeWx0VjNHZVp3b1Z1SzF4VDJGZ0dRYzNlV09UK1ByalBzdFJhWFpENA0KMlQra3EzdWFub2xSRTZ0M1lGSytqVWtpR1lubnJMU09XWE04MElKKzJFdHJTZGE0a3JzbVRLUStNQlA3DQpQRE9nZnBUUHBGSmFwTldZYUlJa3hKb0NxYnFYSkhBbFhSTUNwUVQvVHVrM1dIOWhTa2dGTFVQSWRZVnMNCkxXSWRHbFJFNHRHZG10ZVVSS2tWa1RKZTZIWjlKdmYrdkVWRnJGMkEwakMrcUN2dGVhWWFqSk5tM1hJOA0KLzJqQVBROXExalpVc0NkZWhKbEpEYmNteiszcEhNU3Z4eTJ4dlpISGRTM25GN2YwMzg3bUl0SDZSQXB4DQpEY2plMTY3RjZkcmo4UDhNL2F3L1RPWVlUbVVIeEN0bFpRSkRiS1hLSkZiRHZUbUtiVTBCVExSTENHOFoNCkYyQytpM1cyUWpLaU90bWFJenJjU3libGV5cy92UnpIeXYvZFQ1bmVVQWNaYWYwdFVsbndoUmdWcUZBeg0KaCtmMWNrOWtocURXU3l0dmxKNGwrcEpQY3FPblE4T0FHbVU4WEJzbVlwSFUvL3pDblYxKzFKK1JxRHBaDQp6cDNWU25DREZneldBa3I5WXdjdy92YlVueVBLWTdGRHdhRDdMWnJ2ZmVrWDlnbFZ3TmdwZDgwdmdmd2wNCk1uUFFRRFRsdHNOTHNFbHIrZFZVS0hWQ1VXQVRtQVJXTWYvN1daVlUvNjJHb29lT2JTb3lrN0pqQ3BjNQ0KM0xyT3BLS3VSSTVzK2NVYWpUZnBTZUpqQ1dxUkhISTE3UGdHSXlvam9GZUR4VzJDV1NLNnd0K2RIQkQ2DQp0SFFvbjZLZlpKOEJnajBlMHZlb253UzdJamhWZW9vdUpyVi92QTBtYU9Fa1BCTjNtQUpBdEhPdjNiUU8NClJXb0IyN0lDYWRucFJWTzVaUVllZWd0NXpvTzhkYTlVTVVGN3BzcHN6c3h5TCtTdXFpcVFCMHBybTNIdQ0KM2FvN1FLelJkUWFWZUc3b2pxc0xnUkduUmVNcklwUjFBUUpYVi9nUmhKdHJKMnpYWUQyeHpzVjN5SENSDQpObUZaLy9samV0TVR3eWRJN25ucGZtYXFDWE1ZZ3JkNjRmZ2ZQK0FTTmV3S3J2UFUraWduQmZmOE0zTFQNCm9TeFM2cHVVNFpVSHVCV0hDQXoxM0Z4RHR2VEd0N0FXYjhtR0dsNU9JM0hlNDJOVXEzS2xzbjRSZ0RKOQ0KL09DZ08zMnd1anFLQUxCYU4rWnpjU2VxL3hCWm55d2VFWWxhRTlMeGJlNkxGVU5OR1lzSVcyTkJyU3VlDQpldW5sbEE1TUQ1Z2xNbXo3eEVCaXNuUTVLYzZhK3NkNHNaM0N4aWh2K21BM0t3UXZFZ1MzSzYzZHlOelUNCjlWbVJybmkzWWZKSTZqbHM0TUNIeC96cnlWTmMyWldrUm52a2ViajJ2YVpOaHBqR3JiQU02ZWxxWHRPRg0KZ254eXRiUHdBYkRrZ1RWK3R5Z1gyZTI1YzRwREprVnpVaGJzbFM5TEd3blh3VEVOVm84MUtRRDNGTUpqDQpGMTRoU1ZRWG1BUS92dzQvMzRzL3AzN0VPZ0ZBejVqS0gyL1VXbjVYUDRPNDRjRllieHVrZXVKdmxhd0YNCk1HWFNQb1JvTW1KeG1sWFRvdndnV1hqVVdCbUZZMDBaa2tqOXBlaEpGdFBkSFBsNEFkQUl6Z2Y1b1R2Tg0KMVB5RmRKckpQMm1KUDZMZDlIWU9qSlhjTVp0NS9nb0JMbzlYZ2JRMDcreTBzWnBzTXVWOUw3MWFlbXZEDQovcW1NM2pIREVsanRBa0tHQkVpNXl1cXZrZUdIQTByRkRvVXBJeVRZM1EzbXJKUjVENUIxem9kalJjNDUNCmI3YmRZaGd6UEZTQkQ2Um1jbStxWmxOSUtWdVFNT0xjRHkwdUNTVDV5eks0SFVHaXlmVTk0eEpPWHVjSg0KY1ZIYXBvTkM0c04vLzkydFhQdHNiOTVVdFdGaVdNNG9oWDJnNzVNanpubDg0dkN0bTh1UU9KU3NOVXRPDQpXTnFZNHJJdmNHNTVsREdDakRyWjlvTTBMY2hISmRmNEVIY1ZPWjVkUDJwOS9xWC91cTN2L1pJVFZjdjQNCkZxMzFtNE9hVm1nVDM2NUhuTG9lQ1F4NjlCVTAwMjJWdkEyL21GZFFDVWJtVm01TlMyWWZLZXdqaFh5NA0KbEhrNzNJMms4YUZpaWwrUEpLemZFRzUyV3JXWldoTjh4dUhmbTZQUEdFVUZ0VlVUSVVnd1MvdlM3UThUDQpwMHQ4STd1VHRTUCtkY0hSdWVtdUtqOTlLQkxHbnZmSWtYek1ndjdqWlpuZE15T2REeDlrQjV5KzhaZkENClRlVGhLbVdiNGo4UUdFbVdpUXo1eGlUMzdic293NUdBYWgyZ3FoSzJoaC93czhUNWdyVU9rKzkxREJ0Vg0KcWdmbTM2WFRic0VvSVZTbGZIK25ERDhiTTFsRFdhZjBzWUZNU2t4OENnRUd1N0tMdTFlK0xFL3dkQ3BHDQprM0YxN2VPbGJ2cTBnT3BlblhrNkhGazlzeFN3N05IZ3NFZlAveEt2alFRN2F0aVp1OXRzRGFwS2pvQXkNCkxrTm1vY3pZQS9yQ05OVjBmc3RPTFhJVUZBbnV4TmdDS2thamowWk9ET0dzUzhOV0xJY3AzY0IwNXpJNw0KZmFXWFdjaDNhOTY3TVJvVUI3cFQzUVpOclNldE5ad1V6NW04S09YSWdmYTU2cUFhNzIzSEVBTkU0VVJEDQp3UmtuaExYT2tHOUZuNnJ2ZGNIYU9JODlhdHVPa2V3N0hHNnJYWGhuUS82TmVaMm5scHhlSEVBMEpHVlENCmpXS1ZTRjljOGF5eXEwbGsyVktlOHc2YXg1a21NMGZqczROS0V6Uy8yTmlRSHdHOHZGMkUvd2pNd0UrLw0KQ0hGNVJkZGtpbWdYc2pPVE5ZMkhDWWJWQkZGcEhDNjRxOEZtZ0lxUk1RaWY2bW9SY0F2MDcwUnNCdVpPDQpWcSsxczcvbGdPWmJrMm9GRTczcVUzQzJTZ0RTZXk5WDd5VnBDV3RoRGMrRXRDd0c2T2RkdnpzR3NqckoNClpocUU4MStnZ0RIUnRJVHNLRStIcTliU0lPTkdhRFpJaU9YR3dPWERaTW41OXZrTDloWUFTc29QOC81cQ0KZXVMRXJEcW10Ny91ZldLTzVyRVRvTy9ya1FybUVxUHd4TW85QzBHbXlMbHNDRC8rMURlcGFzOHZGOE01DQp4SmhTZWlJMWlVc0ZiUStjNVpmKzN1WUtQN2x2dzNZeEJoUEx0ZTh0cDg5aisxRVhkSWJ6TXIzOFFzWUwNCm56U1NSZk9KRWFsOXFIYzdORG1TMzYzZUx1U1hLY21KY0J6KytQQXVNU2dwWHBvZUtGaXl5T2hjVnRpTQ0KUjFWckJ1UVV6U2E4Q3ZvZjVtazZDS1RLeWx0WE5MWXZ1WDFCZlRmYVRYcjkwZ2lYdG5oVVZUZGtEeGtIDQpxVFgzaG1Ka3JiVitKMzNsSUtsWUhPSDUvaGczWE9oNnZFaTZSY3BvQXRyU29iZnlYWGV1M3VONnUxQnINCmMyVHRwWEJVcDZycFVHNmV5UXJaSmUrVXZ2UmRiWkpUeDdNTGtnWVpWSUpCWVlCdWdGL0xzc0MwZGFiKw0KZC91WVBhUkpLV05XUVdNZDZIMGQzQmxtRGhUb0FKRlA5WFowMGFlTjIza3pMZzQ3ck9XWmllSzZBWEtQDQpwNTBBQjdMQnAzckRQZ1dTa0xRVTUrMS9GMjBOeDJWa0RYTXpsRlZiYStwQlZQbWs0aFFoR3RDUzM5Nm0NCmk2dkZzUnQ3dGFOa1BwV3hoSTN0S0xjRG4vVjVuUWU2OEp6TnNSc2hSQW9OeGRKbmFrYTlQSXhyRy9sTg0KNnQ0cnBYRHVsQkZrc2pMOEJoOWE4ZlB2NjFBM1hNT0VZZTFqbDlxNVNsRW9pRFpNTlBPelQ5aFJ2VnJHDQorMnp1aDNGQXdrOGJZVmdySFl6RnNaMVR1NUZINld2U0Noa0UydnpEc1BDNFBMZXJMdUNvZm84VjJ1QlQNCldKYmJuUFcxa1k1NjErZGFWZXBCc0JaMDNIWjZRakVkYytDRk05U1I4eXJXS3gwK3pCaXJDeTVLVjQxOQ0KSUdqNDRHc0dRZk1OdktrNzVBN1VaZnNVb1ZxeTdpK0ROOG9IM2N3dmVzZjBHTFJhek5WdEtlSkdIZjhyDQpOQXZWclk5NVRSazhMLzN2c1RQdVc0dGJBU1hrNTlCdXZLYU9JTHdoK3BKby9Oc3dGMkNkV203L3U0eUQNClpWVk5vNElzd0x5TTNJMUpwbU83UWZTU290eTR1RzMvNmpmU3g3UnJ0bWFQVWJUZ2NqQnBPSytCQ0lPaA0KUm5XY01BeStzZnhBajRMdzltTzkyM2tteHBPUkF2SGRxaHFWcC8xSDBXMHBEVVc5UU5abitDNDE1SGxODQp4VXlMWm9FQXJubmRJaXFFUm9NT1pxemZ5TzZodXcrazJHU3lOMzBZN1d2d3NyOWNyZEF0ZjFHL20yeWYNCkR4ek5qelAwTlUxYVpyWFFkRThRM1RKS0g2bWlVUlpYQ1N3T1VRbll3YU9pNjdFYnFlRTFienhNejhVQg0KNk9EL1BKeFRxQi84OHhVc3ZNV3FqQnJVQTFaU20vZldMb1R4S0U0UFRqN0hnSldmRURRVFdlbjBuTVRCDQpkQ3hHSXlGWTU1bTQ4TEtZTW56cmJGdHNGZXllbFRzREM1YjIxaU8wSUhTS1BZUDFxUDBvTGRXeFcrUVYNCkxuTjBVZGVwTWlteUk2czdnNEJ5U2tJUTlpRlo1QUQ3NElIcGV6ZXdzdTdmS3lqMm5NajhNb2dFMDR5aA0KbWI5aHp6T3puM2pKaFpDbGlFcDkwNjJtK0lHN0JWa29mM1FnazdtcmtSYWcrNEdhendIcGZDOXlTaFpLDQpPTmdMbDBSQXlPWWM2dFcyUlpvUEVxc3VMN1Q5UUR4Z01uaUhvN2x2MzhYeVJLRXZyTW93K0gxVnBDOGcNCmtzVmFTNFUzeFB4Vk9RQlp5QTJTSytzdFZ4dVdyNndaaG9EeW1FN1hSeGRDbjJMaU5pZkt2WTB4OHZndA0KNXpxVkoyQkMwMnhydjFYVnZzNXFTb3FYOEROVC9CdEIxa2xuTmdGOWpsTzY0OTRtYUR1ZFFuM0w3QUJtDQpiVWtMOURVbVh3ZDNZancxUlVOV0dwZFlXalgwMHZKL0NLU1UxWi90R1hCUjkvVnZhNlZ6cVB6RWE5NWMNCkI5YW5HL1hVd0wzWDJ3OENRT3c1eWpydGp1ZjIvenJHV1ozempjMUFmUG0wTk1OZStnbDVISUNnZDJJeQ0KQVJBTlAvQk9qekJONUN6MldhVDBuNnlIQXFWMUdmaVVzRWtpSXE2dXVQMGw4YUNnWFl6cGJweld0MEUwDQpISU85WjFmajRyemhzczJLYUx6dFREc1pKWGtrYnBZb3F5dlFwQzV6Q0xXWUNhbGpnaGJkbHdwNFZkTloNCit3cCtmN2pRUE01NG1LUWNaQkVXbU1OMVRENC9XdUFyNWVYNDVTWW5NVE15QjJCTnZ6UjVYNTg0a05wNA0KRXhtbFFVQjlHam42aVEzd00wMG9hTjJvTFNWSVppZ1lzQ25VUGNyNkVpc29qbkNZekJQSU9EUWZ6c0tvDQpIWTlJUnVFcEVlcVovU0UxWVRFa3JNQ0wxeGxIWWZHQ2cvNHIwaTdIblpqTXBpSExXcmVmSTVUdXJZMEoNCjJGVlAzbERjeHo0NVJkdTRKaHpxVVkxcjZSVW15NWp2ejJDaTYxTC9CUCszRVNqQVNTbWkxL0dUeEtudQ0KK2xwVVU4TEt0dWJSaUp1Q21DZ21hSURUN1NEZGtUTWFNMXZPd3hJRlFzMjJmQjlOTWUzQ0VsTnBpbzR4DQovQjVNSU45NFhTNFk1SmNvQXdTdFpLTzZrS0ZFbVg5QTFyb1hQY0Fqb2Y2S3V1SHVnTUpPd2twditjNmMNCkVkR2NjY2NmdjBlK0NXcVM0Yk1YM09hekI5Z2R0OHQyeTVsT0JMR1RSSDllQ1NzTmZpeC9Cek5jekMrcQ0KUi9VODA2WjNDcnZNZHJyQW9ualpLUm82L3FvRzRDcG1ESlZYSVNkYWViQzFRL1k0VVAyL1NRQzNUZTIxDQpGNkQ4UHc0bGxYV21SRXFhd0lOampSaE83bkdzMEptVnpCWnVuekxkbXhBdXBKQUpZcWI3TWRVSFRYdDcNCkozd3lKRWpNMjFOWmlPdkVQVzh1dWFUWTJvbXRrbXVSTlVOUDQyM0hjeXhpd0hTRjJQb21jVVpkdGhQdA0KZm1iaktFc1pNbm5NYWZscUZTV1Z1TUJxYmRDMndwbm5MVUg4ZkhhVldSOEZoSHN6cGNRRHQwUEdScGlUDQpKSmpCck1YbzdiWGltVTdSWUNUUVNiSmQ3VUpUVW4vYTdTNTZMTWplWHVBY2NNMmZYZVYrY241bW5KcHENCm9tUXEwa25LQ2M4UkVYcloyTVlreDM0Zy9PM2FqVitUb0JFdHcxR0NNcm1xNTJmY05OYTZHT2Y0ZlRTUQ0KSEVkdVAxQUF0b3VqaTRnQ1VObSsrbC93dzI4T3pUZWY5djhTQmtmMXpCSFErMExVWnpQdU1maW5lTWFJDQpBaHFKTWR3NkRNSEIxTlgzU09GUm1qbUtmUFVYazN6RHB1aXZzYi9PdFlmZ2s3WXIyNTIyQ3RFeVJPNUsNCnJUNWZhRTJSc0JoeVJTRFNsVlBwQ2ZQbmtGRnYyNHVqMDkxKzdHUHZsM082OWpqRUo1dTVJTE91VDRXUQ0KQ0Q2c2ppV1BPamNkdHBxWWdHWi8wVlZrVks2a0FwOHJTc0lYNDk2RDdVSHdMQUdkUW5zbU5oNm8ra29BDQpteVNRZWlhWGx2eERkUHZONldHRnR3czVtdGlEMWhUMGMxaU5CenBYUHdCMklOb3RJY25WLzE2U2c2VE8NCnhUMkYvVWduVzE0OUcxa0lxcjNRMEdxdWtGaUEvWnllbCs2SjVHeVpra2RaSXNVQmJmVkw0VjZ6cHdPeg0KMDRTOS9KNkFwRVZ4dWdhR1JTR2luK1pEQ3hYUmhtWm5iNU1hV0h5ZWczSXdlWTlQVGNXQis4cGVUTkhLDQp3ZzcxbEQzYmg2VzZUbmVScmVtMUQvWkxRd0tyaGwyeTAxTVFZenZ4T1JqdW51RkNUZWdVY05USnZnYjUNCmlaYWxLT0Z6WWFTMWRRYjd2U1l3RGxJZTRHNnRvZncyWlZVZUllaEFDZFJ1RmNPMkZkb3gyeTBNZVNRdQ0KOEdQSVFSNWtqeGxrWFJhWVNGVEgrYlV4Qm1Id1o0d0lHVnZDQWZvSmY4UzFGKy94OEdOYS9ZUEppaUQ5DQo2NWY1MFRpcTdhMUVsekhFbGZQYmJrZHNGYWJDMlFKQTloc1h4amNhUzA4RmVkRWl4bWp1UkdrZEU4Z3UNCitSNCtDNmMxbng5bU5kZHNxMnhaWHNDQ1lWeUkxZ0w5RExMcUFFaUNRVHBEbWtaYUI0S2RpOGRMT2cyYQ0KVVhkTnJwV1RubStZMjROUG9nSGw3QnkrdlRCcXhBUWZpT0FWRk1TZU5YKzZ3alRHalBmallLTzlpTGhNDQpGcENodjdsTFhudXJrbDlBVWdzTThJTHJBME5lZ2V4ZlkxRFhBYVJkRkl6cE5TTEtWT3A5QjVMdmkvaUsNCmJSOGdZUkcyampTZ2lnZWJYeVU2RnhSamxTVmozekxHUVg3bHM5Rm1DM1VLMUZRdVBDSlJaTW0yVUY3dA0KVkN3bG82WFZKY2xxZTBzWkVxY0tHQVBiczhsckxDSzQ5RC9HRDlRMzFDQmJCSGxXdDdudk9mSStrdmJSDQpaVTBPdUpEWHdMcWlHbXc5S1ZRZXc2SW1RM1pmTWdxcC9BMm9OeVozUzYyc2I0cWFISjZFV1paaDl1TXoNCmlIWFZrdzd4dVRyMXZGN1dnRUdHakZ6TDROc3ZqbW1FTmdkck5VS3RHL1hLdzR1OWlnMW1kSGxBWnFpbw0KZkhiMkJWZisxZ0tiSmpPUENWcFJOVTFQMDdTbGJoYnFpRjhsVzNVYXA0dFJDZFYvOG81R1VuUC9zWjVsDQphNE1ZdDlLY2NNanFEbElGZUIzdE9sbFAyclkzNFdRUHhrTjFWVFVnd2JhVnhXd1g3Q08wMk1vZHltWnINCjlkYzBsV3FQM2ZtdEJ0U0JmSzdEZEZmYUNIMHlMek1SbE9HbWkxbmxHQzVsMWE5MXUrTDkzcmp5N1ZKcQ0KN3E5U1dhUFRUajBjNWlYOEpSbGFjWHZaZWZjOVVJT0p1UkxGZDNZZzNsWmdCTWxvYzhtQzNacXFPd2piDQppek1JdmxNSll6c0MydS92RWZWNVBUWDIzN0pZcGJpMHFhUUhGTkUvb3JUd2dWT21BeldIMjlEMmREVXYNClVHakRjdGFyN0VyNERxZGh4UDdlYTlmZFlhcnAyWXlCSG1ERUVRMDRRYzYrNE85QU5rc05lc1hWekk2dA0KWlBwME5rK0NiVmEyUDNWYXRGS1VORE5aTm1pNXhvNXJKRDJPYkRoY2lNTGZlSDFXRk1xN2JkY1NCNjF1DQo2Y2U0cDZMSGNTbUpWWTV1NDZ3OEZjOWVmRHZRQkVzQlRYaGJ4d1IyRE8rbWh3QlhhVitRa3M4OWdxWUYNCjVWcnZ1dW9seERRZGJodlRXN3hVanZncGZ2MGN6dStqT3J0TS9HMVZpSlV0WEN2a0ZwVDFkVUJGSUJjZA0KaXdqbWFiZTNsTzgrekg5SHpGVXhwc0U0VG1tSWhFeDRHSGI0YlFCL3BjSVJaMHJmNUV3YkNHRWo4dS9BDQpXTGlrYUdjYTdCR1VWTHgrdmsxcFhxU3lDK3pqQmNUR3dNdmZrY1p4N2J1dGg5cjRxaGxLMnlDZkh4d2UNCllaR3ZmcjJWayt3a3EwR0tBcFh1VGdDZHZabjZ3QmdoOUJkb3ljMUMzbGVGYnd6d1dUdXNWVlAxak1XZw0KOHh5ZXp4bVAxbXpBQWt6UCs1dkpvVmhGUmZURW1pTDBmb24rSFhYME43b3JVRHlPNE44RmQxaFZ4VjRKDQpZTXhjL3l0NCt0QlkzTkVzV0xleC9aTUZZeFQ0YWRJd0ZLSzN6bzJqK25OWDJoQ1R0eUdQRGRGdjMzTFgNCjVHalFUeWJ0eER5a2djRUQ1USs3Y2U2SGdQRnQvYmM3UEcxeGo3YTdaWDkwSERNTmdnTkQwc201UGQ2bQ0KUE1DTGdpeDc1elBpTjFEbUlKNGwveWhpWGJsR3M4NjBoaFFITG85UEp3MFI0UGU3b1NZd1N4OGlFV0taDQpGQVBIOHVsaDlrbmlRNnlzSFluTFZtQmh4VHBxRWd3d0pWUGdHcVFSdlBZN1FQRVJCc0cvZ2k4dXBvUGENClVLdnZ1aUFqeFNSeWt0bE5sTENGbDZ5cjFTdDhiM0Z6K2tTd01CQXgwYityd2Vqc0NaYmQ2Mnd6Sldtbw0Kc2dUa1pqM1NNM0ZhalA0eHd3TDEvNnpqNUp0YlErSVpvUzEvREZ0dGtaTksvVHE3ZCt1SWx4YWx1QlhTDQpla2d2S2NWTjNUSlA3YmRUN3BXWUR3RHRoNHhNNnRFTkx2UDd6dDBUMnV0dEdieHV5RW1tVCt4UW9DNjANCktqRUp5RWhrQzd0bWxtWVhTTlFJd096R2VuMENEQnBMTWFkbjhWazBPclQ4VUg5ZWE0ZEpnOEJsTE56Tg0KaXdJc0k0UVNlVHpWa080SlVqT0pxRUc0Zm5SeXRvd2JWSkswakpxZjh4U3JOcDMvZXVWemxlMk8reHV1DQpQaHBJVXRFTUIxVFJDWHZRSzJncHB1QWxGNU9mV09Qc0JuOWYwREI2RVREajE0N2ZUd3gyL0duSjFhVloNClc5S0FQUFI2RWxuZys3ayt3VkJ4alJkUHNNTERoaVN6cHRYU3VrQmsyRUFHNFBYTU5WNzUrcmVBOGoySg0KR1c1RFkyakZaWnJCeVo4ZzY2SkM2UEZFSjhlbkUvZGtzMXdNZUdCQ0F5S1hmK2tLRzNFN2dHbFpaL0VODQpzRWJpZC9UT2ZveTdjVEl1UG1GbXhvSnJ5bVdmeWVxOHlnZDQwaHM5bi9uK3kwWGZlbStoeHRDT2pMd2sNCkZhbTdOSEJaME5McjlIaHk4enhFbGx6clhwczNoNnJUa2VNdEJua2xSWm9zQ1pIcVZTUzBSREI0QTlJUA0KRnptbTkvOWVPN1JZbUpjdGdXdUIvNmdwaDdHdGtKWGhKaHZZSXduVVFTWmVQcnBObTZwS0YxVFlkeGtyDQpBMHhveDVpR0FWdFZCQ1FoUU5jOGVIV2w1RUMyVjJhWjd3cEo3NnR4R0dHQ1ZvUTVycHhCV2FlUGN3cWcNClhNZFRoYWo4SmZMTzMxZVhsbStkdjU0QnFFSFh1VlVyeTJFRHp0bVBVajdlSHB4ZDU5dklXd0RYdjMxTg0KdXROM2h2MEs5ZGRHWE53QUtHbkZCUm1LWDczM1cyWHhBWThJbDl5TkhkUHNJQzV0cXZDRVlCenJYd3orDQpES2Ivb25zc1BXUm8zV2N5LzNGcWM1Y2dDSTk5U1F1dGZyNXFrQ25QR1hqRGJRYi9Wam9wdWtUb3pHTlANCi9iUlFVOXd0Vlk1cUwvS09Jb2wyaDVKdzk4bWNMYVpXMWlNMUtVa1VKb1VpMlpxdTZTRTdJTVB4NnQrRQ0KSVNWaGZLMlVkUHVYMXBmVkhVREVDejBvaFE5WXZDbllRMDJOVHJmcTFnSDRQTmtFZXBORUU0WjZEYy9oDQpITUhnTTdpS2gxbWY0RkYrOWsxZkh3VTQ4UUl3OUlueHNLZGhaTWRwWXk3b3ZTVnFBRkxMRmRSTm1xdFANCmhCb3FJRmNJcm1vRDZVZmErdUpNR0x6MjYyT01XUkt4b01oeFMzMzZVcHJqM1FSQ2xWd2hxeDdDcmJLRw0KajU3dStvcVg5QXp1dHhNcmM1Rjh2OXhkVzR1UitiNVd6Um9NcUNIYjRsM2UyS0RTdFQ2L1QwVi9RekpuDQpoSTVPQThTMU92aUErNVplT0UzZlZWWGRZYisxd2FUZW9hUXo2MVdTODhlN3UwcGY0ek1xZzhzaUJtRWUNClJ5VkFhVjY3K3BLQmxXY3pCZHdZaW5jZ2F1Q0NqT1BUYWgxeDludUJBK2JJM1pDR2FEM3I4NUtIb05QWQ0KOGI2REx4cTNucUxnU0xTSmdSNC9xMmUrWTE4d1dQL0t0OTcvZWdhODNqb215V0JQUlBjOHB4S1J6NHlnDQo1dzlNNFQ0VUhaVi9zcTZjR2FQU3lpZXB2NkNDNktGWnJPd3pzNkRZczVQZ2h2L2N1ZUNJQTZDdjZvN3UNCllMNEU2czUzbTNFMXdVWnkyMHl6NEluZ28xa215SGg1dk9BVTZ5UjFXdC9SQ25KZnRyRERPeTdwa1pkRw0Ka2I0ckZaZnJES1BDOUJodU0rb3M2OGJiV0dzUFQ0cnI4M283aThtY1BlZHNCNzU0TlIzcVEvNGJ1UUpyDQpndlMyUzJGRmdhNzJjaW55N0dJOExHOUg3Z3E5UXlzWkJyNG9nendxOEgydHFmYWdzSldZTVVJOXJPaGMNCm5Yc1M1U1Z6cDZiTUpiYXUvT2txU0U5cW9pUE5UdEtMUE1kdjQvaDFDMW1iL294VExjSEhqN2xmVVdWSw0KM1Y0bldBVWZrcHRuU3NlZ1BncS9zWVc5OEhDNVR6V1Qzd1d5WENrdStOZHp1Rm1WRzBzK0VYQW83WUJZDQpscHk4WkcxSERRL0lvRjhsNGhiQzFoeGs4RUcwZDdrc3pOVElmVnRSMFJKRkkwd2dnMjY5b0c3TUt2ZzcNCkw0OHRvZnZ0V1FFWG0wdVlqcFBtekEzSXdYRHExc1ZsUFZGVHlmN3hoYzRVTFhaWmlJcXhFd2krb2xHVg0KRlluNHFveDNCWU9xK0ZnczA1N2JpL2YzajMwSmhKVzlWZWRUZGRVbTBsYzlidHVDK3lUY0UvS3BmNk02DQp1Q1RVUm1Ldm01Y1lwZzdmcVg4dXdxeFRidjFpRW81T1hkWFU1M1J1K0JUQm1aeXZhRGVHelYzMVVOWW8NCjEzVXB0dS8rUlNiZHVDUlZ0RXNGMUZkcGFMT29rZnNWSUZlK0tqZ2NrUEFHejd3U0ZYdmF2N0RaRm14ZQ0KeGFoL2VZaGYyTjhpWDJVc0V6NUNydDJ0a05VbWdFM0RyMENrVGRoenlkM0dudVFZbCt5aXBMMVd2RWtjDQp4SHBHM25nN3pIditBdmVLbnNmK1JudFBvNWJKeVR3VjlsUDQxUWZGSkx5ekpVWGtQTm9Odm5OaE5JakgNCk9yU3c5UWJpUXZLZnpHWDFLUlg3QU9SU0JSVTA1RkhPN0JxeUNDbDVjUmoxRVV2TzRLWUJBcTRUM1FSYg0KVDAzVDdXcThtSjRGQkxDM2drWklBRkJYakJldENTK0lZUTZGM1Z1OTYxQ1JYM3kxQVE1QUlPMWpzMGF3DQppdTdxbk5uUzRXRXFOaEJKOTFGdVZncG5mam92VmZmQzZjVlFmZXBncXFrelZNZThCWnM5TWpRbUxVcnkNCmdTMDJ0czFjMjFPdHdHUE1FS1F2RUEySFUvYlRUSXd6LzRVajNWNTJBN2Z5MUxUU0tBVUx6SFN6c0VlVQ0KVzluR2cyVDVqQTBkckhwdzdOTHpnNzFzbXozMFFINVZycGptaTFIY1BpaEFGRmdEbHJvNDkrQW9IcDMxDQpOcytEM3pUUmRLZFRnMHVWRWpRSkRUeVk3dklQSW9xMFJQNFdrdTUrRUVzTExrOW95cit2WE1Bc1FUKy8NCkduajI0ak9mZlJDOTc4bHZrSlZpU3pLWTVOWEV3UHdmZlNkT3hVWHJyQ0xZUERwVXV6Y1F3UjJ3Y0xrbw0KUllZOGppaGQ4UmVjeU1UVG02VUU4Y1p1RlhzbHB5ZGxvUXRoV2EwZzhiWFNKZXNRUFdwY0RkS2FBTzcrDQpCQlR3S0lIRE94dm1obDliWDA2V2V4TTFadTBNcmQ2UUx6cWRsTTcyQUZyU3cwWGlXUDA3QWRmME0wWWsNCjBxemhEQTNwZkZ3a0dOb1ZscmhnTWNCOEVWNUVDaU04VWNTUjQvdGt3V3YxanA2L2RUR0szT09tNlhVYg0KdzE1UWdXRmFMOVNLSzdLL3RVM3RhUDBFVTBQWFgrNkVZWTdLMytSSUhNS0Y4c2dzK01JZnB6c0J1WDBuDQo5NDdmeG1vNjdrZ1ZHZS9VS3RRaHpEUlZpZzVGYkpma2VQOEY0T0h2YnNKcCt4TkxkcTQ2UUZVVzNhTmUNCjBrUFc5RXlndTFocnFGbkZUelJlQXcxdlVHQWpERXc0MitqdHhFcStTd21JZWFiOHdpMWdqK1dXa1YxbQ0KTngwamVXMUx1VGRzV3JLejJtU053Y2ZrU2lEcjhkYnpScS9HTzBmVVVkZWNzNCtnNGFkaGlFRURpU0pjDQpQTjV4bHQxVEZZZ2N2UTJIZWVRa2tiZWtBN1JEcTlkZXJTSm1mWWFXb3ZnMFU0TC9WM1VXdTU2RHgyS2INCk95STFDVVlOL2UxNi9adEYwbWxnNWhCcVR4b1FXYUdzZ0tKbG9wNjd1QSt2UlVGWXNaWnMrVG16NndWWA0KaS92LzlDcDg3Sy9yaUo3THVxMHJXelhWc3hxWXp1R3VaVWhjT0FaN3I4dlZQa1ZvektSMzRGbTRoM0FGDQpCd0ZuQUVCL29xam9oRWgrZ2NNT3Q3em1SRUtDM295UXAzdmpGQVE0MFIrWHhxT0FHeHU2N2phTmRjOHcNCkEvM3F5OUpDRE5DbFQ4SitmYlFqRXhpMEhPSlR1TlEweWNPWklHS2VySGwvRlN3OEtuZXdCZmwxUXlteQ0KT2N3VUFWOFR5UHZ3NFNNN2hKOVYxbnkvSTR3Y29VeXlKZVVOMkVONWwwYklqR1pFR1ZYL3VVSGVrR05oDQpyVXFReDAyeXN2QnNsY01DYXpJVzJSYnNYbnFpM0ZWbkgxalJwUEkxaEc4cGNPeTFtZFdCd3ZoRWF3dE0NCm9STGNaUHNsM1h5Qi9jWWNlVk9FY2hqd1FoKy9DanZaWGtkZUcrWGRsbFJkRm80T0kzeHhNa3B3RmlqKw0KTjBCdEZwMmJuZVh3LzBVbmhOS2o5M2xrcXoyM0F0YU5mR0tMbXZvK0FWa0Nwc3M1SzF1TDdkazZiRzBEDQpDcjUxL1BMeSt0dTBEZmRBbVQvVU1Yd0NLbm5mSjgzbmVRcmNHYkV5ZUxRaFlmL3RvQlJyUlY1YUs2ZVMNCjcxT1o2d3hMSmNoVUN4VGZKWDhpTStXSDRtRG9ITWwvc3VobVlFSjJ4KzZrQy8vWitzc3cwK2w1YlpQUQ0KTXhqbU1KaU9nMm5JVWxiNEw1cVJFOTdic0lVb0M2Z3ZIeVJySEpBTWhiVEVEZUFzejBQNWZOMEdybzFPDQp0V3F0cDlMeWdHeUN5Z0NUbElIamFjUmFibWVneTN5UWlyT0VNYTlObVJEdHVtVnVXRjFYZGlmb2JPeDMNCndVMUVEU2VKa2NRL2ZCWlZRS2p5eUZCQkl5bUd6cFJKVFozQ0l6V09mM0lzTmtBb3dwN3NYYzZUTDlLNA0KckxrMCtjQVVaMVBBSVROMnVKaVlFQlNlMEZ4bDh5SjRFTlMyYk1ZSk1kWUp3SEhpa3BUZ0xuMThCL2s2DQpsQ0hTdC9TTWIzRVdNSkZJUnRIRHlSVmZVNXcrQjVGekF3M0VnaERYNzdiWTVnSU91dUJzRzVnUlNjUUENCnYzQWtyRHFJTVBMUjFhVnVNb0hBaHovMlh2QVBiM2pnRy81ckF6WmczaTlpMVo3dDBiQVd5WlpFUEZzRA0KVUVWNnpyZmNuZFp4V25GRlNBeVh6RW5NcHNIcUY2TE1vZUlHUVIzZHBDeks5ekplSXVWMXVtODVxMmpIDQpDbWpuNnh5d2dvZW16NVFhV0NIR0ZTajNhbnNMOENrRUYzRDNTLzZFMzAwUWJxaDU1cDJ3U2owcHR1L3cNCncyd2s0MytDUFhwUmE5RksrTXZvMk50b2F2aUNmTHl4aGxHL1pqWW9wTzdhT1UrTHNmRlFId2lERmRBdw0KbmZ3SSszYXdLTW5TOGdUeGVVUnNTck9kblhzUnY5RFZYTUpMNnlDaEhlV0NDUEtYdDE4U0J6eTE2MkVMDQp2OFQ2VEdCbG1Ba3FVTVQwc0pPRDRsWVRRakkwbnBZeVlLTG45amVHTGtOYnk2WWFIQlByUFkrU3E3Wk4NCndTc3VNZ3hvTEE2bjIzTHJ5d3VDWmdPbHlVV1pvSlh5U0lxV0t1ejlaZ1U1dGNxaTdJZk9mS1R4VThDTQ0KbGVObmoxRC9pK20yZ1E1TmtJdm96YU1KL252a1dJVkNWcGF6dkNWMTNDRVJ6RGN5Vlo0bWhCdzl3c2grDQpCSnoyNEVQdjE1NUJOU2FYU0xnZWRnTzZlTU5halJSaE9TdGdsMWFqUmlTQnJIaGxUaHM0UmhXYU0rMlUNCnhkWjdUWnJXdFNWSnVoaTV1TWZ5OFhPTlBmbVhCWGlpNHNaamszZE9ydnQxZEVjeDhSdUsxbHNScXlIVw0KNmRVVjlTbVE5NHhYUHJrRytDTTJqZ3ZnVVNPR1NzZmlXTS9Xdkp4WFNMVzhib2ZJQW5SR2xNYXJWYjgwDQpHbGpWdzdLWi9oMGJOY0svUWJ4bHdjU3B2cC80L3kvVW80UHAybjlZUWtGSmFwSlphYVEwMmZ6c2lPUVANCm1tUE9IMk1zc1VMWGYydkliUm5FQ3I0Q0YzNEVnbzJYMTZBQXEzcnZDQUgyWjJTWlNQREdWdS9VSEtLZw0KNklNWFRybzVHNmNuVW1sd0xWVU00cDMyUVpYRDk0SWphYTJuYTdzNDd4dlVtei9hTmdPalFSTFk3YnBTDQo0cnVZa29lamFONEhmcXRVV1J0RnltUXFqMlo4cFBzbmlmZE9mMWhkeXZpZEdxSVY1b09HZXlEMVA0RHMNCnRsTlpYR2toTFdQbjkwcXJ3YXp1YnNoa0VJdGZCblkxNFNQTTlBWXlEUVkzRlVWU2Y0eVVxKytHcDB3RA0KOHRQMExHRWl2UE5ZTXpmbVRzNVUvNVhTeUdkdmM5YXNGeDE5aTEveFlhVkVvTjVSajdOTmJmTUFuSDJFDQpKejRxa1JNRkhFVUsrakFRanJjWjBBMnlwOXNOYjJabWoxQkJXNFlqcWMyZlMxM3JDYklIeC95aGgraXUNCml3V1BTYWloek1GYnBaUVZhem5VdEFQMnJDNnNjNW14a2x5ZmV4bzY1L3pEODVrYm9pSFNiUmNnV245bg0KampzcmNwQWhQYnp2REtxZ0FKS2p4UUhCclo2eEpISmNhMGYwbnhHOGxJaXIzU1ZTY2RIZDc3SzhxblF5DQoydzl5dGhmeUQzK0xramJKdzYyRHpOenFGeS8rTUc4RC9zQTZHdFRKaXlpOTdYWTBQcG9YS1hKVE9JMVANCk5mbkNseG0zVFhzNlNjWWN6VU9uR0NNYitnQVpCY0hCM0xIK3NqdVI1QUpjeWk1SjByY0FnWUlGajJBZA0KMnM5bVYvOUUrS1hUSnZOdnpRTzlxRW9heWxYU2lGbTFCYnBncHdoV0FjanpKSmw0QWxPQzVQREpvNGZkDQpqOFZaZGdRTnRjV2dYSUZhem1SbCtQK3BBWHNJTDJDN3VzT0MxeDhxZTlvbUl0RWI2eTJGQmpmNHNqUzUNClVScG80Q3JBSnhpM2ZGTG1zY3Q1cmNvSVIyZkZENENKa1RpRk9CODkxYnFra0tRUHozT2VvRGUzTWY5Qw0KcW10WkdFd2xLYU1PbVZJeVRQSXI5eFQreEFkM2hJMHREazdjbFVkc3lxTzFDR2FPOU4wK01vNE5VeHdaDQpNWFdFTFBGem93UWZDMzNKdHVEcHU2YkdXUldXSXJzcDA2M1k0UElTRmRwenNjSWh6Z3JGUHJteXBVZmwNCnpHSXF6Z1dGV2RMWDBmai92bzgwUTJOQmdQaUNrNlR6bU05T042bkcvL2pWNXFuTHN6MCtjRmFzM044dg0KdU5na0lCN25BalZBQ3hiUTNNQ0dFZkw2V21xTXYySGxnNUVPaEpnelZCMk54OVB2STdOV3FFYmRJVGR2DQpFNTZOa1UzSVFvSWZMY1Fhck52aVg0SmFmdXBiN2FPWmVtdmRLUGM1a0NZRm1HSWhkU3R2c2ZQVmpEbkwNCmh3YWZ4aUkxbWZtTTlJVG5XVmhqUWpTNTFGOFVvNTM3MmczcHRKYjBnSHdPRWlERW0zbWM3aUV3L1ZMZw0KbzVUVWxEWjNwVGFTSSt3ZHlmVnkrRk56eWt4eWhnRXNydFhNN0FSRGprVW1oODhWa21EYVZTUDdzdTQyDQpZeElmdW91SkNsWjJyNmZZMkVtR05zdjlnNXFpcFlHNW9mdFIzalg1TGdqdUtpOEY1UHhXZCtrWWdVaDYNCjh6RnZkbjZacFNiTlAzaStBVVh1Mll4QjM1ZkhoWHdaTy9OZlBwaTg5TVFXVW5KLysvN2cwTzJsQU1XSQ0KUGdYQkI2WUJPaUNBWVlwZHE5YlZ2K1Q2WVJOdlFVQ05Nc1FsdVBmU0dVam00OU9DMkViSkxDbTIyb3F6DQpYZ29sbVhuZldzY1lwSmdDUzhOZ1NpNDkzQWFOYUgwU09qZVZydEgyL2VIb2pwMnRRZlVZWHJHU1BYTEUNCmxKMFhKazFrQ0NEOHVVU0R1MjNyd2lzQXN1NGlrTHY2THdQVTdyOWVneTVDa3JHb2hqYmdPUGlUODJtTg0KaDVkUE9QdEw0TmJOV3RubnNuc0tXTDQxcXBQSGM4VlZhK1lyYzl3WkwrTXQxSmVSTkJoK3VxeUNhM21LDQozWjRGQ2ZoZUFTZmpoR3VOWTdWOUVxRmk0TDFkQmUwM3V6Z1RYd2k3L3NUb2dSTDNSMFB3SXJtcmFHRUQNClAvMWJvaWdFazBDMHE5L08xdGIySnNDbnl3VWR3eEU0VXEwWVBFcGhpdDhpcVRvUGVKMlBRVmpsakx5Lw0KZFdiYTk3M0ZDMmhQL2xIRWtJeVBmN2VXbGRaT3Q3R2dPYmhPMXpjRy9MUWxGWTNkcWV1UWZqUDIzemM3DQpkY2Zkekh1KzNVNDNDc1d5dEVQSS81WENFczAySmJJVis0SGpGR1hveURVQnkraGtNL1VSTFdEU0Uva3YNCnhyYjBnNHR1czZSL0xrRFBuYjFJQjQvNjdrelRwYlZPdERPdUFzZWQrZFY1V1hVM243Q0VtQWxHcC9jSA0Kb3J6Q0dNMjJsS2ljSG9PWDU3YUNiMEpVZmhKbDZpb2JBUk9yZ0I1dDBLYTdEeWFrbFhBQ1NtVVBIRG1aDQo1czhuTE1hVGdHaDJQSVVHSXFvdFRjSkFJRGc4NW53Y3BCL0VSdlczY0hLNitWMHlRU09WbnhXN0w1WkwNCjJjanovN1doUnp0ZDVsSWZXTys5dTdtTHpHNGhWTitrQWd2d0ZEVFlWeEhySnZrQ3lZR1lXTlh2S3JVUQ0KWFZ0bDFGYUtSSE1KMGhsK09zaWptaHFieGZjbE9qWVF1empIM09QUjF2aDNFWHRHcytwdmZaMkc5QlNmDQpMYUIwMnFvczl4bTc0Z3lWbkpvRlNHZzAxREpwajd3WktDVTNaSHlxVmYzcFRpN21OTlpOTDhjcWVhZkMNCmlHRThPZGl6Vm9SNlFOSTFFMzZubVJtTkhRMGZvblFFRmtuWGdXYWdlOXQ4aWg5cjVNQVNTLzZmRTF5RQ0KWGpyN3hyNkJKS0ovWVRMVmdZY1pveXNJL3BqZ0lLM04xN2dxOHQ3WVJDdnBocjZyUTJWMExFUU8rNDJPDQpuNlN6dGpVazhoVlFLZVhiYmFxSlpJU21NYUd1S1lSRExHUit5QVBYK1ltTnVKUGJSZmFrQ0lLVTE5Sm4NCjF2UEdYYjIvcE1lZVNMTnBxVkRkemRId01UQ1BVbVkxZ0orR0N5cDRyamVTbWoxOWR3ckNTN0RaR2k4Qw0KTkY1L2c5UExNdG1kZ1ZVMDlkTVBKbDVwdDBGaEFaWnA1THVyRlBOWHVyN3ZpeEtRNUdpbVBZYW5OeVpjDQovMXBiRE1qUkU2UUVLMXlXRlJQcXYzbW9KOENia3dzcTA1YVJ1K1JycmJjdHFORFJhMGtBelVGTGNrLzYNCjZqWngreFp2d3lkYm9TMkpCRGVoazh0NkhJVGpra1lXbVQ4WllLbUVLaGN3ckZJS3VNSnd3S0tSYS9oRg0KT0V6eXgzbno0Tnc5STZ6RCt2SU4xSEJadDhuUDc5WnE0L0c1cEllcmV4QUdlL3hzWHdCSmovUlFvU1BODQpsRitVVjJuVDM0L0FYL3QvdXp1VXhHQmM2QTFOUC82dUFLdTdpLzhYUXB4Z21ZK0sycndIOVlNb3BTOHkNCmhhdlArNzF1QXZMZTBuVnZhWVRuTG13V0lOZzRZMUxFZEFMZGtBWTlxZ1Mza2c0N2kxdmg0NHNlbWVHWg0KLzdKNmRGTHdNTXJJOThRYVBDd0lHa0hpb3pUOXJQRk5ONWdWbUhDMVhLNXFvN29lZDRueFdQUEl3dFBBDQpVbXFqNHpaZE5YSlkvK3RLNUlvQXd3TzRrMm84Y2RMUVh4bVFMdGIwQVQwdjFrREdjbmdReFkvNFVyanENCmVHMkNmOEJ2aTV5YVBYWm54M0JORlhoT3NtOTFoK2Q5cDZhM0JUNHJvNEp1WmU3cnR2NVVheDNucFpLVA0KeDlxTlVMUi9iUmdoMHRFc3pnY2FiZXFPQUV0d1NVVUVuVlJxZ2wwZEVQL0R0NHRubkZOeTZtdllyT0h3DQpoNWRqZzdtMmk0RXNGNkRFMlMwQktyTmRKL1FOd2RmV1h3WUV2eWVSaDlDT2xZZjl4OWh3Z3IxZ1hFSE8NCmp5RTUrNXRjUTk5SW9ManpYeld0K0dqTFBrd1ExUXowM1JRWjZpeGFqdXlZK29hSUR4VE9ILzZGRWlJMw0KbnVHT05mZlpIcllRdTNGNTRTVlNrWGUySG83OE8rKy9NZ281T2h5ZlBvTTMvblZVOUJtYm9MSVg3NTlPDQpYamZWcnh0RGI5SkVTbE9KN2JRQUdnYUZQSW41b216Nm5YQmszcmM4aHBFZkhnVHNWa0g5eGl6QXVoMVANCmxYQkd4ZXFGYmZNS01hV2VUNVpFdWZsMUdtb0dsaXY1dk9KTzNIcGhDUXdTcm9rQ3JQeXlQVFV6cVl5Mw0KdEJLUjJYdTRwdHcrbVRYdFVBZG9QQXhLRThZL1gwSmh2MnFkcHAyM2d1dkpJT3Fndjh4ZG9oZzdYaE9rDQozQnBJT0xhaFRoeGp3NDJaSFptMFE4OGVsWnd3N293RlpjWGRCTXp0S0o3NFRSV0lub2VHekJncHdHVHoNCnZHSzUzR1lmUWtxWVFtWXNTcVVIcVdzT3VqTmF5YU5rZUhLNnp2RmxQRHM3MmF2UzQyeGlWVzVEM0NCag0KVDVHUFZmNFluLzNrdEMyU2FZakZYZVVrN2xXZis5cmorWk12VHo4aFZnYkpSbldPTG83dW5uYmRENndEDQp0ZWlUekI0MG1OSi9QUUprRDkrOENudnpIdk5HS0MvMEJSeEtHY2dPVWduT05KZEhieDBKeEkzZFoyOXQNCmhmdlBmVS9zbDRyZnVSQUhLbGpUU1ZERFgxbVN4S2NIdEtHR0FkdkltU3ZNQ0JwRE1tc1E0MXBkMTNuaQ0KMmVLV25oKzllRkU0UXhFaXlEVVJuWjFTYmZhOGZNTGZYV1V6ZndNcTNhWHA4MEIrZFdxNHFCZnZ1cjlkDQpLSlVHa1pmVExxdGVlVHBTNU15U051U0t6RnhGKy9mcUtYYUdxSFI1a2dkZUljcm14QmdLMDhkMEgrWVMNClJCU0tmQTlwK0FvNkhpSHNLWHBIeEk1blRkWHhCSTVMVlYveXorZXlFQUpRR2tralpqZ2tLMU5wRXQ4Ng0KYVhlc0tySzNOK2NOQndkbVRXcldQNFZlWjhhQ2sxem15TVNCMURteDdlOVUrMWpJUzYwVFJsZGQzVnRrDQo4SG41dDhQdCtVelk4aFN4c3JRdmtGcStEeG5mTkQ2VVRoUjA1b0x4Y1JsYjRoVmlXYnlQMXZPVXZTc20NClhJTW1PbVZXV0FxRkVkVGp3K1owNi9JU1J2TThYSmhQd1ZIanF4ckU4Mm4xS1hhQy8wZ3ErZVJtYmdDZQ0KVFZFUFErZnpESmdrQjZVTjk3TzJnQ2hCNk1QUWlFZlQ3dmVJZ2ViRTEvOE1HRkhBSk55NmNsWURCemhaDQo3ZmQ3TXI5M01LZXBDdVlIYVdaMmlTb3RGYjJueDRnRU9xT2JiK2ZXWCsxbURNdTBnNFFOTVF1NzM3dGwNCnMzVkE5akFHUVVVMFpNNVlPaGxjZ2xzMklVeVFhd3k1TlhSaXhLeXArR3hPY0svcVlFN3QwVTBZWUZkbA0Kc3RqTWxNeThwSE1TVmtPckRaR0xUd2ZBeXZ5QS9VU1NScC9tNXdpa0pBcG01QmlYN3RXRzBCLy9leVIyDQpnUUY4UWl3TzZaVUlxNEo3MXBlTVZHSUt1RlBhTWNnNGkvdzRJcFpld21rbjh4UEM2MzlRNDBqbU9aUC8NCjVzTXd4Yy9WZmJJMm5ZM0xoM2tHcVpkK1I3bFJ0b1B3OVRzOEM4bWROQlB1bDRYMm5oMUk3TzZKU2dqVw0KNFRwdFBqd2ViZE45WG5RKzNQajcyMDh0NzJrRGpXSWN5VldDYThJU1VsODg2TXFxa0lQdmZaU0FiOS8xDQordFcrd24vQmFkVThQeG1LZGRZbDd1dnJBQmZwZlpzNWlSUVhJejJJN2FhcXBCeE84RmZjWlViY0tYN0YNCnl3aE1WM00rYitraWNOaGlvNVN3WlIrRmNhMFhBQWxYQXVGSVF3eFFhQzFjak5iaEx0ZDdOSE9iLzhXUw0KYmREWnZvN0trclRmOGVsS1YyaGdSblE1czRhaC9vZW1jYTg3MjhzaEpldFF0U0lFckRmclpzRmdybVdYDQpLai9NdTlFdEhzNkNhRmhkcVkwcWVlUHRLVXgwWXJBZXoyWU9Md0FBU2p3MzBwN0pwYWlMS3lUOXhFb2cNClhpMjNBSmNyOWZ2empCR0RnaGxVQVJ5RXV3WFpIZVAvYW5wSUtBS0owUTljbjlVYTlzMjFQRklobW1tQg0KVkl5MTkyZ2xQTnlXY3ZVM2RGSnBFWE4rZnc5elFSemx6NUE1YURrNWJManNCR0hLTFNqS0I1SkI1dXZxDQozNDE1VmovOXJ0K253SHFPeHBXTFAvK2ltYllucmhLbnZCdjFlUUFRd0t4N1lRQVFaa1hlSGxPcHN2ankNCmN5c0ZJL2dyRUN4cHpXdHRQdHVGekpIZXpiY3ZaQ2NhSGVRNUU1QTY2VlpCV09KSmJXMEkvVWUzM0VnNw0KZEh1Nk53VXVXVmRsL1lob0doNGRQMGxDaTdtRG1mbitZL0w0QndMY2Q4MDUyaHEzTUVHVkFLRHRwQzdUDQpZUThNUktGbjlDT3JMc2ZCMUpCVUw5aG1rTnl6S0wwci9vMGI3cHQrbjJRdWJmK1A1V1dNSGdSeXNKVU8NCk9uQlFmV2JQSXFpVGpHVkF2Y1QrU0wvZG5aN2VudWRVckxyVUlpODRmYXh6SkRMQ3dKWmhuY2RnSlBtbg0KeFJuU2RDakZTWUl4c0xBMkk0aXp1UUxoaG9vSWxMUk1QczBoaFUvSDdTVWdCQUpDVmw4WFN4QWpFZ3pJDQpobVRyVmFtMWdXeVRpbmxQZWpHSGt5eTR2ME11ZlRNbjhHT2FvdTAwS0NkVEtrRUg1MXduWVBOWE1lMk0NCnRnQTVOK1g2ZzNUMisxK0IxNFVsY3JYb3JNc0FCNW4vOEFjcFhpQndFVFdVREw1WkY5Y3FONUlOZzRtRw0KUVdzRnF4aytSWjFBS2xwVnpLTU9OM0dmbEc4bWw5eUp4cmxmYjc2V1VvbzR3RTgxbGdHZGtFZzRCbjBFDQp6b0VPNEQ1WWJwZllWVDI4TWp3SXBRQmRsM3RycW10eUFBTGZJbXhtS0dpejlnbk9kR0pwYXpHWEliSkENCnR3Z3VZcE13anZzcHE5L0RFaGtVQkIzcjYxZHRBVGJHTGZEVnJkZU9GSWFvMXRXVHRwb1RlV1JPSUdTZQ0Kc1hWZkxUQ1hNelJwaDdLMytjejBTV3FKcWppUDRWMCtlOVh0UmdRYTdNQjRCN1pPWHJhMVU1eDEyazB4DQo4MmdabExpOENJQ0w2REZuMnRGYlVZb29NQ05tNDZJN2dTeE41K0hXbUh6SnJpT0pwWUk3RGRZUGRpUmoNCjdVK0FpUCtEZ2pGQ2Y2T0FMRHNyckhpTG5QeGIwZ2J5T0d1dE4yT3N5S0ZLaWs5ZVN6WUFzckl5ZXU5bw0KT2JsMWpxZmZUZ2doRG1NQmt4SGxLTGV0MVlqQnJWYXV3djUrVlgwV2pUV3A4ZjNDTU1JVFRPVHhaYXI4DQpsSHo0RC9vMnVLYlc4SHRST1pJbjhDTk9UWFVjK0d6bFR3Z2syTUFuNVZSRTVuMUFDNUExd1U2cTQ0NGgNCmJuT2FpVWQyTWtiTDE1K1NYR3lHSytzLytHMDFHV1ovSXZWd3k0czhQUHZIQmxzMW82VHM4L3dnNEdIdg0Ka1hJV1c4OWJTTkZhaEszcmxqN2IvMGk5MWw1VWZmQ0J2Vzh4dys2TXVSWHVHeWM4d2hUVnlVanF6ektzDQpUTzd6TmVlZlFROXhKYVhVQ2VNc05PVG14a1VNM2Fob0JaZm5ldm94bTJpaG54M1ROOTgycm9OM2NoRUMNCnBmblFFeGg1eG1ZR0dPVGpYY2RmbFdxNlBsOTUxRGJiUG56OGV3MlJFeEdlaUdWY3VGVlpxMzIvK0tMSA0KQ2NReE0xZHcvT2RtbGhpRG9VSXB0U3ZUZUhhMFl0bWNNa2E4QXBSREFBaVRxQ1lzOXc5c1pjWlc5MjIxDQpDME5aMS9FUDlQQklSRlEyZEJiL3FpVVRTMVNFL3BLaGVKQkVlb1dxTzJGeEkzdy9xWlp0ODlWcVBsaFANCmlGMzl1bDBPYTgydDY0RStVZU5ESFA5VTVFcWx3YWJ4T3NDWGRHSHh6QURXdzdLUy9FVy9vWWVVR1VrNg0KWjFmcW5GZUhDMXpKZ2Y1VGxXL29SK0JDQWQwWXZKVlpxQ2JOYVZncVVQTkpxVmp5WFBMWldaTHhIb25XDQp4UThhdTdwY1hZSFk1TEVaeVNaWndWNnY0NFFqVC81VS9lUjNZSnB3S016MVRGUk44RmRoeDVOUGNQTXgNCmhKQ3JJRS95SEVkdFhWaCt5S3lQaXdESmR1ajRlcWMrWjdidlpnRy9GZ1ZMMUt2bDVOT0VsSXV2OGVHcQ0KengvSis4MDg1OUpIQXN1R0ZLKzBKVWZKNEc3TW0vMlhFZHp5bGF0U1Q5MmhOREt4OXFxZFZYcTlUZk1TDQpxZ0k2TVVERjE4WFl3U05JNk0veFVPa0NSWlRKaEU0eDI0Q0REY2R0ZDBMNUVKbHkvNy82ZElCRkF6OTUNCllheHNLenlPU2d5M1JWY1JxeWFUbWRZZ2FPbjFramt3TjFzUXpUQkpUMUpuMTlUZGt2MXcyc3NMMnVjZw0KMXFCdzBzR0h6UTVFWXg0ck5zenVmMVYySk0rS2ZqT09uaDlwUDNxY0lHMW0yQXh0OVc2YXBWREs3aUpYDQp4MG02QTdrK2NETHJqdlhIdUt3YUFiTXBPWkdZdlZOUkZlZFhmanRFVG51UzdiYk5Kb2JtUXF5Q1VUNHUNCnRjSDdZNnk5anh2SUhBS1pUdlhVL1FiMVpTNTlNUEk4M2tCN1ByVGdzVDQ1QlZTa3lnWjRiY21oSVN3Tg0KcGhTL1k1d0xhYTc1OG1tMk9nS0RneTRSSjF0c3pDSit3eHNRdExCRzhDc0x2ZlkzTjRVTVlXOHp0Y3FwDQorSTNkUnlRMEQrRkZ2T1FkdGh1b1FVcDhRZmNndWFmd3pqTktGSGtZWm1WR2NtSlRWZkwyQ04xNnJNdjUNCk93MnM2QzloSzFhejRuaFFuUjJVZEpRVlh4Z0dESmNuOElGOWJqZFpOMk9pUk1wTFQvVzFPeUs3YXhmYw0KV0YrNEVWd3czTmtmOGhmWm5LRkZDdzlHdjJmTXZtdHN4OEpuV2JuMlJvOVFBeEVoOWVXK24yUFJOcDRNDQpoeTdOYU10Ri9FMEx1ZUVPV2RQRkRqSStlSmtaQ0lWS0pPbDA1K2EzZTlzVHRyOTg2YSs0R0o5QmJzb04NCmR2RnlIQWZyTzM5ME41WWxvdnZ6MlBpMDRRQ0pRTUFGSm84ZDJ1UjJ3dHBwQmxNWmkxY2RpOFM4azdPVA0KZHhmcjE4RVJjZ0dCWjB0S1NhZytPYmZzUllqYkc3THpVRzBNM2xKYUFnOEgrQXQ5MTFOQTVsdW9hWkZjDQo4dU40Y1ArNk1iRXVpVmtoZzBMaDRjZjRseXlOb2VjYXZycWU2eUJ6aHNZY1BUTE9jVVR0eVRINC9RKy8NClhwc2pOYURaMEVQbWtGTzhvNUlsOGMzd2RzY1h1N25yZlZXeW9JcFJmZ2xxVlhDRFViZlhFOHUyZ2dDNA0KVG9pUkFrVUM1Rkl3MVZkaW1HVCtaY3B4ZVcyMmJUM2pBbjRieU82andvTkhlY0dudk1BYVE1bXF6eXVaDQpvMjlPSkdvZXV2bERjOWwzbnZNT3hmQi9CUnRIdTNWdEUvb0wvK2EvQlRGSXVHa2VWdlRlOW9lRVIwazMNCjRlSjV5enBTU3NOWThpZ29tdkYwRGZEMGIyKzZqekI0eGJORGw2a0dQWURKMkJoRG5vTnZjNmNCRFpmRg0KSDlxb1hxaEJ1S0Z2MEpaVFFkMGkxdzNPYXN6WGhrTUdqU2p3UTNlQ0xudWJPZGYwVU5MSU5kRForR1FnDQpqRkR4SnNUUVBDSWJMY1hNQys0My9sTkJ2STI1YzdaT2thaUlna1NCSTlTSGZvWktkVC9Kdk1WdkdOc08NCnBpdnBlNDQ2dDFIM2wxV2JsVUlUZ2F2NlhlM21VbXFaclRVOGVuclFvRXdwYnJsRWRJY29ZSTEzMDNoTQ0Kb1hmVkpkeVlRVHN5aHJpNHNQbUVBbWxkY3YrK3FUUjhlZVVkTFpLclFHYlgxbkk2YzRSK3JMY2Q4NzVCDQpKeTV3N0c2WWV2WVlURmdqWWZuNnhDcGMwOVA0ekpzbWgwRVpsRExPNlRzOElpcHFjY3E3V1Rtdis1OXoNCmEwb2pzd1RNTFFxc012ZmxyelJaNDMwQ3lTelBLSGdraTNEK1VrZk56M3p0U1Z3MjZiZmtZeFI3clFQOQ0KSGRLREtVd3hLVEdjQ2RVQkE1N1FLTlRrdTN4ZkdoTGthdlIzbUljTHNSTkxaazdVMTJjVzFqblNtOXlxDQpURkxSeHJTZkYraU5kUng4SkIwVUZ3VmI2WnptV1czRlJxaGVvK0RTQUpnRTRKVlV6S2J1SkpNbUZuMzgNClhXZzhxSzJZSWZ5cFJISmpOLy9RT2FEMzVCa0VRWkt5NlB1NjJmOWFjV0ZuMzJpTGlBRGlXcjg5OFlHbg0KNzV1MitwQWFYR0ZjUm82ME0vMmQ2bTNlSXZmWVJUNHdLbmhZaHRTS0xCS1dleTVpOXQyMnJ1OFZZRVBSDQpuWjR4blFDVjB3YVVqczB4MDlkT0FXNERJUUozZHg0WDViQXJJMTBEOEVRcjJhZk5LTEQ1R3R0a0hNRUsNCjdWRGpDUm4va3pvWmdoR09sM2Y0cEZuajIrUTI5YWswY2JDSjFmMWNWYUNWYWpQVk9qWHlXd1IvNmhqLw0KRnZuR09SaklNQVFabkdaOGtEWDM5ZUxFbVMxV1JPc0Rxa0tnMFNKOUQ4NlR1RURPRGM4bVdLdkxwNzRXDQptYzFmY1NkQTcxYTE1UVZNK1lqd3lTWlN1WFl0VjRJc2RlVHlLQlU2Q3ZaUDlWOUZSb04vNU96QlFxTzcNCmIvY2FmWm5CYkZ3bVd6TU1McDEzS2RHc0tyYmt4eWovVWJqblRlaFNlR3lQNFhrNllNUzBZTXAxR3U4Yg0KV0YyZ2ViWFZablZxSzJnazk0Nk8vRVEzclJqV0c1dXJEdnBGWXduSCt1NklEVHRVZU9ZNW02ckZyZ1d1DQpBcXJSdWpRQ0YvanM0NDdOVWNDVzBENm92YjhFNG9VTGNVMUljTWxpZ3hnMzJFaXNhRlhyY201ZTFMMDYNCkZaU1dyTVNMaTBWQjkwdlF1bzQ3NWZpTEJOMkJPK2dFbjJTbXRURjNSbGxud0gwaWV0Z0NMT05wMFZYbQ0Kd1FKMHN0bVBxcmJyb280bk1wcTB4dVJQTWNuMlZVR3JHajU2bGxoam1HdzhZcjFLVDRqVFdmZThOaFIxDQpGVUtEUlZMZFMzcUlqUU4xL2M1ZlRYWE9jS2hPbjczaUY3N0RtTXdmVGJLUktXNG96RzlraytUbGNVNG4NCkY0cEtlWDY4d2lkVlN6aEhXNUMvVW1WOWRsYWZiQkZmb3NtNzlXUFppV25TckNqOFVhYjcxWGZ0cHR1MA0KTHZuM05SY1pjaVhLZFpadjRzTnA0N0hvTm5pR1JnOUsrTzNObVk3bkV0dmN4WEhuNWg4WlFXWXJWc3d2DQoyRUhZSUlqWVplTGZ5WDNWQUZLOElGMzFDYnlRcGUyUFJCeUhQUnVDTkNvV1lhOEhpelpqRW9WSEVQa2kNCmJNU0tGdkF2TU95ODc5MlJ3emZvZkRxOGJ5Q2tncndJaGtSbjRiQk1WQXFtalltMGdJWGluODQzU0Y1TA0KNTFGby9Xd2Nla1NLejNRM0tPRXpJY2k5MXRxcDFtY3JVcVc1VGVuUklaMFZTcFFYMFovTi9SbkwxWFhvDQorcy96K0VNOVRXSGVuWVpxUmJJY256NXo0MnFybEhjNktlODgzQ0tjSC84SVkyc3Z4L0dFQkhGUW1xdDgNCllCTHNQVjYraXFiM2hvQjlVaHZBYjRHdEhNRTAyNmdObXNRcU1HVi9KY3F6ejVnWCsrc21salRDc3FDRw0KRGlBNzltYTBlazU4bThEaVllc25yNUtqRnFzNjhxN0dLZVJIelAxZm5pRUsvdXlrVW9NOXltQmh1WHlODQpBZzc0L1NsRStmQUZQUHM3dXdEV2N2K1BlUUNLRkdRd3hDcytvL2VrY2kyT1hscTEyd2xRaVFDUWl5ak0NCjRWZmczMXgrc3RraE8zU2RleVhVdVVySWp3OThJZUVHNXlDbmxWRFFuZE1MNGlOSXNDR0ZjTVNGaStpOQ0KWTA1WXlwRXZzK0grTjBwbThtR2U2VFFhOGljM0Vnc0xHeFlTN3F3SWpORS9jditTdTRPRzRRSFBwSGNmDQpKRXIrNmoxMWpIZ2E4UFQzUHloTWREamlHa2pSc3dyNXIrU1g4bFhMNWs0TDF5eUo2M05EdGlQR0MwNUcNClkrSEdTUUlJd21nZUM1a09RTjdJOGdORm5vcmtOM1dGRU8rOUU1K2lXbzY0ZytyMW5ZUWhHUVRDamdjdw0KS3R6Z0JUK1ZnTElVUGZXQm9vVFAzbkFJakFGUm1uYTVpUGJyclZMb0M2R25FTWhuZzRlSlRMNWRuM1hKDQphWG5uNUhRc3BHUmR5REFMUWU1RHNUbnN5aEpYOHdGYWNzcjg0dDZ0a0NFV1dhYWJldXE2TGRQV2RuUUsNCitZYWJZcjVvMzlHeWtZOEhEeEVVaU9MUWF5SjJIaThnd01hWC84Sy9LRlVrUUlrNVlraFd5N0Z6dk15Ug0KYXdvaWdrNXhzT3FJVzFMd3k3Qytjb1FVUFZpZFpnbFdrb2lzMFVXUmRJVmVneWI2L2JNUzcybWpWQUUwDQpMaW9KVExLTnpDOGJpdUJMUnNvTEQzY2JQK01BOENiczdxR0VNRGFwV0tDTzdCTlA3OXF0MlR3UGFmbWkNCnJHVFQ3UUJoaCtGMUc5aEhlZG1odGFEVmFOTDhISmV5UGhQNTJFRjBWZ1dwcHBja0I5QTkxNEpIUVo3dg0KSUF4Y0Jja3VqZlJmZjhCZVVtMTBEa0NsS2tORVA3NjBUcWxYbmErM0d4Qm1HSkhHQ0FieE9FMHlvenZDDQpwb2dST3RxNjEzQmg3VXBINkNzdXVvNlkyZG93cGRvUVZaSVJsWlBmVXlTU3lDL3BHdFlqb3NJYjEvUDANCjJiVDRNVXlyRmorbWhjTjd4bFhxNC9KYjhWRzMwTkZibStVV3VLNllvZkgybWFvdUVITTdyaE85b3QzeA0Kd1F5SExhY1FoQk5JTGN5NzZMd1p4VmJWWjdEUlFXLzNtOTVmSS9Ub1FRTWR6NWRpdUYwSVJjQ1NIK1hLDQpqT2ROSzRTYks5SU9HY3o1TUdGWXNiMUtoUThLaEFBbWYrQml1MklWTm9Jb2lFQnU1RFNaL3lMdDJWOW4NCkR0NTVIQXVFTHFmYTBVN2EzQllud01TRjdvNXlrMDNHdG5lMUE2Vk5GNHFOa0FhY0tlaWRBT1BjR3k4WQ0KT2xIaERxMjJOeDRiWDFDNm9oQUk0dXRxVzBFRlEyTFAyNzlROVNMVUtTdHlyM2t3eXRJWngzMHFVT1NGDQp1WDUvbWtCWXF5RlpUMHp2VFNuSHB5MkVkSnk1Y2FhWUJoMHREOUVrSk1aVjlHT1NOb29LWUk4NFJWRUoNCkpTN2dpQStxVFpHMWtFUkhUMllsSzZ5MU1SeU9OZmI4VnhYeHhTYW9kcytoVk1nQVJkSFJneWJGc1YzcQ0KZ2hDeHplV0hZbjhZcVRpLzhJa3l5bEJHZlNtS1FJTnBQZTJ4MXVVMm4vV3MvcStaVFg2TXB6bDFBTjY0DQpsVzJCS3ZLVzEzS244RytzUFpkY1NmbDJoTDhpRjRSNDR0SUdQSHB1K3pWVmJZM0tuS2tSRnB3NUNJT2kNCkprRHNMZ3JsbjJjOUxyR2Zzd0FJMnN1MkhEUTBYMDN2U2d4QjhXWkpVcjR5VXJUQWtkMlcvNEQ2YTNQVA0KTG1oME5MYkpCcC9iYnE0R1NXM2lnYitSODcwVTFoNjkrMUtKTjBVbnpuT3dwdEtGa0N3emFBd3RkR2R2DQpVWjNUZ1ZrRUNwZDZoY3FyZmczcHE2dFRQbWxzRC9EV2lzbE1wY2Fub3hRTUVEVGhmSmIybm83U05FeEINCmlxM0xIbUp1aUNIR3NTTHlRd0xrcXNzUkZ2anltRTZqSWk0My8yckEzK2NaVGJDNUpaMzdJTWR3SCtnMg0KaXluUHhrZjBvcnJDU01SUTgvbk5TaEhvWEZydFpGWUg1bUhwUG9mNUFxby9RYWlkUEFRN3FuVkhIZzdpDQpBMEdrZ1Bac2ZJY0tLWWZWaDJ4L2IxWkpTcnlLT21UK2xMNC9Odm5jVG9JUWkrdnh3clRQRjdYWlk4Nm8NClQ4MlVLSzVoNmpaazFCYkhmMFRLallaWjZ5QXhSYUhCZisrcGIzUGt5eW85c1RHVHdpa2lwUWZXNi9UYg0KZ3YzRzkyenNjaXM2bEVaR0dsOHlsUjc1czl6OWJzZlNlQURZVXdMNTMyZndZT1RsUjV2M3Q3Tk9KVVFlDQpPRDNOT01TOGhkaE5mR2NCY3c3ZVk2UzVTb1VtSTdOOFpSVHFYQklxOVJKcUlTQkwzb1QyN2kyci9tNEMNCmRNMnJKL2xWK0pMOGJ6VnpMS0pybTJNaC9ZMDIya3I2a3pmR1Ric2VqOUd6eGNFRFRqenl3N1FQbE1nMw0KRmY2OWx6RHJ6ZVFVMkxnTHgveVl0NnFHLzlIeStPaGJjNzU1a3NkNDN5MFJ2NjZuKzhXd1RzNmU5ZzNyDQpqL3kzOWFlakI0ZWUzRlVuMDBsdXA4MGV1TWhBRjFocFRhRkhXZnhPNjZ3bnRqb1J5Q2U1eDFnNjJFRVENCjdETzkycm1KR21JZGx6bjRPWGtYaWJpRmpOaFFJWk54Z2xSZnY2V2dLc3VoK2NTV0pyem1iWTVNUzRvNw0Kd0lpWFRKWi9rNjQycEFWaXZaR0g1S3ljT1Q5N2ZHOEYxejVXSVl5NHNjL2JpKzhuVWgzeWJGQjI4WkxiDQpRWEIxK052UHFMTkJLT1FsblFiNGkrd21PY2k0ZGRHK3kzYmFPdkxVWWdNSTJhbzVwdnJEK0NUdG02aXYNCmJNejhXZWFyVnpVeXc2RnlTbXR4WnZCOUdHSFRrLytnK0FTb2dsQm9iOXlxNkhXQzMvYUJ6UTN6UmJCRQ0KQmIrRloyREo5M0VLTEh5dkVtZnRHM2Rjbk02clR0TDR2Z21YN2xoWHFOck1MSkFoV3ZDbW1oRWNvWUV1DQpORStJak02emYwdXRMOGRvbDFmMWd0ZFVFSkc4OWdEekxBbjZUakN6VjRYOHZYd2xBa2RST0NpM2MveGQNCjl6K216NHd6YUdKaElwUkRvS3prWWdRWDhTczNCV3RpdnZaN2Y5ZlFCK25LWE1sdnBLL3k2VWhHb2JUdg0Kb1J1bEtvUktJR0daTkM5c1ErdWgvTjdrblpvRDdTMHJQT2VSZVNyZ2ZjWFByRUFjMVlsRUFmWTBSY0hwDQpGaFNnMS9nbWVnOUcvNVR3SWJXUnFYQmhrcG5YUEs5Ky8vaDBOc0o4eVVaQUJiSHpRK1hBdThHNlFta1cNCktLZ3JKWFd6VzF1L1BLK3hhMUJKUjJnZnVFY3BuV1ZWSlE3VDZBeEF4Ny8zR0xhOUg1WE0xWURDOFBaVQ0Kcm5CanoyVm9wT3Z5TkZ2Qmt2TGZlMzNqRWphcCtaM3VXbmpxQk1ENXBwb2V1bXAyNjROeHN5bzVVV21IDQpaRCswR01WYmhUbElocU4xV29tNmJyalM3SGlYMUV4WE1OMnNkN2x3dHcvVFdVU2JvV2pLWStnQUc4eFoNCk03c1VJSm1xcU1YOUpFTFNCdGdwbENab2swcXl0aFJzaFZ6QzdvMEhKeTlKRVVaK1pNcUI1dHJMaEZDMw0KTFZheUU2Yi9MUDQ4cFpjYUluQWh5QzQ4SGpkT1plejFHaUxXd1NoaTA5eTY0amRoUzlNWHZwU0JFNklDDQpNUlFqT29OaENGRFkyQlJ0Qk9rc2hldHZzQlFsekRoSWVSMk5HWXFObzh2ekNleXJVdW9rYWg1aERWbysNCit6RnJJaWlzVE01N2prb2FLcmp6OGp4MTlNWEUzSEkwTVFJSlJMTVJqaFdES3JlUUIxeEQ2K3h2WVR3dQ0KaXZsTUdKMDlSVGNvZkpTNjJ6TGZoV3pCa3ltaW0yMktoM3RtYjI3cnR0aVpXdXVYQUQ0RTAxMzhHUVIyDQpBNU9DQVByR08wUUZVTGNIZ2UzVy9xY3pJTEZRN1Jxb2did3N6cDVyeFBXZzFsZUJpYjkxWTBmL0FTc0cNClhhKzhZOVpMRi9qMDZkcGt6dEtGaVFRR2RhZkxiejQ0dXZ6VmtRYVhwU25LWUMzZ2RKK3VLbzErRmU4Qg0KR3F4aWJqb1F6Zm00cHR1WHk0VmlBRlp4amtYQVRrNHNJK2M5R1dHNFNpOFA2YWdkT0x0bHVmanVtdVVnDQpUYjlVd05DUzN1d3lSOEM5T2dSclc2M1Y0VDZrNFFmaFB6VVFVMEpDYld3WVE1MldNY2JJd2d1UjFpd2cNClBhYkxSNUJoUlBHLytwNkVyTVVLRllJM3ovelBPcGlXU3NSQmJiT2F0OXFLYVVJbG51cjAwU2RsTTJmUA0KdmQzT1V2REZnUVMxSHhPdnIxUEhNZFkreEdqazV1N3Z5S0MzWXU4aHJBNFkvbzF3d05XOG8vTDlQMjlwDQpUYVJPTzRsWXNnTXJUUmZVTzVJQ0JyVENZU2RPUDF3TnBIdlVXeXovdStHQXNRb2tCejkySWxmYzZIa1UNCnpxWjZ3Y05RQTNUWDdoem10YjhUenRYc1Z4a2xCMWMzUXVDSGtlamR0cy9BQTJnK1BNbitEOFF4RkxERQ0KYVRhZWZvbkIyZkFPRFBEZ3dLSlJaNmFZdkllRDNleE5YVEdKN0lWTWJEeWFOSnVLQUUwY3hZK1VpZE5QDQovNlBMZGtwcUpvWmUwODZPOWtVT1VBaXRCN1k2T3dVR2wwNVM3cEVjL1RrNThmL0g2VGtRY1cwaEhIbTINClBrMXdnN3dYMkhCME1SMS9XbTc2SmxoR0pGS2xNZXRnem5RMXZ3OXBQMUtTeERYQUk5OVcvcGV2dEllaA0KVGRjRnpFeWFxV0RRaXhqODc3VUFvWU1Bd05SaGEvUzFyMjJ0Y1dzRWdHTkJCMHVEenZ4ODlHNXIvZE1tDQo4Zys4d0tZY0ZJbTl3NVc5cFRJZ2dCcStiY3NqdUt1d1FZY3U3aTBXNWVXWTBCSTl6N0RIbWsvRURFWmUNCktrQm9DQmMwSzk3K1kxbHEvNm92WDVrRXJSUlFEeHhtc1UwM0hIeUl3N3djME05OXJBMXJzMVp5aFZKZg0KSG5UTWMyZDVYTnd1MjdLTjhsYTk3U2lnOGR4aW9veWpNYUJORTFiem9hUGRZa0RqN2pidDF6UHI2SHY2DQpoMDBIakxUUklmTzd3ZEFGVGdlVXMzeEhxNU0rOWl1Qk9FQm14OTN0aVhmc3R5U0MxRXRiZnkxRlY3UGcNCkV1alRRbThBRTRyblBXSURvM2tsRDBKbjZPUmowRHhQdHNqTW9raW9MMVE2ZDJUUTEzb0dld2xhV0ZJeg0KZ2R0OVFPaDlZZllUYTRCQUdmdFRKOHJPSHRkaGVkYVc0Y2h5NitWU1J5MDNLVnQrYmI4OHc3SllQNnVQDQppRkNpanFxV0lSZW9pdmVKTlM3dWd5Z001a2d1clpEeXBQeU5JVERRTi91cHZYdWJMRmZ2NE1vM3FlTSsNCmxPQVM4VjFlMjVnNFVSbUdLMFQwc2tVV1ZSTytCbUpGYnJyWGJGVzRxRkIzVWk5Vkp0d0dNTGw2aEgyUw0KOGdUMGtERzdKREticVhmajY4ZWQrcUJmRTh1QkZwMFZTOWphWUgvWVEwS2w2QkhLVXJZSGVhekNtTkJYDQo4aFRaekIxNDkySmRBRDR6cnA3ZCs5N1JnNWVWeUkzOSsrNmtYTHhlcVhoaVJxMDlRcXpieEZjdDN1NmUNCm15SXYva1FLTitPencrZlNyN1F4VHRDbmc3MHY5S3JXR3gwQnhhTDZsd1JCT0Z2YUo5QmtkdFFDWm9wVQ0KNmluOVRjVjZ1UHZXV3VKckNiTkgyOWZTVEFjQlNpUUV3YzRjajMvRnZQNzhzQTRKL0VFVFluRDNCa1FHDQpUanhKcVhpNHFjb2wvSC9RU0VBV2dqbTBQUU9aY3JYVk1oZFVRWGxMenJ5SVgrekFEdmZQbWs0OE52Q3kNCkk3RVZKcHhOVmFLQ2hBaVlHT0s3a0NKbUJYQ1cxcGlrajcwSXcwbGNBRFZqYjViVlJtcXRzRGR3N2x2ZQ0Kd2dCUEx3b1AyZFZCbVQxbW14dHBmcXdFL0p0dVRTNE8wOG1BSitodlR4eEw2MGQxdnZKTzBmaUltcFFZDQpCUjlqRUlaU2ZFUmo2dmtIam0vY0xPQXA4V2FvOWRxTG01Y0s3UEduQWxCK3hyZHRVTmkvZElEdm1LeEoNCi9hcmhCcjQ5RnBHVElqcFJYL0ZJYTFUN2lvL2hjcjFhUXEveWFEU0pTVlR5aVZ2NFRIM1RMWHlQbHowag0KOU1NYTNwM0tYWFdyVTZjZ3A2ZmVXVmtVUkpUTGV0ZlJIemNtUlE4TUUyb29WNmlqaSt2RzZuSTRoSSsxDQoxNzdvemltajZtZzlOeEs3QmFtbjk4TWlFUUZxcHlBbDZ3dFNIbEpicU1pY2tiQ1c5a28zZGx0VHhwZ0INCk85UEFLc1E0S242QlByRC9YN0MvRk43S2I2d0dENXhCWU40NkJhbmRLMm16K2ZJTWZNODM1M0hITUV3bQ0KZ1dQMG5zalF6NzNwb21CNk43MUVZcWd0VzBlZUdKVnB6Z3dRRVJxblAzalM1WHRBT280RitLMHphdzczDQpydjliRE0wTStjMXNDQVRaVnMzK2dHQzJpc25IZ2RzdGxZNE51TWQ1YUFFN2d4YlVITDluNStZQWN6aysNClN4NkJRSnZXRzlSbWpiU1lQNmpsVmV5L0ZmRUx5QlVOSWh3UDNaOFRJdHRKNWhYWVdwWVZYcCs5M1pRTQ0KbmFaWWFONHJjTGpHL3M2RURNU3NyVFc0RXNnRmZBTTVKc2p2TlAxcTB3TlA0dHVLWW1ONFoveGErZUE2DQo3MmxLWTNFcGhSbDlRTEZ1bXN0dWozQ3ZtaE5ZbkxoVXZwTC9jbUJYblczeG1kL3BrZHRoN2prbU1NSDANCkx3QWpWanFzbmR4UUNiRDdWeThOVjNDSFRkdTlqRFdBS0RlV0JQcEpkeXhpNTdXWXB2WEJMeDVjcVNmZA0KUWUrc1BTendNZ3BTaVhucnBzaU8rbmk0dkVEVHhQbXA4TW04K3hIVzJ2aXhXV3YrcEk4cGdJeXM2QUdLDQpWVHJOenBjN2p3R0lWQkdhY1hHWUVpeEZKbmVFSXFzcHhXMjQ3eEM1cTNMQkpSbENQdUF5dGJWenZLODINClJESCtQZlUzQThHV2FEWWpUZWcvMEc5UkZETnE4VkdQdjkwL0NCRWljaFloK2Z3ZlJKQytEUXpnWG1XSQ0KOU5ENlM4NExqWWVwYnd5VFZwbjNmTW9Wc010L1A3bzNkZ054M3dKbjM3QnJXL1VFWnU2NUd0bnluamYyDQpHOHdpWEUwZ3lQbkpEdjhORGF0ajhNSGR6R3ExU3N5bkJXbGFjdmtIODE3TG9SZnoyUnZXM0NxNmwwNFQNCjY0Q25yZnVFMzROTUtNV3ZtMmlRcUdYdTFvZnlzQTY4WEM5WkE4T2R2TFZVU1pIa0M5RDFGRGFTK3R5VA0KVFhIM2J6cFZ2aE9xamY3Q3JmSG9ic3VUZTJNZXNvSUZJMGl4Zk9WZlhBbEFGMHJIdStvbE9uNFprZ09TDQpIdUtjTXNDWUtqU09sWFpScUplTVhDc0Z1QjQzbFJVTXBUZ2t4Y1dBQy9qUlVnS0tGdVNTazYrWDZwNHINCmhIYVd6WDYzU05VMGZscmFLSm9hVStaT21PMFV6U0xrb05PQ1ZRai8xQk5lenl5d3VkdFRVWFptYVdOOQ0KZVg0Rzkyd24zNGNoY01sb252cnFGR0ErcmVmTE1iQ2tMN3diUnMxRGdVV0xuU05Eclp3UU9xMGJMeGQ4DQpqTVhTSFBXRHN0dVgvREp1bDd4UUxVakNWMlZBc3M2dFlzTEpDZFNqUEdTTDIwWnBEbFBZWUwxQnJOa0wNCmhGR1o0YlM1U1J0ZWtrczI2Vm5ONkJmRHZmcTNKVFpGL0J0SDgvdGJYZGJ5MS9xejFZZG1KenhEVkJRaQ0KNWtQcGh4RkNyTmltYXVva0s1SGVtaTB6RmtoTWU4YXV4VDcyN2JXRndsVXcvSXJSMGtFa3dLQkNpZXZjDQpJWmVFaUlZeE5kTVhPOUJPRjk1OEM3THNQSDcwaWdBSlFRS1czZzhOQ3pzSkh2MWQzaUVnUXVXYlZCekgNCld3a3lLV1hYZVlmSXJ1M3V6cnhmV2VsWFlreXh4dGxPbmdjNU1CZndkMTl3M2k1V0NYbVY0Y1ozaWd6Ug0KUUFQYTFyOWI3ZzFycjA0WW42cmtHWlhrM2ZUQ2p0ZkoxMVc1Vmoxc2o3ZG5wNGV6bUY2bmNNblB4a2h0DQowZHc5cit6MVdOMEdNWjFmUDhoUUtOOUFhUkdjM3d3TksyWmU1RGdaTHl0V2VWbXd6bFNyRVZBbVd3TWYNCm9GbmxiUkljVTNZd3RjZU1IMi9pSE15dmx0bU80TmtnbVNaSVBHTkk3K2lZbG50R3l3UXJTdyt3NU1yVw0KZ21INUdiTXY3UnZocmQ4cGdGOS93ZUhITG51N204eXFIZzBCL1gzREpZdDhYVWdPZWhSVW8xSGZibmxtDQpiYmRla2NCeE0yMTJVYmRlcFp1MG1jcUNCOXdYVjlicXhIM0FxbitQTXVHZnRhM2k3QUF5M1huWlc1SXgNCnFMS3BsOEpaSVRUa0t6MlJvck9RU0Era3ZzMzJrbG5WNDVsazM3TExyaCtXWEdzY2F0YkVJdmt0cGZQSw0KQ2xSaUwrODQ2dkpCR1ZOUmo5c21vUVFra2Zva1IxMTl1aFBoNHpCV0tUKzhyekYvS0V6ZkRIKzhEWURQDQpBeDRtOU40OW50Q285RlZxRWRKSUFEUlhnK0o3akVaVVY3eEI1UVRzTW1pVVlyc2tGNkR1OTFQK3lIMWwNCmZCbHBMai9pYUdnd3RJbE54SGlyRlhsYUxRTmR4L2NzM2N5ZlQ5QWNuYUI5MHJSSkNXTWIxdkZPTUNBVg0KaWMxMEI2OFhkbytyVlgyeVJDYjdnN2Erc0tmYjBjclNuT0oxc2owNTBweTRGbW11S2lIQ3BVWnlCOW13DQpWWEJOMnVTdEFiV2JnT3hnYWVsbm4vN3RxbDU4Uk9jWTMwOHZlL0ZmZHFMRUlFd0V1c1JNdzQvSmV6cm8NCnhsbFZ1cnp6YjZJb25Fc0ZLUmY1RmRmRDdySmI2aUVHQzlkUTNoTVRLaE1DQytIVlBpOHZIVkFpTU4rNg0KUGlxdmVmNkVmYmszbkZkcGtLSXpkWTFKcW9TNElhd0RlcWJpSDJWYnhEODhyTXpSZ1Mwa0EyeDh6R3pXDQpkOTE4a1VNUGQ1T1pPMlA4WDl4YUdQTTBnOWtDR2V4MTJTK3NnTGpOOFdDSnhMdlFuSlpEU0s2Tnlud3gNCk00V25RMlRGRmRPZHV4OHJnRE1JTmlwT2Z6dWV0OC81cmZHdVEwUlZDQit0Z3dnT2NORFQ1WXdMVDI3Rw0KU1pES09LWUFHY3dUWHlGMjBNbUxZaDFFMG9DRXl3dnZTdStoOEVJb2dPcDQ3c3N5YnZUR0U5aGdRbkNUDQpPZC9CMWhvT01XaDJ1ZXovdDBpRU5IV1AveU9ReDRrL0lJalZ2U2dHVnVjQlVXeXhYSThRLzZORGI2R1oNCjNaMEsyNmZTbk1HMkE4clVBTFY4VlQ4c0taV012bHNpUVhxd0Y5UXdESUlicFkyOGRYYUd6NnFxaWczSQ0KZExsaEppaklaVmtUTmM5cjJrTksyNkQ2bWU5K01nR3Z1cm0xY1NvbXZpYUJRR04xWjllY3VWdTlGSVc2DQpsR2tiam9GUURkYmd1cVpUSGtiUkF3ZzRnM2pQdFlWZGNGamkzRWdNNldzOG1jVTV1cHNiNmVWZkdMbHYNCnBMQ3dJVWJJYmxCV3pFQ1VhV25DNTR6WU0xbVZJMGE4dDRaYm4zT0kzZGdsS3h5cEtJblhqdjMwa2tVcg0Ka1JNTi9KT1gwamYxdXRjQjZYU2dmN0hwMm5EWFVOZkF4a0xFUlBZMHhQMEQ4aXlLM3BPbjQxZW9CMTd1DQpORWx6R25rZ2t5MDBLVTRGRjhqN04vaTlYT1J1QklVNGVPTFRzRm1IWDZxS1pSODlNY3BVclVKZ2dRaFMNClZSbU5qeDVjQ3hwWHFLYkdDSWdFL1puVERFb3dpZTRMYkJsa1FYYVRWYWdDOTlITGNRRWxkb1NyLzQrUA0KZjNmRTlxUHRibGNTZHhKUU94NUc4T3Q4eHNXeWhKZ3JQMldrT0Y1UFVPUTFGTUdkQmZIRVluL1M2VUVZDQpReXkzNEQ3ZXdMMlMxU0IzZFAzVWRWdWVsT0tmMmVnU3VXK1Zzek1XQkNCUFRYV1lLaXRrSnZTdlBWbU8NCm9XUTlMSXR3T0t4WHlSaEo5c1RBM1pYbjFLQ05ZUEVXUUZ6MG9zZkR1bWRWdWVjVGRzYUhKWGszcHVjZQ0KV1NQOHBsS1VrUndXMUhRampsWFdjaU15dVpYUSsvMEVGRlllaXlEeG52VzVMQkFuWUhpSFhNYUN3UHVKDQp6dVpvVjVFZkhOYkhrazZKRkt4YzRPZmNPUmtYS0NRNGNLWUVKSGFVbWJwZUxsQ1lmV0NZbVR6clk4b24NCmtSaGxtRU10R3QyR0NIMjA5K0Zqdjd2Z3RuKyt3SHc3alBRYTFmNGFzdWV4OFNhVytmRll0QzZIL1NJdg0KU0hmejFrTGwvcktGbDlKOFBDNjUwdlpSd0FUZkdaby8rT05zelZSUjR3bHJwbTJGZnliZWFXMDRmQm40DQpPSmN0aHlNNms1eXhVRTFPVlZDN3MwVXluUkhSbHdJVGZqdytpOEVqT3o1WUIwTXllY2FBRThpUWtmU3ENClk4VElGRit1b1FocGFramV3K3V6MkZJaGtxTGRtODg0VUF4MXUwc3Z2bFR2Q2d1YjJPOWl2djhBV1FIVA0KZnBaQy80MUtBMHJHZVQ1Y0tlS29XTkJjQW9tQ2kzWm1Yd0FxYm9vd3JxZkZDZVZ6endvdmsyUmlyUE5ODQpQUXBjZERrYjJZcmh3NkMzaklBNTNIUE1MSkNnOWh1anI2WFpmcGs3bVd4U1ZDK3JwQ0M2UUhPOURDMEMNClE4ZytyQTdjQUduVlRFdjQ3M2dmMDBPL2YyeUdmQ0djR0pwNHhlMWdHYTVxMEZydGpleUx1OU9ScmVGbQ0KRkNUbHl3dWhERG9Lb1NXaGErdHptempPZUZlVllXRldjdjRTbVEydXFXQ0JrMHlmZytiZHcvQllqUVpIDQpJdk53VHdyRGRYazlIR3NNaTZnOFU4V3Y3STZKeVhuRzFaQ0xLSCt0Vzh0SWpSYldRdjF3M3dENXdwVC8NCjhsQ2JYRkYrdkdGbTN5amFGMFBsYXdYZUFIZXhyd0ZJdUpySEZYNzk3VFN2Z085RVg0NWJOT3NVdThTRQ0KT3RsYTg3NFpsOEhQOWJsNXUrYkpuQ09obHRpQk9RU1ZveU42OEsvYVRCTUpXZFBqU3BBQmZjbzhUbDY2DQplMTNjRlRiOEpSODFZamhpRGkwM29GMlZua1RlOXB6RGhZL1ZiKzdyMXkxVTZ5YVJSNTlXdzlzMWVYRTYNClFxM0hPYzFDVzJYZEtoNmRuR3YvYkk0b21KZ0dNSlByNktpU3kyb3FFZURFYUJhMTY1RDZwWVg2elUrYQ0KN0RFZUljNGZWNm13UDI2R2ljWUN2Tnk3Q3FoTHE4SUlXeEVpNWJOcWJJcUluZTRDTlp4alQwREFSZFFVDQpTcW0xYWRDc2taM2QraFc5NkZjOXViaFdoM1ZnbVpxQVR6Qjc2cll5SlRZYWpodkk3OWNiOVE2R0FEZ1ANCnRWR3JoSW5Vb2VSVjNNUDdObFRjOFQrVG5pVERXTUFDZG9SZXBIem5OeEpyTC9XSC8rQ2dROC9QUVRKOA0KN1h2bHhFaWJnTzlxQitxY3plK2JnN09xd08wclV3dTA0L1gvdlMvNXpSdllRUitzVVZ0WVVLWGVwZUU5DQoyNC9IZjVHdmU5NUNZN1R1V01KSXdKWDhRT1YwWlB3SnZjRUlQbTRsY2RFeWtjZWVkZ1FWQlBRc1QvLzcNCjNUMjJPRlRreXFIdzcxa21qMzNsTkZiTWE0NHZydXdRZkkxTDNDZk0reWdmVVBzc0RudlNjSktzYk5zYw0KbzNKNzVIOHI3NEVwejBZeGo3cnhVenhudTh5UUNaSEY5YzFuYStjODR0M2t2WkpWcHI5MlhLYm9LUHgvDQpHYVRBVTZpZ204UDhSWk5aMlh0azRtRTNlYVFmbXRTWmhxUFNrQjVzUE5qWjJSYnFCd2Q0RUljY042S3cNCmQxRjdsdE1FNVROWk1qVjhUWDBKSVNmb3hFMTNQWGtzUmpsb0RlOGtZUmROalRYem9uWnAyTnBUTmlEbw0KR1lyd0tyeFgwVjBPRmpSRUxOV0g0bHkzd252RUZScndYNkszWE5ablF5YTlRNlY1ak96bVkrNjBCL1pXDQp0ZldiU2F5TWZVM093YnVvdlYzOUdjK3VsWjlpU0lFejI0d29GZnVLTnorL0VPWnM2d3Z1VmFOTXYreGgNCnhaeDRJWUI2a2ZnZ1pHSHVqcVZWd1FpOUVlWlZtbVpwQnIxb2JQZ2xueWN0L0FSYlRFenh0WEN2Z1N5ag0KTDBia3JHRTE4bWpRdVRLcFJOMnlKOFdzYVJLZ2ZoelpPS3pndDJCSU1zSzNvUCtQTk40N0ltVHp3Z0RJDQpnek5HZCtiTVEvbTNFa0NVTnRQZFh4b1dOdU9jSmtWa0QzYkNUNWJiZnFNbmRWTTE4d3UybW1aYVo1WUsNCkU2M3RoZ0dpK2RyM1hMNkM1NURMSmszMEhFdmZ5TGpweXp0eFBWMXlIQkVZZWpDRFpxWnNTWHF4TDJIKw0KazhTSGFjcDNQR0RJdy9DRVd3bGM0TklkVVNDTElZZHJOeGVxdVFHcGptODhGd1RlVXdSSzRoNCtPcmx4DQo0RnF5ZW55cks3eHEwT1NvdlpqYzlDRXlXTTR0M01KME1aWDV1c284cjdpMmFmS1hldkhMVE5WNFEyQ1UNCnZTY1pWdUtDTlVpR0MzdWNDNHBsdWJEODN5M2MrWlVJRlBka3FOd2Vyb0lMOGRrUFZrcnRzTStGdmlCeA0KL0FWVjJVaVk0MXRYSlpXcUhBdncydTlHVWhraVYzVzRSL2dMZmpXbkVZRmt2WlEzT0liZXpnckFGYjAzDQowb1BYWTFwOGw1QzByOHlsRS9lekRuYWN6NEM5VENWc2ZzdGpQMFUvK2cxblNiNXI5ZTUvSjNCMHVKSWYNCmFTSEZucUpzVnZyVWpGT2xTakRpRGpFZmsvdVFxVjlmSFFQMnk3NUpaWnZIODVxaXlhUU5ST0N3M0QreQ0KeU1kbHNFSU1YMzI1VGN2VytNTGt5ZnJVMlg2SlpsNXE2dXFZL2dXSVZ5T2hrSmtpQWdGNytJN3Myb1hlDQpnaDdQVnZkZWpDd2VJa0cxZlJnb285d3Mwako0UE00MGhoVUhpSW90UGRTM3pBejZ4Mk4vQkFuRmVYNDUNClpNVG5raTNxbnkvYWxTcVhZcTZYbGJqdDdqNXRBM0s4Z1BUUXRZUlFCVVd2MzFybEt6SzVTSnhZWGx1Nw0KT3RvM05Ja1hGYVZLeW5tNkpPNHByQ3lvNHU2N1JNdTI1R0hDM2djSEMzd3k0aEhwcUVheHJ1L1p0MGh0DQpqLzdtSTBucWowdnkzZWZzSmV2ejFCYXdYeTlSdG5VckxzRWhzMnBHeXA1NVpmOExEMnlBQlViajNwUWoNCnJMc3RQMXpENVBWdHFHdnd0UmFwYWwyOEEwUmxJRDFxc3M5RndIWkxDYjAxZ2tPWWw5Y1FJZS9CcVV4Yg0KWldIUHZqN2FRY0xvalVqay9mZlUwMlFEQzFvRCtGSkZla3M1a0YrKzVjQllBSUVwTExVdzVRUEVMekQrDQpTKzluMjMwY0Y1SVhMQzQyeE1HbElHNFpjMlNyQWpXcVVvY3BrcFB2anlaN1JoUW1MZW41OEdlNjdETjQNCnVnS2YwVUF2TVhWWWM1Q3Z1RnU5OHk2NlRMMXA3ajhyUFZDWkRTbnBJWk9GZzNCRnFTbk1Da3pzNVV6dg0KbGlNU1ZVeVNmend0ajZ2RnlwbDZnQmQxUmk2Z2ViK0YyZ1RaU3RYd1JsL0VvYW45ckRhUWZiMGExZUwzDQpubFVqMGJ2czdOUTFGNGM0Yk5ZQlhhVmZJdUlhQzRCdlRZZmJGMGR4UFNObFlwL2U0VlZrRjRNMHYzUDQNCkhvc091MFh3Q2RYRG1HZHFWT054MHR5cXJzREIyYVpwWlpoaFdtb2JvL3hEYzh5SHZhdjMzMFhUaUpqaA0KUHVqY2JWRTFUWU11MFNyMmwwTmtUK1hZZVZpZktsNUFsZ2ZPTkFXK0NUa1kwbE1wY3g2bmFxV3E1Q3lpDQoyZTVJZ08xV291a1hTcG5rcmNhb2JweDBIZHo0UkVROE0yQ0JxdnExb09FbU0vZ0h2TFNkTFdyTHpGV1kNCkJEZzh0SzhpSzRtNDJDZ05HbXI4NGdOK3BDcVBaZk0vQ1RoUS9ia1pBeURNU1VGM0RpZ0pydUlSRklERw0KZUhCbjRjN0ZQK05sUkVQaWJXcC84U0VWOTBHYS9mWnRVbTdETE9zeFE4dzZPRWE5NjNMZEM5MUcvTUIwDQpXY3NZRzdhdVVzZGN2R2xGSm9sM3lJUkhDQUh5UWg4alM3ZnQzQkgrUm8veEtpR1VxVzgwWDVOU0NUOW4NCi9oNXZScmpDaXgwdnJQRXRoSUtYMmFWYVA0S1ZCZVdVa1RuYm9uRW0za3RmQ1d5Y2E1UXFRMlZpcE5iMg0Kc2c0cmhFdVJsV1lNSHdkN0RrQXN0OS9pdjV6N0h4ZHBXRXBEczIwRm5UNzlHUVNDVWdYRFYzN3JvUEJDDQpYQk84UnBEbWIyUktNT1k2ZEpXd1g0UXc5V1R3MXY4My8yTmI2VjNyTmJMejlIbWhrbGV4WUdNVUNjNlANCnFJdGJyOEt4akptVE5OVGgrR09CVmRRdXJIYU9pbHo4aDlxQ2lXVXlLbm4zOFZYKzdkUjcrTUl4Z2V6Uw0KZnpvejYzdFFGZ0JTc2pWblkvRWxFUUZRLytSbXVMdm9nV21aejBFdllSMWhudG1FV1VLQTZ3OXEwcjltDQpQT0hQRkkvYlo4ZllkdTZvQmlEZHYvL0pmdG1UTWRpVG16aTFzTDNCNHYyV3FoQVZLY1lUaldUSVJiSTYNCmxKMERNSDVBSk1Qa3B6L0FuZ0tnWXhaTjgyS1lOSGludmpOWWxBam5nQzJlMWxPeE92YWJJRG9VNzFaMw0KRkxyK042eXZ2cUhQT3N0cmZid1J5RWd1NmszYzRFRTNRNHRLL0JNdFN2RTBFcHI2Qy93U244ZzlVdkNmDQpvSkN1V29IVE1LQzJaa1BGc3J2eHF6Wk5saWxtN3V3elJrNkhqMEY3YUJSNXBHYnNUY2o1OCs1WGxCVjINCmJpMElmcng3ZWpmTnJxeXFXSm02U1pub1lnM2craTM1SE9MRk1jTkZ4MklGNDZNdGFoS1dreWFaN0I2ZA0KVnVwS3dCN0RkS2ZaR280UThwcXJwVGVtVHV5WE92UEJ4ZVUxWUFXVjlOSlpmem4yaHl5S09UMEg2cVdhDQpPRUZncmxaSVJ0eCtraFEvV09QKzZTamZCNWFySlNhMDhicDF6b0RZN2t3RThhUGE1M1Z3QTRFclNFcnYNCjYyQ3IvQWJ5OEI3RjV6OTZ2OHJYdWpHcC9TWk9SekI2Yi8ycVRNcmZxWk9XaHh6YTcvZVFwQ3JqMUlmeQ0KZ08xb1V5aU9ETThBQ1RFY0dXcC93YXh4SVR0eTRqWTg5SDMvSzFLdXNweldwZUtOMzdKcDEvT2NDTXBEDQoyVDhkUmlmb1pJMXZRbUdncUk1L2kxM3k1WlVKR0x6aDRIcUo0YUlqeWs2NHRqNGFZbks1WGZpMm9zWFgNCjJ6MFdveEtqTHNuWmZySmFUZ3BsdUtncHhkUFZxL0F6MVVoeXlURDRzbmZhMk42Z1NsMk9XVFhXR21SQg0KQ29sZzRzbk5LTTl4OVR2SlVCVDUyNDFMWUFyS0RIbUgycFI0WDhONEkyQzZjOUxwU2dWRFRYdHZVN1ZFDQpGWURldSszWlJwbWEwVWFTeVZISWtTVFFYZkpjY1RacG1IME1yeXVzb3FuTVo4MG9XNk5GUi9jdWFUTisNCkFLM250QkVuNGZoNElEWVJhRVFVQ29hUVVOSnY0MStyMlJSa0lTTnR1NW8ramNhTXpmelYzNGVQWUFEbw0KNkVGVDR2cEJXWDVUbGVENUlTcURqd2lkTWppM3hPcHRJWXhKRzhQN0VQbHdlSXYwYWNVS3FvakJ0a1IvDQpNMmtGN3lScGdlbE1JLzJUbXZjaFFmbitSNzVPVmwxVUhIU0ZUTHp2b0tMaGZhNmkrcjRlWmdCa1djck0NCkdlZHozbWQyOHQ5Tk4vRWpubERpNnlhTThEQU8vOTVWVlVDNVl4S0daT3ZGN2lJSjdKUFhINVBhY0VsYQ0KNys4VVJhNG5QWXdBbEZSWHZyL1NvUTNFdkdCTmhZU0Yrd01vcjJjL2tTajZNcGNremVLWGVGeGwxQkFHDQpicjkxZThJOXBTcW5MOEQwc3I5cG5YUHlnVk9oS3BBcGRKa3lETXU0RHNnRXVTZ1JGeE1na0tHSWF5cmgNCkFpWkF6OEJlZjFKMXVQOThJTGVZdGdoV01KSnJTTkxiczJQZ04wbDFyZlp2dmVFMytsM2hZS0ZCZkkvSQ0KQkR3WFJZNThNbWptSE1nTXJ6VkJIcGtiVlVQZUEzS2pSUmc5bm1sZHJSTVZHVkRGOG1JaVpkY3A0VjlJDQo2aHNPYlFzWjRETUVraXdPY0VmdklvNURaVGtNbHZLbEMvZUtjbWhHb0RzUE1kVTJoSjFRbWJ2QWZRck0NCmdBN1RKbU5jT3RWVEtYWkg2bWNmVExiZ0FZL3lHNk5abm10VHNCallkSDdyT2FNVVozWGU1MG9JSmtRbw0KdGhtV3A4MEU3YVN5VUtXRktVcThrN29wT29BaWRvMzN6Smh3djNzamMyYkVhdW90WTdKQnVJS0NBOExsDQo0S09qWlY5QjYzaUtxUWg4bFNyOEw0OTcyUHFIMm0wQ1RWbHd4VHpFZTZwZHpUdkRSNWZVM0RpUDE5RVQNCloxMDYwZGhJdDNYTGxLdklrMElOOERONkpVYUN4WlBrR0NLTHlSZlJNWHZJUlNYeCt5S3k1bkZ1TG53bQ0KQjkyeVlDSnpyeXBXaG1teU5vMVdUU2cxU1NOREtXbW1hRG1renBYVjFId2xOVnYrdlJlbm15MWNlUE1SDQo4eVhzOE5PcUtiSmRrSGFUWUlra0V0Z3NiZElpS0ZnT3VqaFF2RzZSWnNvSzYzQ1JzeTZJaElTSXVNWFQNCnpTcUNqZ3NKR3BYbXNBeE1oVnlLd3hxa0xLNUhjYTE4dUhQVGVmVzh1cGlVY2hKTFd3cTBaMW1OSkQxUQ0KYU5UdjhQREttckZFTTZ5TFFYV3ZyK1JuemtuZ1hRdTlGazU3YVgwNVliaGszU2ZhdlpxMEFUcGc5YS9ODQpBUURjNGFNSjVJM2hLa3dwcE4xa0Z2MUE0d1IrRnFpNWtzSjZuazMxNGE5cSs1OUtVNTFPM28zVHhVRTgNCk9NQm1ka2lKMFRVc3JXMW43NHlreU5ETmVYTjZVeTltVS8zcFdaZkF2eVFxQm5QbjZqN21mUURnNkNTNw0KU2EzaUdtNVJMWncxNHVCRWkvVnZpdkhEZ3Q3N2pNemFBSUduNnVLTTVuNGxJZEZmNER0QVZCRXhqd1BqDQpjb3VYbGxId1R3T1FHYmdSQWNHYWU4T29oeGF4SGV5Q0xhSFhYRXlVbElzNTVwb003ZUkzWk14SlVxWnkNCjNIYmVaNzZRQ0Z6YjV0MGZOZEN5bVNCK0hGbUJtK1RsT2Y3OUQ3WTJ4cmxHbW16aDNJVldIb1BiOS8yWg0KbFZZSjViQ1I3SG5qaHNUUGx3c0VjY1RTL3NOMzdDUVp1RUViMnF0T0JjWnRwWVI3YW5XRklwRWVFeXpFDQpXYUU3b0dROTcxNWRaTWt6ZnRoQUdtUmJBWDNxcTNFNk94VDRzOWlMOTVtMTk0WnhoTlJKZktnUzd1ZFkNCksvWmZwUC9hdjVTb21OQ2NlQ1RqdjZ2KzlYRWkzSjdTUnltaTJEOUFhbUEvTmpxNEMwT0NpOXpQZ0NSMw0KQXBpbXJiWEdLTjZLWWVqN3ZaMnduNmI2UHI3dkF1SEEwK1drbS84T0FDRFc5NFI5L2FuOEpYT3czT285DQpKSUZzSGo3VFJpVXZsSndHYWIrMGxCMFU5R3ZiWVI5R296bHdhS20yeHB5TnpFN2ZCMkV2TUUzSU14RGsNCkpJL2w3SHFVQldMQUFUMlUxVFFiVkV5TmRrckpsenVVNEpMcmg0UU9FekxoM1psMUd5ZW1UMDJpK1NUNQ0KYUVZWnV4L2d5di91V3o2MU9LTzlNNzBIM0cyWEZPaGxlYW1aRk4rcHhDTHp0cmxwUlk4MGoxRnRzOVUzDQo5SFl6MXZGUnlBOE5xZmQvRXBTZDhxTFNFbVNkSTNDTnRUZGtneHBWblY1YkxEUTcvbGdVR0lVNkFYWjYNCmRLRlRwNGRBaXhxZ0hXU2R2U2NrTkJ0RXBHNC9Ddit3ZnljUFVtNDladW9jVjMzc0ZuNHMrYzFOTW1BSA0KQVlHWTlCSDZNV1U0bFNwMVJhQkIvTGlZMDJyLzZzQVdUOWJXQVl3cWliZDVmZ0Q2ZnJQR0JReTBlM3hJDQpaTjJMMkdPUWxsdnNRNHdMM2I3VjlhL0tTMDIvZFo1OU9RNjlxZVc0UWlDYjdUcWtqazBwbjhuaTVYNmUNCkFsem1Ea0NSMlNrSDJxMnhUbUFjVVhPODI0ZG1GMnluTGZzT1BaSWxEdEMrSDNiMVdDbmF1TEpXM2pkaA0KVEJDdHNYNXpDYy9SKzcrN3lvdW1JSlFjazlvN0JyL0JqN1hwOE9ESDF0RFVkSW0wb3ZIRThjbXRvbk1iDQo3OGZBaHJxM0grY1NsUFlxSFFPTTVyL1ZLb3NjM0cvWVY2MDJ6cDY2d2Y4Yk5UYzFGVmF5TGZRK0xHanYNCmp4TmtSY0FpOFBwOHBBWm1zcFlWMzBWdTV1d1Y3TmFyZVUxRGl1bytDNjVPT1NkWGZFbTExYTRUQTFDUA0KcVQ4NVloTHJHUm1XdGJ1NkJ1ZlpkQ2lkdmFEbThEQm1JQ2NoTWNvUEZpSWU1ZlpPd2pPWnk2dzZ0TllCDQpjNTBKYy9HZGNLUTFaWjZTakVEZm9sM085V0NxTFR5TWZtWW5VckJ4bjZvSERHc0tFUjVYNFZNeGZLTjkNCkJENkIvSG44eVkyN1gzTFFrbVE0VnNlVHgvdVV0T0Y5SUVtNzBWMEZFOVNOZmozTjJ0NFFUY0VzcmdrcA0KK3BGZkVTMytUc28xVDRNK0pBTzZ1L2dmNXRqMDF3a1BWM2RqUHB2YVpsWUVnOG9OaG4xdjFrSVYvNmZBDQpDL0tHTmR4SzhPd1M2YnNHbVJneG9VeGhnQnF6cmE1eFZkazd0Z3pCeXc2djNXRFoxVDg2N1dXeUdmclQNCk1hY0RST2xZR1JlcHdlWFE0M3JvOXVJZDA3K25ZWXVzSGx1alFJZ0FPL2FWSzdIMmVTS1ZpZDl4dkVCag0KM2VHYVlJUE5KR1VCRXQwbDZRZUZuVVBZbkw3RTlZbldwUXRvUkhBa3MvaW1DSjFZVVZzZm5xd1IzZEh2DQptQTF2MVlZR29KbG5VMVVZKzZzMHE1N3NQeXRYa1ZENGE3SThxNnpUVXMyOUwzV0VVeUYxcWJYQ0Exd1ANCm95ZGEyWk5idFdrWWRQd0NGY1hmQkVOTGJJdTN0L1ByUGZ4TUpOUVdIOVZjSEdhTkdDVnRWNng3S0IyZw0KeVJTUkEycEV2ajNIdUlPVGZBTmgvcTFTS0FBcytTQmtiYUFvaUNodEIyK2Q3c0Jpc1h2MHNpOGVpWGZLDQoyVkxiSWNob0FvUndXUC9kNHQzcU1kY2E0TnpzeG5iMm56VHBDQW11UVlScEZobzgwWkVnUGhHR09RblYNCk8yU1p6bnc3ZXJzRmROVXpobHpXSm5rcEtkaVJNVVZRalhMNnhIN3l2TCtPR09zS2pLQXIxK2kvdnI3Kw0KU00xOW1iTTc1SllOdHhYZVVqaGl0bFZBNHB0UW1CVG5pdFBDU1A0RmVhSmoxVDY1OHIvNEhDMlJmc2EwDQp3WjdJTVlEYXZrRzVEL1RMNjFSelZMVVFLaWlycnVia24xUThHZnd4cjJmUE1PbnV1cm0ySkZwaDQ4Q3QNCm1iUVltTDFQSGw5OXNqekNyZk5uOHZwWlVReVViakMzSGwrYXgxQkV4QVJhb3pvNGd0M3JqZTkzYlFYRw0KTE55TmR1NlhhdDBNVU1aVXo0S3MrQmRIYUVqRDhXcldoVU50MWk1Nkp5WTREbDV0S2hQSUtOWUEzV0VHDQp0aFdGQ2hsRnhvRzNRbk95amNLWkZ1dDBvNWdjbU1qckppUmlLTHltcXQwbjV4SVc5TU82d2hqNzNvVjMNClFhdHhJU0pXQWZHL2VwWnZta0NtSE5TWFpGaFdZaFl0N1RyZWpFakVDY2k3RmlXVUV2c2JzZ2wzSmxKNg0KRkpPZEpqK21qcjROdVVhZUxQa3F2bXRidVFKQmRqemNzRUY5d1h1b0tKYmhnQUpGUVRWaVBENlJuZGlnDQovVDMyWnh4L0dibVcrRS92cWpSTXpUeXlrV0NoYzZReGY3Y3lrZjY2ek5hbUZmUmI4ckptS0ZsV1BzbmMNClJaa3dIUkRGVlJlOHBjWTM1WGw3L3gzbWVrYmZWRER3dGhsWU5XcUlTVTF6bUlGMUhYeFJQRzlqY05aRA0KUnZmcGFjZ3drZVJMVE5JblgvS3RoWVArOXAxWWdXRDhhemNUYlFrSW1PeWlzb2tjb3hHYzJpS1F3Vi9BDQpKN3lncm1oRFpzM2MwZTVFTXFLUVNkNkcvMFo1V3dmNDdaVDhrWEQzV3k4L09QanJUVUVuaWpyZ3pCOTUNCjltc0ZNWVVyRy9XSEdKZVBneVlTYkpVY0JhUGlmSytsQ2lnQmhrYUlESStIS0g4UE9XWXZ4OW9FTXNvMw0KZnppQndzQzdiZjhzU1JBNWV4Umxvb2xZWC9mSjRhKzE2aXI3bVVIbFdoZG1mZ2FnejRSU2h3MEZENWxYDQplalZsajFEc0ZybEtabnNaZE9Ecy8zV01pb3pWR052Sm4vUGdZamFZR3hubEwyTjBtOGdrVWxNK2EzS1oNCnpVeUNoL3A0clpnbjhWQnVXMEV0cFA0L1l5dXA3K3hRMFo1K1BxVkV5NVl2Y09hSGhUN2NjWlppcGpoVg0KYlRQckx4RkpFeTI3ZmhPL2pWNWV2Ny9nWTgzQTluRGlranByaXdiMTFneU5uVVJEekFUSE8wN3E0Q0wvDQp0LzdLSUlXZWwrYVYxMWxzYXJTckZ2VWY5cnBobzQzTWF5WFRwclkzU3FDcEpnRTNadXdZK0dTZjBHUlkNCjM2QTJ4ckVxMTlrTUcyVEVFQ3o5ZzZsQThxZXVQdzdXZnlCcC9OblpleTcxUU9BQkt6T1F2WjIzVFY5dA0KRDVHMGlXVms4ODJaOUovMDh3Ym4veDlIK0w4b2JzYVhaaFp4UjgzeVJSdmR0WlkrRUw4SnZDeWpMRWo5DQpBcm5IbkJpcUgzZGNzL09GTHZPcWJ3Z1U3cHRybGNFNFNkT09LYXp1c2pyWnVzZGFZMjZaeEFBakNQbUQNCmFSdXVleEM1Q21qakxwSmdTNFUrMUo1TVNndzNTVjR4SEhuWXF0bnErWUlKTzE4NUUrb2VXcytjc1VCZw0KR1o0MWRaTWQ4MFhERWFCcFJjOXJtbHBhdndIM01zazdWNUZaQTFCWjVUNTc3TFM0L2ticzRJSTYzMjhrDQpNVFpNRngwZTJEeTRwak5ucnZDY1loc25USUh3QUxEVUZ1Z3FacEo2MjU0bzB6R1lhc0Z0TFNhcW4zTm8NClVhM09jMGdXTVJDTDBDa2ZLT2Fnc28rTG9Wa25wNk51OG54Sk5PVWVwdEY2SzhFdTcxbTUyOFYzZXllLw0KK0ZEUjNWcUkydk1pRUpUTk9UbVBka3FTUEJMVi9SM3BmZUhtVUtTdEhTc1NKeXNla3J3a0kyZjNHZE5uDQpZdDRYMG84ZThrQ3FEa2FTMUZHaGpJbHVWODFyemhhVW82MjgwUnpYRlJvOXMyZ1V3K2lLNncyYmdQZHANClYxTUx2UCtjdk1CQXlpYncvREV0MVBkU3gxcnJyd3NOTWVacUtRaE5ocUFReGgybTZuK2lVOEx2U1E4MQ0KNlNGWGhJMkp3TXVtZFIxUk9lSE1sdEVubzg1V3VQZExESlRZNk1XRXlXMDVtMUY3RzhJWXdHbjlkdldoDQo5cklqMXc1MHYyWVRiejR3WFZQZTUzWG9WNXdaTDcvS3UreDZML0M5NHoyTVJXRElHdUhJU3JYanhuVG0NCnQxTGZZR1htOHIxa3JHT0dBUEd0UDk5cFduOFY0dkZCZGFaYlphYjEvQi9yQ285Y0x0czdnREt1MmRKQw0KcC8zOGZjbDVyQnVPakJjTytxKzFiaG53NDc3bm1NU0Fzci9Yd1E3STBqK3cvY3NQL3N4ckhUZGNxN0pUDQpVRkhzbUdKazNCeXNXREN4Zks2WjN2Nnh0ZUZyTjUxK0xtMHNDdG9iL1RIS2k0b2FoUlJvSnE2VWdFOW8NCmoxcENqK0phT0ZqOHEvMnhLZWVjOUFjTmhyR3p4OHYvT2ZuaXpyN01wTEFqNUV5UGRCQzRUVSt6VG5ncg0KdzhWYXlTbmxlWHIraWNLUlF2VU1PRlE0Z0pzd1Y3MlpPZmlKU3BhVlBkUCtXM0VlcW5MM2F5a01aTm5mDQpDQjRMK3I0Z3AxSEJ6MmtmWHpyZXZrZGJtSWdQRnhwS3EwZFZMOUFTaGlaOGZkUThwRjl4ZUgwZ051S3ENCnV3NkJBNTFmWmFTejk5MCtWNG5FVFdpTmVaL0VUbHVCQngvSTZMR0czZDgwdXF6L3JiQ290ditpNGRjNQ0KdTIzUUtQb0hOYTVkamZ2cVJtYjFoTVRTYUdXRHQ2TVpBNkQ5N3ZnTDJ3ZTVEMkM4TnlqanRoek11S0ZkDQphbFZnVU84WUdvRFM4UlRvRnNuTFcvSlJYNzhMeHRlM3diMmZRT1RBaENVTE1QTG56YkJDa2kwR1hUYTgNCmdSbWxiVlNVL0ZSSU5Zbjg3Ri9XWEhWaG50YUU0VGM0cjJqWlBkM2EzY1hRT0NVL1liYTNnVUcvSVNTaA0KeXRMbDdyWWRWVXI5RWlMVDdXQVpjWG5JS1kvbGhGeDBLWHBUWHp6K0lKZWdDSW51WkVMTERmYktBb295DQpUamc1NkptUWtEUHk1VCtZcVFONExGY1gvSkovVS9pb2l1STZ4Mmw0bGRTZHg5OXJhaXZzaVIvTGg1aWoNCjNaSVhxUHlUS2M2SkI5OVZweERxYjJMT2hWZG9JY0FOaFFuS2RkZ0VZYm9CYkRNUU4zRG0rU1B6ZTV1Zw0KU1JPWWJaN3phQ3ZIZlJ2MVZzT3RvWVM5Rzh2amZ6b0x6TVdiS1ljZTJzUHBYNHYwTldrZmh4Mmc3RStFDQpzdUpOTkVxRXBSUGFpd1VROG16Y25vK1A1TnhlWTdPKzZlQkF3dHVIR2RGOUFmNkhJUXArWmRtSVRKMDkNCnNGSE9lTmVTaEZGZGxtRTRXaEpOTVFCYkZyUlp5SkEvYVM4RXN1U1NJcHUwbU1QVHN3N1g4YkVtYUxGZw0KZmZORjhpZlNiZHdPWEFNQitrc3hnZlVzYklMa0J6Q3kzTVRBMmZDUGJzd2c5bzhOYUtvRVFJTHZCWXZLDQpuM09CdzMzUHhqRGdDUWI4MkNYaDBwRUswVzNUSVRPZVN5VElURmkydWxObjhPY2R4L2ZjWmZ0b0JuK2QNCnJENEkxYW5BNzJXdmFWeDZNanFEV0c5ekZqSDJZbEpCanZJcVpyRk1uKzZaNC90c1JFVXdDQkFkdUk3ag0KNU91S2QxalBhWXNQSUx0ZjNtY1U1blE1cTlLaDM5MkR5dWtEdFpXNGlSWHpuLzdWME92S3NTeUFPWTBEDQpHZnVwU1krTzZIUEpzZHkxczJaakFFejBmd1hIb0VLeGc4Yk02RXNOMm5kNmRIOUxjNlpPZHRHUktqNloNCm5DQUVPM1MzWEV4cThjeWVXOHRuMHdwdlhDTmF6QXlHUDhKdCtBSk55RFFkSWY5dTZPNUZhNGROb3VTNA0KR21aWkZya3YxTGxxcjRySG1NUFhic1g5Wnh5b01Pc3l2RTljQXlCT2FUQ1FIZ2UwYXdnT0dGMjU3VTlvDQp5aVRNbHpQOEx6ZEJ4akNRdlRsMEhDTllCNjFWVnFvYVpacnJ4UjFNTUlYWG8valpYNnJVNnl0OEVRTW0NCjBpYmNjYkV1YVJwWVptNndhZDNEV0ZScFFIcDF6MURHcG5qbUxyWXZ0TFpjaXdnQjZDU2dLUXhGRkV0Zg0KSW0zWEtPSEd2TlVjaTRieHNXNkR5Yk5YNVVBeGxPeW9oc21NZ05TTmYxRURsdDRycWN3c2J3d3NRVlJBDQpkdk5WM2hSN1FHWU1FWjcxTWhSUzdpU2R1ZlFjcStPVDBDUjFBci9ReHM2eXFSOTFFb2xnejdvL1VjSUsNClEwbC9FZmI1TjdzZ1VKRzNnZkc3RVF3dmo1eTNOOTltanBpVnA0eUFHOW9pZnlTaC95cmxaNkZIdzlWdw0KV0xlZzlFdnRwNlNDM3ZrbXFSL05kZTBrVzk3bjNLY1pCTldod1VjNzhnTjBDbUR3dHhiQ3RlNU9qRWJ3DQo0QTRSM3JJenhrczVWSDN5WTMrQ0VDNmhWOHhrbGo4Ym1pYmtrQmZtMkUySnFIaEtZMEp0OWZWTms5Wm4NCjc0WkQ1MzFjakMwUUoxcnN2eHE0UXZBdVdCMU43c095MWJrSWFFK090QzdWSSs1NllTL3NlRHdMM2JuOA0KZDNkNnZiaFl6OU9zSW9OY1hNY2tMakd1YWRPeTFYcXEzZ3FkekpZTTFyUC9EOUphcjkxTmRRT25xSjkwDQorMjh1bUQvc2hCNEhkWnNHOEdUY2hOa2VTQWQrVXBlQ1g2UzBlektyL1lNZXFETlZYZjVoNXJ2SzhIOWgNClFjQjRyNEd4TTB6OSs2UHVNTDNhTS9IakxRRHhxS2FGcmRLQW41eURsamhxVDQwaGhQVVpUb3hDYzJoVg0KeUpmOFlQcE5teVVJbjhHZDFMcWE3VUJDRHVaUkNhcjFWM1JOWjJZVE5CZTJwbWtON05DMnlBdktvSVV2DQpqemhEaDUzQ2RCOTQ2OVJhREhwUS8wZE4yajM3SmczUkhhS29nUzE3LzBLQzdoeVpFUHZ3RnJ6dWpqZ24NCk5wOXltZ1M0Q2dwc0JERFZpRVpDT0NFSFV3d1dobFR2enJHUGJvOEtNM1h4L3p4OUV1ME53U2t5a0pleg0KQnFKNFhGN1loczF0QzNuOTd3b3p5cGxvaDdYTzFrQWoxMktTakF3S1dzWXU0RkdhSGxsUXQvSmhlaUNoDQp0dzA0RlJMbWQ3Y04yemN3TnEwTklIbCtJVjJFVHYycFJiZjgxSVFGL0ZWTFFSNng1alVvRGw1ZEhDeVYNCkxoTlE3cWJ3a3dwdnBNaitERHJWTzVlc2dydE51VkQ4ekJheFcrNTVIREFrRVBuNmNkaXVIVFBwVFBEWg0KeEhBNE5ZellLRnI4ek5DK3F3Y2xHeEZxeEtRSmM5RHdyWThlTit6ZFYvQnkvbFFIS1lkMlkyRmZVZmpiDQpoaUVuUitRaEhUZlpwdHBOVzFDRjJ0S1QyeVVCd05CUENlRGxML2xrZHpUNTJ6REVNdW1lSXZWU0FhN2YNCktZaVltQlc2d3RIeStPWll5ZlpuZGQ1Vi9BYmc0MC85YUt5dG9YQzRPNWNXYmUyYVUvaGVXMGhkQUttKw0KUDNFSWRXZnFBSEwrM3h1OXR5Sm1kYVIweUFNREJteVVYME4rbEpjQUxLSlpMdm5JZWd1b2lCOGJQQUUyDQpCN2FwRjlINENnQ1ZnMlZuQ2R3VzRCNnphbXkyUHpHVk9PRGl0SjV0TzgxOHV6Z29zRUpXTWtrZDJlZUQNCitMQkFnc0ViZTdMWk02RnJ0ei9RRjl6UWcrOHZGck9xMStsQTJQWjRSVEhRSDAwdmdpZlUvVjVmc3Rpbw0KKzFHSlc0SE1HNVBEbVY2VnRwNWFuaUFjbUUvMWRqQjhPd0gzVmJzYUNZS3JDcnlmemZRVEdGdEp5ZVBHDQpQMHgrd3hRWDVLcGRoRlZaZmFYckVhbkYwZWdBNUpka2JPd3VlUU1QTEw1cFBPbDNTeTV0YkV1enVoZHkNCm40NUErbW9oMk5rYWZ0ZCtvQXo1Y1Q4OHFSTkpxYzJTN0VNakxqSHpRZnFJUFJZQnJkMER6MDMwelhPRg0KRXN0blltTUFna0hOd2lEZUZLQ0h5cndyUEo4LzdaMFlnT1NwVDFKdWxYbVRBMi92SmZHcGp3MG5zT1lCDQp0ZjU3dUw4bEZ1NEJJcDI5N1NXU2REdE5QWFhNVHNucldFaW9XRzR3c2xFRGwyeEZWTXpOczhMOHFHYzMNCmVpSmlHVjI5RUhwREJTSU5hOWVmQzBIbVJjVU5QMEpSdGhrNlNQMStOTy9wUVRwaXBudENNdlZXcTF0VA0KbTVYTFRIL1M3M1F3NEFrQXV3V0dwYTFsK3pJTXBHQXRwbFd6VlA4dC94ejdXam5FRTUvclI4MVJ5WE40DQpvR0o5T3MxeWNqeTdSWkVZVGlvQVBIMGMralE2YmwwSHRDdWZCWWZUV1p2OXg0U0R1eUJVQ1RTNGJ1dXINCmI4dWt0RnJydTcrL0k4ZU9VVkgxb2NxODI1QnY4R05xK3BCbzEzL2RPT3hJL3lQdnJ6Q1J6SlN6ell5Kw0Kb3ZPditwWmlUTmhlRWl5R2Q4N2NXKytVYlp3NkxmSXM3ZDRoSERuVmgxOHNLUGRvZFViWVBsdDJSVm5WDQpiancxOUtHL3ovQUZIWnFSTGRlZE8zUThHcmJqb3B1NFMwU0JPalgxVnRmeXIvQVVZR1JYZXNmSWR6dkcNCjZUTExuSmdtZXVSL2ZDUmRCd2crUDZ4V0dpYmw5anBZNDZIMkdON1VlQzIyV2Q3RjBYN1czNEY2c0RmMw0KTGJMbXpJdEdsTGJRR24xenI3aWU5cTB4YWZCcjFsZy9XVTl4SnlaREllRWJQWHBKV1QyK2FwRlIvYVBwDQo3UE5yb0h3OFk0ejlWeUxxcUIvbjYxSGFIejVBTjdqd0Q4bEE5eUdvaVRXQ2M1dmF0aENERk0xV0RFc0cNCkJYQkpkQzViV3lIQjErbmh2b2VZS3ZPSjlSampFWkdkc2laUjJmclU4eXRhbGMzUGFuUExOTkJrWStwcQ0Kdk04bkI1SmtWSllWeXovb0Y3OUJ2b2dOSUplREJ4cFhyeFdUeGI3cTV3c1lJN0NRcEplbEkzRXI2T1piDQo4cEEyM053dVhTNVhzakIxL2Z6UUVZY1pRY05QSFpmUVhGcTdFQURnWHVuVnRLbXhNNW1QVE1Db1lRdUYNCmdZcDBBOGc1N0FMaWY2TG8vNjlDWjRpSjc2aGtjcUZMRTEyNlZUaUh1OUtPMXlXRnJyR242OE83THQvYg0KYXlBUHdXRHpzNW4yMSs5T0gwTmdsVHdUMHVpTzZVMGVOVURVYVkrdG9oV29wL25jYkxLcENZL0gwZm1yDQpwVCtGVlBKV2FvUFZGcThmL2pXQ0Vwb0JZVVZTOVk1a0NNcFNxQUxpeW1GV3JpS0RxWklXYnRQeU9QSm0NCkduN0p6MXNBTDJkUkVkZnYvcW0yUnc1YVdMQ1duMXE4djZObkVPWTkybnBoK2FuVGpjdjkrbVR1U05sMw0KYnpBN3FHNU5WYUgrWTBmaGlieDNwU1JzZHJVYTcwSndUc29RZWxzTGVXYjV1akIrODhXREZTa3N1Wld3DQpJWTROU1VUWll1emFJNG04ZkR3L1lOVzdTRWJJTWJLamhPb3dkTEpnZFh2SFJpdzkwRVR4Zzl4VkFZbTENCnVNbmJXSCtUZXBpU204OW5Ydkh3VGVqVzBhMXRqUHU1c24vY0xWTmlQc1VMejFLRVFjQ1ozQXJLaVRvNw0KU3RNMFpBTnEyeU54ZWdFcUNhVlh6NnRMNDdEM2ptQm9lTkRidGJyUzVSOXlYZUxRUUE5L05WSHBwSnRnDQpXOGhhUXlOUWxXSVg1NXlBelVKOEdROFhCeVprYTFWRjJJREk2STdIbTlnRm5IQVBoMGNGYVU2YXhQOFQNCnR3K0VETUMvOGRZQktXUTdKRDdaVFBMU2h5elBRSjlDUnBTTlh6YnA1Q3RtRURQWStqa0x4WElKMFBrSg0KaDRsRE5hQmJNV1NLd3J1K0toVk5uTGpNcXNnZ1YyNnkwckIvaEtpQVdRQXBpbFNmRXljZVZ3bURzdCtoDQpzU2R1K1JGenhCMVNVTTdwb0NSNE13UjNFNEV6a2YwbWNTVDhmYzE5UStzTFV0bVJETXkxRzRBcFN5Ti8NCm1zS3JTSnkrU01VUmZGSHZ6YVpLL1U2V0tEMm51QjZIeHRkWDB6UExYWTV6NFJZbHlrQTU2TFVLek1vQQ0Kc1Y2U0NIcXFJWTNyaE01YllIcjFSblJzeUVNZys0TEl2VnFnbmVRNHY1NlhSclg0dWxSMHRWenhLaUxTDQpnemJRVjlMQkVvQ3VGaXRueW1sL09xeDAzNSswd0Q1SWZkS1dRZnFBWFhtZEoxY3VqQkRGRmpPdU5yT3ENCklvQXh3R1hNTllNc0I2Y2VmcGpGY1kyenhSNVpWK3U1NXplSFZrSVNXaFU2WXVRMWJlV2N0RGljZm1acg0KWVl0d1RERituVlhib0RlQ1dTRlN1ak5YTGVjcDNseWNSWjcwd2pSK3hvZWszTXBUb3ZKWHRnRWJRb3ZoDQpOcTNKYWZRa2NzNHdvVTNMSjlUUnJwR1Q5N01hQjc4b1JCd2RsaEgrNkdmMFI4d0RUMHFNOW1Ic2toSjcNCnN3NU5IOElBRHRVT2F3V1N1QzlpOFNQYzdWZ1pZZlRLWFBvdHYyMUlQNFl6YUJtSWFrVnQwQ0NVRFZieg0KVzFTL0dhTzljeHpGNUtrVjBJcjQzNWIvWlBjeWlUeURLUkhJdnZWMHkvR3MxVUlFd25pM1FZYnBtTWFjDQpuSElvZlh1SllRNzg2OHNUcDFSVitSeHl6TnRBZDFtUUZWalE0QVU0VWJMYTdLOTFhZXNOMitRU1NJdEsNClYrMFRHa0F3anNKQ3kxbDI3dXNLZi9rZGQ5OGdSb2hTblVYcnNtSnJVVmVGRk1CaXhndWJKVFd4VisyWg0KdzNtYXFORjZaTG95K1VGTFg3eXJhNFRqclhmMnR3TU1vMnJpa0t4eGRTcmFFMWJsY2xwclNzN2RnUnY5DQpFNEJSZ1FoaC9zQkxtU2Faa3hzUEVkeEV1NEpkeWRTQlgwMlR1ZVNNOTRGSm53KzlvTTlFMkxnNitXa0cNClJQeDc0WGp4YlNtUDdUd1pnaDlnaXluRk1za3FRaDZtQnhSRGZKbXdaRnQ1QkMyVDkrQVJYdTEzQTZhZA0KTjRPQkgzYjUxZnFoZGVjeFRXNmdhUnUvNmdDTU0zTFNoQzRCNWVWSU1acDRnUXU5YVhXZ3RES3ZXK2ZPDQo2TVNtTjhSM3VVUzZHeTNPTnBORnczRHFURkRQa2V0ZFczaDAvbmZZdEFuK1FFQ3hraWlwLzdMd2dlS2sNCkoxMHMwVnBIR1VoQkMxM1lLUlo2d252Y2FJc3RSNXpodUs2dWlLb0krdW5yTmZzc29FNzA1UjVKTnZKUg0Kc1ZjZ2o1ZE85QmQyTVhianI0ZWR4eVlBUSt0VnpLMkd3WFdsdzM0dVdLYTVJVDRJSExXV1BQNFpJbVkzDQpWZE1ZZEJCRmdGRy9rMmRxcnR3TEhJODdCbXBSUThxREF5cFR3alRxS2RLZjZZZUs4aGxUN0RhNllkc3oNCld4Rkx6WmRrQUtyb2szdTRFWGZPOXNydjZSd2tBTUQvM2RZSlQ2TmtqL1R1REdMSkVSdXk0S2EreWcwcA0KM0ZjVUJaOXd1S3JybEplNnFGVVRHSGpNWHBRbHFneENWTVE5NmF5Q2Vob0EvcjArRTFLSHVXR29XNHhBDQpNaHlyeWJmNVRjdHkwOTdyN1I5N29tdFE4eUdHeldmb3F0TFd2czBqVzRqTGpxNlhaYzlwVUxES3ZEV3kNCmFnckRlS0gyUGdyM20vWDBncEQvNW5scm5Dc2JOQVNSTE5HZjRhRThFZitsVkx3ZU1DbDNOR3JxdzQzcA0KK3g0Z2R2Vk8vWGpvL2xZYkJRYmVTSGI3YmR3cHFzb3UxN0xIckxkMXRGSGQ4cTUxa1RETkFFTGJMWjZnDQpGOG96MWdnRFZiRXl1RzJ0Y1FqQytXbDZWeXU4dkpYdUs2clp1RkdkZjBKM3haZ2lVTlBaS3MvUnEzQmsNCmUxNVRPSlFiR2NtQUpmOER1aEUwckJPVTY3S0NpbWVDZDQ4TUlpdHNEOTdVWmZ4dVpkMGFUNkRtdk8wdA0KNmFZV202Rk80Y21IUmllVG94V20rN1A4OTRMT3AzL0FiaEhQcHpwdnR0aDlQanNYSjBoUWhUb1B1bWFhDQo5VEM5a2JvSXZuQ1ZocTVCVUFGSVB2ejRvbmlId2NHZjEwU1ZtVGE5V1NvODlFa2Z3VFV2YXRIMTlWRFUNCkM4dTl1VGNQb1h0VFNHb2NLSm9vbS8zY0ZZNGlZY1hBZHllQ0RLdnR4SHpkdU9jMHI4YWhQSjE0b3JHSA0KV29kQkdSL1FXMzVLb0pKK05HdEYwQTdyTnRkMUJpRXJVdGFFSFVaUDNVa285bHlRVTNJY1pWNHRLWTFjDQo1ODdZdHFmNDlOdm00UnkvOTRjd1N6MUU3cld5c0ZwYmJJSVdYWjU0clZ4elBMS1paSkY1SmNXQy8rM1ENCk1vOWFKREdkUjNuNS93L0NBdnJWSFlqNEVVNVRNOVhna1U2cFc0UzJGb1g2VFh0L1VpY0EydlNyb2krZg0Ka08veUpIS1VNaDhRcnN5YzZ6R2FsM2RWZEpnQ3F4emFsaWNwc1VHZGFsRzMrdmhvZ1ZjWjU0dlAxSHVYDQo4RXpYRHF5elE5UXlwNjBhUTdwWU5kUmJqc1c5QzZLb0xkVDAyUFQ3UmNZYSsxSWRlaDFNQmRhamZhdFoNClJGcXNIdWVqbSsvU0ltUzZXSnU2akNCYm1nYUpNS3BFRmpyZE1PMkpKZUxOd3pLdlRFMTJtL0VTam1CRg0KRlRpV3BVVDVmbkFGMXpxaDFsdWgvQmJXTDI4TkRzeDZkUUJNTks3WDk5ZFVKbGZxcCs0a2dCekZRVWcxDQpPQTZTTmE4bFBWQkF4UlVKcG9CZC9yVDh6czFDNmJuWGtwT3l1UlhHN215OWV6OG1Id2E4cWNlbkJudzgNClNKbGNSQ2tSVkhxY0NBek83UUdWZmp0U204anpMQ2FBR3N3S0tGT0ZlUkx0aHhtYkFLd3RhSUcxRVRrRA0KTVRaTjJTVk82aU5lVkhOZ0hKWjNSUjJHcC9tMWlQR2lHWGhjdE9OQWJUbmJaZngydk9BM3hySW9LbFZYDQpMbWoxYkFta1IwZWpMdnNaZ2tGNE9vaVZTZDBGSG1CS3dpcCtXN0JyZ1FQRm9HNytCSEMyRUtxaTBpWEENCmJZMjlqYWR0MzVJeXpPMk1zWmIxMHFRM01hNnZ4WVpraG55QjZ1WVdXSGVwUjZVNlRETUNCbXhUYVpYag0KWHVwUnRDVHBVeFR2UmE0b3dtcVlKY1B3UEUvZzRwM0Y1cGVXUEVMMmNUK1k1aU9Nd2liNjFmYW1kanlnDQpRSkRudEtaMW01dHQ5U2tibUVrR2JOS0Z2cGtBR05mWnlUK05mOHlnT0JQazgzWjhnQXpXRDNTbmJHOTENCkRzNnJJR3U4SjVFNEYrclpHTEI5UjVWN25SbTI0ZHRWam5IUHpQdGRJa254V05oOVYwOGhPaTlnZmw5SA0KVTgxd2pQcENtSEdRVDFoZXpFNzNCVVZncVA1Umc3QWUzTVBTUlBUdlAyVU9ORnFSU3NiT29LSDVQTHp6DQpIRXhWblcyTDNlWjNDWGhhUWR6ZW90Z2FJMVNBTi9RZTlYdHBqUWpscTRmUzlLNHBtYWJhbFVKOTdHY3INClgyaEVHYk1pbWhOY1NvazliWkN3dzJlekRYTXhrMGxZODljM05uSlN2eHQ5M2hxVFl4am9aWlB6cnpPNA0KalQ4YTd3dUJ1MzN1bmhaQVZtRFNYb1AzVzV5M1ZsVm95M0NYKzlKdGt5S0d2bHFRakRFUlhuaUJ4YWM2DQpkNXNKRXRKdnRNZ3lNcnBlUFR4MVZMdzlqRDF4NE1iTW9vNWdnVGE1U0piZ3IxODhkakpUVEtXb0lYZXINCjgzcUdXMjlJMEdMTUg1eDFOVzdBeU4zbzl5emhMVFloMEVndzJFNVEzV1JUYThBZkpLeVJOcnpPTGtNNA0KUWE5R2tiSHY2SFE3K21LdERzRlRJQTNzb1FNUkhFSFNVWWxWenQ1N2FjMEZGbzRWMTR3amlsQzZNZ3RjDQplVmJJSXlIQnJ0THppdWNvTVBwUmpzbGdTSDlZalB0a29HamlYUEhjYTZGMHRmS0xXYVlOT1V5ejVrRE0NCnVKUGNnZms0MSs0M0RPd2I4MXVrY041WHU0bFBHQjI0dVNReXpYM29lKzJLUUkzMENhS2QyOXFoeC8zSA0KVWN2dXhrNE9rVTYwS2JUSUZHR2RRejlMaUdYdHVRTFlneGFqREFmNDU5SnlJeFlYMnhWRFprRUc0YXZiDQo1SHRLd0VQT2d1a2x1V1cwbkh2Y3E1SDVXeUxxQnV2cHZLbnhQMFdqZWhKaldqa0hFdDBDbWVYbTVTMWcNCjNpYXZTK1pJZWhlMExlSzBMVkZYMjZQbjAvK2RmZ1RUWnpITHNseVlDa256VFAvalAzZDd1NGszS1AzTg0KSmYwbDg0YTQ1Rm1UNlJkMmxmUlQ3ekVlYzBrNy9GZ242ZWtsRkVmOUZZTDdpcFNUeTlwVGVRM2d0VnU2DQo0a1lTM2JJUHdtYjlvL284cW5Jcnc5Z0NGUTIwaSthYXcxanZHVEY3UEpMWm1vZVBGRHVrVS9vVURvc3MNCmlkNjRac1IvZ0lnaVVzRWd4OC9SaHFna2VQRWI3ZGkzUlBmbUcrcEpGZmJ2dzlJTVhNUExtY2tlU3NDaw0KeUxJaWRzSmJvZG1WL3FHbFJJZUFENW5LaStTbk9EbXhJVTd2RGZpT3krb25ZYWZLbE00bmljaVRCQkRCDQpiRGZMWlJtRnJtTFBHRldyUWxpakcrVTNDc2xSWllqV01nZGpxQXoxeU9JaEd4SmVxVUgyOFlBTVZHa1QNCmc1NnNUeXJhN3RzRmJJb2V1NzlvM2UzdExwUjltdzdjdk1nMkZwcGh1MUpEU3hkT1NvTEJqVHp4MENUYw0KWEhueGoybXpuSFJON0NEc1lxQnhMb3JKNk1zRjl1Z29Ed0hKYjBCZDFuZnRhbnh3eXpXa01pbHNLSjJ0DQpzeGNtWFQ3WUVFQnBaRmlETXBNKzY1bS9Lb1l4SldRNDI5QjVwQ2k5QjB6ZUhmMm5JSmRJR3RrdCtqZ3QNCkFHbEJFNFNWWGpFSkdJMG1tOWxHQnZsN3FNbTF5QnJmNHBDbDhpSFdienVvcEowRXFxQzRmVnYyc3Vpdg0KQ0FydXdYeXdZVnZONDB2YWZVREtKQXVNckpIV01tVDllMTcxSHhXaUp1OVFQZURWSWRlalUxdVpEdlN2DQpmWUtOcXpEb25NZGowUWRnVnA1L2ZFakRhZFFUZUpBNENuTnVNNEZwT21nRzRPNlA1aGNmRmwwa0srVzENCkhndDlORzdxSzAwUFJSdHd5WlFmUnJnOUhhTVVjNmtqVmlQZzdkUkN4a1FoRnR6QzdNQndTWlN3Y1p6WA0KQVcxYTkvMmFMTGVGcDhxMjBMcTlNN29SZThmNUh3eFhsU29UVjlkalkwYnNNSDZTdTNFd1hPc0tjdDdhDQovc3lLUjVGOEh6L1ZFbnk2YUxtY3dHNDVLOXlWSUhMMmJIRDR0dDBDL2RrOXB3OUlFeUU0ZFUzSGJIRnkNCm83WTFqUGFCVjFJRWkvVGRsQlpuT1F5d0N2aWd3M1VrR25KemNKMlRrVmpEZndTVmo1OGdpaWRKMUQwTg0KUWwxb2daNzdFakFaSUU4MSt6N2pnNnE2ME5mbVNoQjhHbXlPYnFKVnVCRGFESklMRWtFdkxMVFZHVE1mDQp0OWhUdzNPV09LRnVPcTQxM2dhdEdpV1RPTy9WWHZDNlVvcGg1TzFQaXVYejZUckZSQnJqcTI0SkNnUWUNCkd1aTFMemZEc041dHdyVXZ5S1lzaFk2OWdocC9xVUE1Q1N0bDJxbkFpRkNCMjM5VnNJY08wVFIwYnJ0eQ0KdzFXdTlTc1EwMXhsTmVER04ralB1RG1YYUVJelpST0xhMDU5eHYyMUJHaU5VQkNGODZWZUk0dzBZamFoDQovaXFZSWxMc2dlY1BQRUhzbjRGUUh3RllST2lTcklLOWhadFhXZEVBV0dpd2pMbzJwU0lwVmdpTmd4cFgNCjYzRjdOeUFjMHZIeEw4TkgybjE4dFMyUUUvbzNBVVhCN1BwZk1CSGwzVVRqTkdPV21zT1JoeTZpVHdDUw0KeGltSEQyYjZEYzJzamZsZlROTWRuUHVva25VdjlTWDJGbEUyMWg1UEtyOXovOE5jek9HZVhXZzM5UzJzDQpXK0dZSjJsMjdHSFRjR2xUeldKOUpycEFEUWlEWW1DWGhJR2lHMWRWYjlCZHNDTWpSMjVsVTYrOTJwWE8NCjZXdDQrL3VMcXlrYTA1b3R6bVFMeFVCRjlkdUZpM0pFUmVUeDFHbm81bWErSGxHL2RJeVhWREZwb2JUQg0KT1p2K1h3UWVQWjBwNjRhSjlQWDRDc1hiMzNuaXpiL0FHTEVmV2g2NlN4M3o4cXlFa1dHOGp4eHNnWkpNDQpBb2I3N3NRWFNudWJyMEViZzdwc05SWkRDVWNscFlxSVdEdGRvUWRUd2RHcnVRTDJZcmQ2RUVpc0syRHgNCmRLTjhMUi8xZzRIQ3RZR0VTTDNEdDBqL0RHRDFkT0hHZXhlV0xRR2o1OGlvekF6WGRwZUFxaDdodk5iVw0KYUExWjJIUS9kK1ZHaEhtZGNReGpmTGZzTHFQdWtsRUt6RUcxYVZWUFdKMTd3UkVlY2QxWkZEbjFQUFI3DQp4a2txZDd3Y2YwYUhSbmJuSk1RVkRtR0kzL0hUZ1BPdkpQSk5EMkt4Z3BkYlFCTzhlL2FNazRuVlZmckENCnBaeWdIQWVvVzR4UnU3TTJNUTlOYUZHZmxFelVLNGN6QmVnYjlGdXRyTCs1UVQ4c3NMYjQrdG9GdFBlbQ0KMEg4SUZPSmR5dTJjakZBMjl2WXVyMVhVVmRSU0RwSjMwdGc5Z0MrN21EV2kxMXRZdkdGaTRnelVqN2JkDQpvSVJaL2Z4VW5jSGJvVWc1d3VkOXg5NWtWcGRUcUJkclRsbWk0WDJXekZGcVU3Q3JSandXWkRxNkFJRXQNCmkxSFJpdzB2OEJySk1idllUc3dZdWN5VHR0RGFHZGZvb0J2d09MQm5ZdmZuRytwek1GRlRPb281NktXeA0KWkViWHFxWGtDL2lpQjdxdFMzYS9hN3JiZE55OWtEWllQRDJaNUJZcmVXTy9tdlhLNGZPVkRQcmxYVnJtDQpRZ0NtaktDaDg4UVEvYXcwYUtPbkRqY0x6MWpabkptdmlGWFRZTktHc0dlTm9UNmhhS21JV2t2S0hFd2ENCnJGZm5KNExqaDJrQTVJTFMyOTM2R3V1Yitwd1E4clV2cmFSN0JJQlY5eThnMitSMjlxU1RtaUREQU9TWQ0KR3lQcGNuSjN2Mkdxd3Z5ekJRc2I4NGhqVDI1WVFKVjJOU3V6cEZWWHQvS3EzUGprckRzYkg4N1VpTUJvDQpTNkFuRmVzQ3FqUy8rS2hLbUdNdlRMZ0t3cmt4a1hVWDRyRWE3LzlZclBrT3ZLTU1uaDM2ODByemJJTHQNCmRCRWJCWWRYT1JmT3lXLzd4MHNOWENJZ2o4WDV3SDRHM284cnllNERMVkxPYVBLZ3B6b1ZFZFl2MWtrMg0KcWVrOXVJNzg2ek01dlYvWUE3R0k0YjF1SGJJRmZIemJPNjlzNG1qclNSK05nVnI4bDlUT1NRdz0NCj1RVURNDQotLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tDQo", + "size": 165884 + } + }, "raw": { "id": "16e8b01f136c3d28", "threadId": "16e8b01f136c3d28", - "labelIds": ["SENT"], - "raw": "UmVjZWl2ZWQ6IGZyb20gNzE3Mjg0NzMwMjQ0DQoJbmFtZWQgdW5rbm93bg0KCWJ5IGdtYWlsYXBpLmdvb2dsZS5jb20NCgl3aXRoIEhUVFBSRVNUOw0KCVdlZCwgMjAgTm92IDIwMTkgMTQ6NDk6NTAgLTA4MDANCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L2VuY3J5cHRlZDsgcHJvdG9jb2w9ImFwcGxpY2F0aW9uL3BncC1lbmNyeXB0ZWQiOw0KIGJvdW5kYXJ5PSItLS0tc2luaWthZWwtPz1fMS0xNTc0MjkwMTg5NTk3MC43NjMyMzMxODk2ODY5MTcxIg0KT3BlbnBncDogaWQ9RThGMDUxN0JBNkQ3REFCNjA4MUM5NkU0QURBQzI3OUM5NTA5MzIwNw0KRnJvbTogRmxvd0NyeXB0IENvbXBhdGliaWxpdHkgPGZsb3djcnlwdC5jb21wYXRpYmlsaXR5QGdtYWlsLmNvbT4NClRvOiAiVG9tIEouIEguIiA8aHVtYW5AZmxvd2NyeXB0LmNvbT4NClN1YmplY3Q6IHBncC9taW1lIHdpdGggYXR0cw0KRGF0ZTogV2VkLCAyMCBOb3YgMjAxOSAxNDo0OTo1MCAtMDgwMA0KTWVzc2FnZS1JZDogPENBS2J1TFRwYXEyMUxiWEQwdU5vPVdaei1Qa3NlajlrQU8xM0ZtcUJtXzVkblBHQjJrd0BtYWlsLmdtYWlsLmNvbT4NCk1JTUUtVmVyc2lvbjogMS4wDQoNCi0tLS0tLXNpbmlrYWVsLT89XzEtMTU3NDI5MDE4OTU5NzAuNzYzMjMzMTg5Njg2OTE3MQ0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9wZ3AtZW5jcnlwdGVkOyBuYW1lPQ0KQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudA0KWC1BdHRhY2htZW50LUlkOiBmX3pUekhWTXdacW9XdXRub3RPeXJ2cHNXaG13Sk1OaUBmbG93Y3J5cHQNCkNvbnRlbnQtSWQ6IDxmX3pUekhWTXdacW9XdXRub3RPeXJ2cHNXaG13Sk1OaUBmbG93Y3J5cHQ-DQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQNCg0KVm1WeWMybHZiam9nTVE9PQ0KLS0tLS0tc2luaWthZWwtPz1fMS0xNTc0MjkwMTg5NTk3MC43NjMyMzMxODk2ODY5MTcxDQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTsgbmFtZT1lbmNyeXB0ZWQuYXNjDQpDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT1lbmNyeXB0ZWQuYXNjDQpYLUF0dGFjaG1lbnQtSWQ6IGZfSW51bkZhUlFSdkd3RG9tdWpjQXVSVnJmQ1plYkVMQGZsb3djcnlwdA0KQ29udGVudC1JZDogPGZfSW51bkZhUlFSdkd3RG9tdWpjQXVSVnJmQ1plYkVMQGZsb3djcnlwdD4NCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NA0KDQpMUzB0TFMxQ1JVZEpUaUJRUjFBZ1RVVlRVMEZIUlMwdExTMHREUXBXWlhKemFXOXVPaUJHYkc5M1EzSjVjSFFnTnk0d0xqa2dSMjFoDQphV3dnUlc1amNubHdkR2x2YmcwS1EyOXRiV1Z1ZERvZ1UyVmhiV3hsYzNOc2VTQnpaVzVrSUdGdVpDQnlaV05sYVhabElHVnVZM0o1DQpjSFJsWkNCbGJXRnBiQTBLRFFwM1kwWk5RVEIwWVV3dmVtMU1XbFZDUVZKQlFXa3ZlbE5zVVhWbmJVaFlWak5UYlhjeFJ6WnlVMDQwDQpRMEZNZDNkeFRuZHhjMk0zZERNeU5Fd05DaXQ2T1dabFZreEdWakV6Y1hWaGRHMTFWM2RoVGpabGEzRmxiSGhGYVhadWRuWmFRemhWDQpWbEJtYkZCcVFWVm1SMkpuZVc0d1ZDdHBOSFZNZUEwS0syWmxaMXA2Y2pBd1RsVjNha3hvYVc1UVFXMXhWelZxWkhObVJWRjFTMkpaDQphRUpKVjNsNU9EQklNRVZsY21JelpYbDNkbXQ1YzJneVRtTkJEUXBMZDJsd1dXZHhjR1V5Wms5NVVIbG9aak41YW1neFowNU1MM05KDQpXV3hNUkdaaGFqZFVjRFp2SzJka1JITm9abmxhZFhONVVrMXBkV2xuV2tZTkNsQktVekJNYVV4NlVuVkhWR2wxSzJaSGNIWTRZME5PDQpVV3hVT1dwb2VWaG1XbTFVY21aa1ZtcGtZMklyU0hSM1pUTXpPVkprVm1Zd1JqZzFPQTBLY1RORWVraEhjbkZZV21GcmFWaElhazl6DQpWamRWVlRjMk16RlVWSFp1T1dOMGR6aHNNWFpLVUdvdmF6UlhUWFF5UkRoQ1kzbERXRFowV0RCc0RRcEJPVmt6UjNsdlNUQk1NQzlrDQpWbkZwWjJwV04ySktUV1IxYUVKbVVVcE5kRlIzYkVORFVEVnNZa2RFT0ZGUWRXVlVibXBXZHprNGVVTlpXWE1OQ2xOaVNsaGFhWE5MDQpTM3BKVGpKbVVWaHRVSFZOZVdkMVVYZExUR0o1UWpsMlF5dGpVMVZCT1c1WWJsVlhLM2xITDFrMGEwWnhNVEpFS3pCMmVnMEtVRFUxDQpMMUpFT1hGdmJXNVJhVUpCYm1SeFlWSmtORWhyZDNSNGVGZFZlR3BMUzA5amFFRm1lR2RYTHk5TGFEWk5aREJsV1VndlkxaFJTV0V4DQpEUXBRVmpOQmVtUnhhMWRrUW1OTk1ubHBaVUZUVFdSVlpFWmlkVk5hZWpSNk5HRlhkMlpxTHpJeE5VRmhiazFSYm14Rlp6Wm9hamsyDQpRVm96Y2pVTkNscHlhMUo1VEZORFpqZGhUVFU1TUVGNmVrZ3JUMWhEWjJsa1UwcHJia3AyUVhVNFVVMXVRamt6U25ObmJFbHFVWEpHDQpNRFJwWTJKTldGUnJRUTBLT1d3emFucGpNemRrTkVkbFdHSmxaSGxzWW1WMWJTdFhaMVpYYWsxVGVURkxXSGRsU1ZjMGNXaFdla0ozDQpWWGRFVFVZclFuRmhOMUpKUkZWQ0RRcEVMelJyYTBKSVdIcGFTalpvVG5sbWVVdHVMekZrWjNnd1NHeDBXWFJDVWxkdlIyVlRZVmhPDQphVFZxVHpSMVduaHFVelJQYjA1bGVVaHFXV3dOQ2tSalZ6WlBhVEYyYWpWSlNXWk1hazV0Y1c1WllsaDJha0pRUkZSeFMyWnVaVGQzDQpjMlZ6UmxVemNIQm5RekZwUWxaVlFuZEtNR1ZHUmtWMGR3MEtZemRwVlVoMFZHeHRhR05SUW1KTVdUUnVaV2xWU0VnNGFISjZSRUozDQpkbmhZVkZabU1VNUtUVkJMTXpsTlFtTkJhRkYwUzNKUGJtaHBXalJ1RFFwbEwxTXdhVW94VUZWQ2JHWndUbkJNUTJGQ05ISnBiV05tDQpObnBxYzBSNlIwSnBSWEk1TTNwck9GcHdOMDAwT1dadlJHMUJWRzFOUXpCUk1uZ05Dblk0Y2pCdUwxUkliRU5ETUhSTlRGZERiaTlZDQpjU3QzUkZoNmQxbEJTbFZPVW01SFlqSjNaekI0UlhGT1dYSXJabmhNWmpGTFNqWlRTMDlHU3cwS01FbDBSVlExU2xKNllYVklkM2dyDQpPRE56WWtoc1l6TjVUelZoTmtJeVEzRjBla3BPU3pOSU9YY3hTU3R3TjBoS1QyeEJOa05oY1VKQlZsWnVEUXB5TVVkU1NXdHdSbUZtDQplak14YzFBcmNsbDRRVUZPTUZoeWJIQnplREF2U0hnelV6ZzBhMkUyYTI1eU1tbHhNamhTTUVneE9HaFZkV2xJVG5vTkNtNW5MMjVoDQpNbk5oWkZsamVEaHBZMmQxUzFCaE9VNVBhblpEVkU1SGFuUkpiWFpzYjBwUVF6WXdaWFpFVGxaMlNGUjJZMnBKTTJZMVRuUlpPQTBLDQpSbEl5TjNwbGQyNW9aV2RGTlRWSWRsZzVkV2hHSzBWNlduVndNWEZIZGtkMGNrZEJUek5DYzFCcllrTldUMjRyVmt4UldsWllNMDUzDQpOWGRxRFFwcVZFOUthamhSUjBRd1NITjRaRFo1UWtkU0syMVNZMUpxWXpKeVJWRnhkbVV4T1dOcVFsSnNWV1p5TkhndlptOUpSa0pRDQpZbVF3VkRsSWIwZ05DazFLTUZGRWNYRTRMMVozUjFScVUxVlhWRkZIVTJoc1JHOW5VRlZtTlZKclEzY3ZWamhpVHpOT1EwbHVNbGRCDQpNM00xYmxOVGExSldSbTlrTVEwS2VVSmxNRzVUZDFsV1dHRlNUamg0TVhwaWVXbEpNQ3RaVldSTUwwRkJTRkowVVVoNlF6ZFlSR1JODQpNMW96V2pGcVNqQkZXR1ZRUTNWU05rSTFEUXBtVkRkdll6VldibkkzUVZjMFRVZGhaREpIZG1WeFZsZElhSFYyVm1WT1RHeHJZbWRzDQpORUZrV0hKR1F6RmhWSHBvTjJsRWJUbG5VbUpSZFNzTkNuUlFVbGxSVm5sdWIyRXhjREY0VkdoTWIyeEpVWE5IUm5SVGJDOTRTaXRrDQpaREJyYlVWcEwzTjFVWFpRTUN0dWNFMU5aMWN6TmtGS1FXdHRXZzBLZEdwUFRVRnRiak5NU3pOd2JFTkdaamxEV21oYU1HTkJMM2MwDQpMM05EUm5KSVp6bEhVMkZ2Y0hNNFNWVjNOVTV0VGtKWk0wMHZhbWx1YmpGaURRcFdhR0kwTVV0dVRWUlVWQ3REVldJdmFVaFVOWE0wDQpkWGc1TkhKNE1GY3hjRGxwV25oT2VtRmxSblZ2T1Rsa1JrRTJTbVZZYlZNM00wSlhZM0VOQ2xGRVJXOVFlV05WTm5kTmEzRm1PRTFVDQphMGRCYjFKRWJHcFdRbVl5VlVGMFpEaG1VbUpDWlN0UlUwYzBjazFXWkcwMGRXOVllVVJyYkVOcFlRMEtjVU5EVDNjMWRsRjRXakkyDQpXVEowU1hoekwwODNhR2t2UkUxNlRubHZjR1ZrZUhaWVNqVXlWMWRWUnpsMFYycGtMMEV6ZWs1cFlVaHdSWEE1RFFvd2FYY3dUVFZpDQpkbUp6ZUZaSWIweE5UMHg1TnpSR1F6VkhabVJGTmxKUWFtSkxSekY0ZFdWamJXRnljRU5KV1dGck1GaEdaVlJvYTB0VGRWQU5DbUl5DQpUV0Y0YjBkWVZsWm1URzl5UTJSWVVsTXpTVVZsV25GVWJsSk5PV1F4VEVvelJrTlZTblIxV0M5S2MxUk9ia1JJUWpGTmVtWTViMFJsDQpUZzBLU0N0TVZDdHBjRVJSY2padlRFRlBkVkoxVVdGVmJEUlhZa3hyZFRKTE4wSmlVRWcxTWxweWRqYzFjMjl5Y2pWRVJtcHpiU3RrDQpTa2RZZFhCRURRcHpiM0IzYTBjMkwwZHVUVkpJTUc5emQwWlVUa2Q0VVZOdFdIZ3dVM281WjBOWlJuVTJPVVpOZWpGSE1HbGpjbFEzDQpORkp1WTJKQ2FGQjJWbEFOQ25KUk4xcEVhRmhpU0N0b1FuUnJPSEo1WkZOaFpVZ3dZelJ1VkM4d1kwc3ZVR2cwVkhkSmVuTnRaVFIxDQpWRzFoT1dkV1ZWSjNlVkpNVjIxQ1ZRMEtRVlJ0ZFZSWE1uWlhhMjh3Y1VveFVIcEdWbkkzTjNOd2FYZGtPVzk2ZUVsak9XNTZaVzlPDQpiVVpCUlhOS1lqRTRSMWhCYVhObmNXeElRM280RFFwWWJtWTFOMU5rWTJGMGFubFZibmhKUTNvM1ZqbFFkRmhNUWt0amFqQmxNRE14DQpNREIxZUdod1RXSkpiMVU1VFVOVWNXSktUVXRWWTNkdGIzZ05DbEpaVG1WWWFreHlSSGRpUTAxRVJFdGxWeTlRTW5Vd1J5OXRXazg1DQphV2xOTjBkV1ltUjFiR1k1WldaYVkzRmtLelJtSzJsbVFqVlNla3Q0UXcwS056UnhkVWxvV1RSUlpIUklVR1Z2Y1d0c05uWkJWVzVuDQpNbEo1UlV4VFMzcFZZMmRXUWl0bGIzRm1PRlJYTmxoUFkwNUdPREowZUU1Q2JIQjZEUXB0TnpjNGFXdDRObTV1ZVd0WldVRlNiMWN4DQpaRnBQT1hKRWEyRnBSRkpzY0hGS1EzUXZaelF4ZVhKUGJtVkhjVlZXYWtrNVZVRkJZVWRGU0RRTkNuWXZaRWhpVG1GRFMzZERXV3RSDQpla0ZSYm5KblNWQnVRVGRMS3poMk5HWlBOMkZsV0d0UlkyNVpRVmQwVUcxUlltSXpOelJ0YW5KM1l6VnZTdzBLTjFkUVVrNWliR3gzDQpTSGtyUVZCRWJHbHlNbU5QYVhWWk1Ha3JiVVpTTDNSUVoyeDJhVkpVVjA1TGVVMXdNREJWVTNWMlVGZE1kV0Z4ZDNwckRRcFBZbkpRDQpNV1pUU1ZOT2FWRnRUbmh6UmxodU1FUjBVak13UkhCQmVGRXdSRTVIVnl0WFREVnhRemhoTlVOc1VWRm5kblZSWjNvclprazFVV0lODQpDak5vTTNGTldUSmpVWFJYZGxWdVZEVnVjVzluY2s1U2RXSXJZa2RYVFV0WlduQkNUVEpuWTNKa2JEaHFSMHBDZFdOc0wzWXljSGxwDQpWMDRyTWcwS1ZUaE5aV0ZtUXpWcFlVSTBXbmRLZW1kd2VYaFRSa3BSUmxRMlVXSXhUMmcxWjFOSllsUldla3BpT0dsdmRFUkdZM1JoDQpUMVZVWkVndllqWnhEUXAwVkVsRGN6TXJhalpRWjB0cmIwZDJWRkJUTWpaWE4wRldTRTlYWkhkdVNXbGxiMk5GVTJoTk1YZ3hReTlzDQpla3c1Y1hWdlUySlpOVk5wUjFBTkNqQm1WVGw0UkUxdFJ6QkZiVTUyV1ZsdVJVTlNUWFp2UVdRdk1ERldNWEZ6TWtFeGNtbFVkRlZxDQpWREFyZFdOTE4xTkNabFp3ZDBkNmVUa3paQTBLY2t4clFVTk9kVlE0Vml0aWJVa3ZOV1pJVERKM1J6QldNemx3Ym05Q1NrMXBXV1ZtDQpTVGhWUVRoNlYwUkpRM1kzVkdKNWRXRm9OMDVsYkhWNkRRbzNaMjQyY0VkdFpGVkxXVUpDV1RkU1QwNXFURVJMTDFkMloxaHFUUzhyDQpiamRFZWpCcFJIcE5hVFJHWkdGclEySXJWV3BpSzB4WVJuRlVOV0lOQ21Jd2F5dG9MekJLVUdGT2NsbG9Xazk2ZEUwNVUxb3daMjFVDQpkbmhITkVJMUwyVlFZWFppWjI5WVQwVXhNMmxrUW5KSFpDdFdVa1ZaWWpNNVR3MEtTa1ZJYkRCd2VuRTFVSE5WZW5kTU1UZE1ZV1JMDQpLM1ZEUmpZM1JGaDVhWHBLU2pWRlp6ZE9aWEJvSzJaeWJsSnpjR3AzZGxkNlNtVkxOREJsRFFweGVUTXhTVXhoV1hGRVJsUnNUbFkwDQpRbm81WWpCVVREQkZSamRZZUdSVU5VUXhja3R3WlRNeU1VRllkME5DWlZGM1VHZFpRa3h3ZFUxeWNVUU5DbVJXVlhWTlpYaE9WbmRLDQphbnBXYlVSWlRVaHVhVEU0Y1dOa1JHSnhiRXhqYVdkNWJFRnFhVnBvYUhoamVFRlhaRWRZWkN0aWVrNVlSazE1YncwS01ERnNaVE01DQpUMk51Vmk5VEswTk9Ra3BOYkhSU2NsZExTMFprZGtwWFVuRmpjMUZDVDBOTlIzWlpOM05zYmtrNFpUaFpNM2RyY0RJM1VUVkVEUXAwDQpjV3BNVEd0cVQwNUllazVzYTI5b05IZ3lhRTlWYTJ0aU4ySldlbmxWU1dwVVlYRXZRblo2Y0VGQ1pEZE5TVVJhZUVKM1psaHlTVzFWDQpjV1FOQ2xwT1YwNVFaMEZEUjNWb1N6VndNVzFwYjI1aGQwRTBSVVZxZVVsM1RFczJXVUZEYVRGalMya3JPQzlCVTNoVk5XTjZaVFp2DQpXbmhuZVZVNFFRMEtRelptU1cxU05HTjNNVTB6Y213NFluRlhTMk5GYVcxYU1XMHdNMkpHVjBweGJrbDZUMVpDYVdncmFISTNSMFZTDQpVQ3N5YlVVNVdVUXpOSGd5RFFwblNIWldjVGxTTmk5NmRVRTFkbHBCWWtGTVYxcFNUamR3YzBNcllWY3djVUZNU0VGWk1HeFVURFpXDQpjMUZRTjJoV1NWSXpkSG8zWlZSdFJWZ05DakV6VWtwbWNFUmliM1puWjFGUlNWbzRNRmQ2TWsxS2FIQTNTbTVMT0daS2FtdFNUMGs0DQpURkJxUlZRMmVYQjRkSGRDUW1ST1oyNW5TM0E1YmcwS2JFWk9kR2xyVFVWWlRsUnZhV2RDVUVkUGJqTTBOMUpoUlN0bWRrZzRZWEJRDQplbEJYYTIwM1ltWlFXbkpyWjFZeVMyUkNXQzgwVUdSQlFteFdEUXBPVW14U1pXMXJRMncxVDNSak9DOUpSa1ZPU2xWNU9ERlJha05ODQpLMFpQUTJKM2IzWjZVblpuU21kRFlscGFOQzgwWVVWUVJGRTFSbVpWYWxJTkNubENVV3AwYm5GR1prRllXWGROSzJjMGJXRnplbTR6DQpSbEpxUVdJeGNFbDNMMmR3YldOdGNrUnVhVWxxZDNKdFFYVmFjRkZXYkZWYWFtRXpSZzBLZUU1a2JVNVROVzl3ZGxGT05YZDRPWEZ5DQpOR2xNVXpkNGFuQnhZbVYwUXpjeVdYZHVPR2xVYURneGRHdDJSRkIwVW1wa1VDOW9OV1YxVm01SURRcFRjMFpFTTJGVmJFZG1kVUpKDQpabXBNYjNKNU4ybHhSVXRTZVVOdVFYcFRhRU4xYTFWRlZVRnRjMFJWUkN0SlNIWk5ibTAzYVdKT1EwTjBTR01OQ21wMGVYcFFjM0kxDQpWSGN5Tm05UlkyRlRWV3ROU2xOSlMyNTNTMlpCVEZCUmVuTmlhM1o0VjIxb0wxUXlNelYyUWpSSWR6WndTV1l6UVhodU5BMEtlRUl3DQpNbTl0TjBjeWFuQldlamd2WVZSaVlUWXhZelJoTlVkemVWa3paVTAzUWlzNFdVdG1SRmMwTUdRd09WWnhlbWhzZUZobVZYRndTRE12DQpEUXBQWkZGUE5DOHpVa28xYXk5b1VFdFlOV3BuYUVaR1JXZFhXQ3RVTms4M05pOXlZVE56TnpaWmNVMU1jR3BQWlhGR1oxbE1XalZQDQpRblo1TWpnTkNtRlRaRGsxUVRoSGNFSkZiVTVGZUN0MWJWaEpia2RZYTAxdFUyVm9kVEpwTVd4eVdEZExialZ1UTB0R2VXcFBaRlIwDQpZM1ZGTWxsNlZtY3hUQTBLY2xOQlNYWlNNRmRCU1dWVlVsa3JaREo2Y0RrM2NsVktNa3hxY2tKR01FZDJWVkZhUzAxNlVtSTBXRnB1DQpia0pUWlZoa1pWUldhV2t3S3pGekRRcEJZekpwTlZkNFdVdGtVblp4WTBoQ1RDdHZhV2MzVGtsUlpHNVRWR3RzWVhWR1IydFpabmhNDQphMHhwWXpONGIxcHBSVmQ0Y2tKRmEzQkpZemdOQ2psUmJsZHBSazltTWtOWGVrWTVORnBSZFdwRFltbENhWFpNZW1oNGJsaFdURFo0DQpiVWs0ZEhsU1oyZFpNbTVhUjJSa05uRkNhRkJ3TmpaNlZnMEtaMnhWYW14T05EaGpkV2hJTlhRNGFFSkljVWhPYUZSVk9EZFNVbXRaDQpibGs0VFhGWmQzVXpRamRCVEdVMVYyZHNUazVTSzJsVmVtWldPQzh6RFFwblkxTTFkbVZMZEc5NGNXazVOV2wxYXpCM2VsVldPVVpMDQpOQ3RxT1U1bVdVNXlXSGRVTkhKS1VqRldNMUJPWjNaRk5EUmlZa2M1U2pBclpHa05Da1JwWjI1RkwzcFhRWHBrUzFScE9ITlRORXQ1DQpNV1l3VVhNeFlWWlhUM2wxUjJ3MmVVTXZhSFJxV0V4cGJXeG5jR280TlhaWGVubHBabE5RTmcwS1dWUnFObVU0TW5CMlpYaERhbXRpDQpNRGs1YWpKek5tMHpSbk5pWkZWUFRpOWliWHA0U0RkWFEzVkRSMVJYV0dRclNqRlNSMU5VTHpscFRIcFBEUXBKU1dSRUsxRktXRm8zDQpNM2x3YWpkUE1rdDZjMDVhV2xSUVVIZFVWRll6UVd4aFYxRnRObEJGTjJSalNURnBkVEpGTURkb00yWTBjMEl3V0VNTkNtWjJaM1k1DQpaREZXTDNOc1R6Z3hRVzgyT0RWWGJEWjBRV1EwTXl0d0t6WnRaVFZhYnpkd2VrUlBlVUYxTUdORWNHUkxRMnBGTTFoMlZsVXpiZzBLDQpUM2xxT0hCamQyTk9URWxwV1hSb2NYQmtNVTVwWm14aVJGWkJaMDFUWW1KMFFWRk9Xa2tyY1hSb1VteEljVWhtYkU5RlVVbE9jbVJTDQpNMjFpRFFvNU5FTkpiR3BDVEV4Sk9FTklUbGhUVUhjNEx6ZDFXSFZRTkd0bkwzVllRV0ZsWVZObGRqUXhUV3hRVDNNdlFqZG5ibFpJDQpaMnBrY0RVeVMyb05DbGtyYUhaWVUwZFRlWFZNUkdwUloxTXlNMHBQY2xadGRGbzJPVTB4U1V0VVpFRlBUVlY0YkVoR1YwUldjV2h1DQpXamw1Y1VKWmNYWkliMU42UVEwS2RERTFOV2RtYVVORWFuaFRVbXhJVlVwTFduVkJVM0JQZDJWVmN5OTNRamRrVFUxclRsUlhWemRtDQpZME5FV0c5M05VRnpSMGhQUjJsbFdtTkNEUXBEYkdacFdYb3dVRGQwYkRBMmJteEpMMmRTV2pWb056Vnhhalp5VjBwT2RHTkRPVkYyDQpjQzlLZWxsUU9UTmxlWEJ2TjFOd1dHbEdkMDFzVVVZTkNqRmpWa1YwZGpkMWJWVlhOelJQYjBSRVMwbDVVRzEyUVVaeVdFVk9ibEk0DQpPRE14VXk4NFVURjRTVFpGY3pGeWQwb3dVazVDU1VSQmJtUlRXQTBLY1M5dk1tMXJRa2hrTjA5elMwMXhaREpaVWtwdGJTOUJhRmh1DQpVVGgxVXpkWGNsTkpPVmRDWkRKT1EwRm5WRk5qVUZSMlJtRmhiMlJLWTI0NERRcHFUak5vTUdkdWEydzJSSFEwWm1KT1N6ZGFhRUZQDQpkemRYVEhkb0syOUVXVmQ2WVcwck0yWkliMVozTUZrck1tODRUbXhOUkhvNE5rOUJhWFlOQ21WblVuRjRPVFpsZUhSdFNGTlJSR3BPDQpWbFIzZDJZNGRERjZSbVY1VnpnMldGY3hVbWwxU2xSR01rUmxlSGxCTUROaGRsSndRbVp0VEhkMk1RMEtPR1phZFcxS1JrcEdOazV1DQpVV1Z2UjJjMlQxa3JNalJqY2xKbVJXZDVjMFF4WkU1WFpVMW9iME5QUkVJeFpreHZUWGxMT0ZOTlIwSTVhM1pqRFFwNGNITm5UWFpGDQpPSFZ3YWtweVJqRjFNbk53VkZaSmJHb3lZVWh4YTJWU0t6aHlRVzVwZWk5Q2J6RjBhMUYzTTFSbFpTOURWRU0yVEZoVGFUUU5DaTgyDQpaVGN3TjJOeE9FSnNVbTUwZDBZM2FGaFFjblF2WkZaRVFqTmpkRnBJYVVjME9WUkhkRVUyVkhsU2RHdFNOVlozTnprellreHNlSEZoDQpWZzBLTjNjM2JqZHhNRTE0WmpsSVZ6WmxlR2xqZVN0cGMzZHZiVEZTTTI1bGRGaHZlRUZRYTAxWE5EVnlPVmM0SzFoUFJrUkRWSFZZDQplR1pVV0ZwUkRRcDFNMWt4YzJScU0yaG5iV3hKV0djMVNtWXZibmRCYkcxdlZtOXNiSFZJZWs5bVVEbGpjVTF5Y0ZoVVpHSTBlSFJODQpaSFU0VldwVVppOUtVbmdOQ25KclpFVjBNR3MyU0RCSksxaFlSbGRzVkZGUmFYYzRVbUY2TWswclFUWmtWM0pJVGtoR1ZHbFNlbGhoDQpZbTlVTUZrMFUyVkZiR0V5TVdSNldBMEtVSE5zY3pOcFNGQk5Ra2RLUTFCaFFWVm1TM0pETnpoRlIyRTBja05pVmxSWGNqVkNkRmRMDQpWa2wxUm1VeFEzWklOVVZ5VkROcGNubEZhbTlaRFFvemJWTTRSVkZhUkhKbUx6bEZZVXBWVjNsR2RYWmxZVUpWZDFCcmRUWmpUMmxFDQpZV0ZXUkdaelpHVk5Lell4Y1VKS09TczBhM1UyWjFoblNFNE5DbW8zTUZKSk5WUk5Xa0ZKUTA1dGNFRk5WMGt6WjFaeFJqZ3piR3hzDQphUzkzT1dOUVdraFZSRFZzU0hSNFRtSlRaVkkxZGpCYWNuYzBaM2xJTVEwS1ptSnBhWFJyZUZWSFNXVTNMM013VDNKSlZWZHBNVlpLDQpRM0lyZVRkTk1ERnZaamhrU21oMk5GbGxaU3N4T1U1c2IwSjRabVphVkdOWlMxbGlEUW8zZFhwTWFHODVPR0Z1TlZkU01sQlFZeXQyDQpVVWxZWm01MVVUWXJTRVZGVTFOSlIxaFNXbUp4UW0xclkxTkNaRE52ZFU1U1VYZ3paWFpJYzNnTkNtOTBVVGRNTW1aaVdUVkhUbFV5DQpaak0yUzFwUWMzbEVUR1JxZVZSWk1uTXJRa3hyZDNFM2RHZHBVbE5ZUWpWamVFSmxla2xIUzBkelZWWmlLdzBLWTNsNVFWcG9hRzV4DQpNbkpPUzBWRk5UVk1kakpLYW5CUUsxQkZaU3RrUTJoNE1ERXdTbk5oTm1sWE9IaDRhM1p5UWl0UGFEaEhlVE56Y2xoUURRbzRNbUpuDQpaMVpuYlVGT05rTkpNMUJFZG5ORlNGbDJURGRoVlhWb09WaHpOMUV3ZWt0dE5FRXpSRUoyYlRBMlJVMUJaV2hrTUVZMGJ6VjViVXdODQpDak15ZDFGV1dFSlpXSHB5ZEZaSFdIRXdWR0pXUldoUlkyMDRVV3N3ZGtGRFVUTjFkbGhaYUdwMmRFTTJXazFOVUVSTk1ISXJUa2xpDQpObGhtUWcwS05EaE9OMmxGWlRGSWVGSnBhWGg0UjJ0ek4xbDVURVJKYVVkU1FtSkllV1pxYldSdGEyRmxWVVpMTTFKTlQzTnZPR3RIDQpkV0pGUlVrMlZ6aFFEUXAxVUROMlZuUXZURVpuTUVSM2RHWm9TM0ZKYkVaSmNXeE9NM1F4VVZGcFVqZExTbUZaTTFkTGFITlNiVzFuDQplR3hJUjI5ME5FTmtSUzlsSzFjTkNscG9SblJXYldOM1dVRXlXU3QyVUdWc1RUUXpheXRSTW5OM2VsUTRNbVVySzJGRWN6TXhNMU5QDQpSbmxXYUVSdlpUbEpZV3h0YlVsQ1RIVkVkUTBLS3podVJHbDVZek5wWTFreFNYRlVjemx4TWpWU1VsSkNiRTVtS3pGWVdFdFJUVGwyDQpjMkpJVXprM2JYRnpWMnRoVWtKU01YWkJOekUzWld4eURRcHlTWEJ3UVVsWFNUTldSekI2VTNJM1dGZHVRbGQxYzJacFJrTXJjakIxDQpLM1ppU0hwSlRtZFdURmRCUkZGRFRVOW1OV05hWlZNMVVHSjJXVU1OQ21ocGMwVnFORTl3ZVZSYVEyeFNWR2RXUW1sUlNWRkZhbmRoDQpaMUI2Y1ZCTGRISlRhVWxJVkhwM1VtRm9NMmcxWldaeFZXOVNZMWROU1RscVV3MEtORmxCV0ZWelVDdGFOMEZzUWxwVGRHVjFiM2R2DQpORE50UlVKSldqbFVRbkIwZVRGUVUyWXlVa3B1UWtGR00xTjFRVXBKVFdKSFl6Sm9kM2xXRFFwR1YxRjZZWHBxTW10aFNXSkRNVWd4DQpVVEpaUVc1c2RVTmxaRzFoWVVNcmJsVlZXVU5TWWpoek1EZEZXWHAzU1hWMk0wUlBZV1JSWlhnMVNqTU5DamhVZHpaclJGSkRkbkIwDQphV3RVY0hwMlNsSklPRkp3Um1kTFUxUXdWbk0wZURVMVpqUlZWMUZNUjJsTGF6QmtObmxuT0VZNE55dGxkR3hHUncwS2JIaGlWa1J5DQpUMDh4V2tJeVJFUXJNRmxTWTJaeWEzcDVUVU5rUVZWTFRVNVJVVkE1VldzMGRXbFJiVGw1YldaYU0xSjJhMVpTV25oeWNVMXhEUXBUDQpSWE14UkRadVQySjFZM0IyVDFwQlN6WnBWUzlFY1VKMFJGZEVkRXM1V21GSVpXOTBPRmgzY0RBM00xRk9OR3Q2YW1SYVlua3ZPRWhyDQpRaThOQ2pReVJEbHhOVFUwV201UWRURXZSV000VERsb2FraElPRzE2UVdWeVdsWTRiRzVtTlhwdWVHaFZOMVJSVDFwaFQwSnZiMkpuDQpWRXRUTkVWaFpRMEtjVEJCVFVOTWMwUkdVRFZZVW5waU1UVkNLMFJ5TTNaQmIxbHBlblZDVVhGVVdFdzNiR3d2VDNneU5ESlFhR1ZZDQpUMFpCTnpCQkswSXhLM2gwRFFwVWJWSTBZMWx1TTNOU1kzQjRhVm95VERsc1UwNU5UMU51VnpoQ1JGbFhVVlZNYmpKTWFXdHpNQ3RZDQphV2RsUzNaSWFUQmtPSGhzWjFNM1pVb05Da0oxWkhNNVUyWXJiMGxhTDFKc1VFMU5aRlJXYWt0cU9WaFJaRGRzYlVad09EWklMM0pPDQpaRTFZVGxFM2IxbDZTMmR4YkV0RWMxbHZPWGRZYXcwS1dXMDFhREJTY1hvNVkyRk5ZVFZEVDJOcFpFRlZRVUpGWTFRMU1HMWFXSFoxDQpVa3hUTDBGUU1FMWhhVzVUU0doWmJVODFkMGwxTUc1a1kybGhEUXA0TjNZd2NGVm1jRWhMYzNObVMzUTRRbFUwYjFVdlltNWFZMHRSDQpVMEpuWXpaelZFSldkbnA1UzBzMFNVSk5XRkZIWlZORUsyNUJMM1EyZDFVTkNsUktkVEJtZUVkWFRGaDJPVEJaT0dWV1IyVllUVTQxDQpLMGh3TWpWNVJqTnNhSFEyWjA1Sk5WQlBSRlJHWVd3MlJXZEpSa0YwZVc5dVJuWk1ZUTBLTUdOTVJuaE5NRmc1VWpkaVIwdFdVWGQ1DQpVR3BaTlRSS1MzWTVWRTFQUVVOSVpUVnpjR2hMVkdaMWVuWjVVMk5hVldsak15OVdhVmxhTXpocURRcFBaVGgxZDNsbUwzZDVNa2xoDQpUalIyV2t0QlVEbDJaMjVLY1ZsbU5qTjBha1VyYTFjeVJVRkdSa2cyZVdsRVNUWlBObXd5Y2pScVJYVXlVVE1OQ2pGSVEyMVNObWh3DQpURE4zTnpZdmFtdzRUMlJoVW1ock1IcHVabk41VmtWUWJ6SjVhMVJUU1M5a0syWnNNbmRFVERsaVFtazFURlJPVVdsUEx3MEtibkl6DQpNVFZ4UmpOR1ExVktaMjB4TXpjNWJHc3JaMGx2Tm1VcllVNXpZMGhLT0hGUFdFYzJkWGxQWXpsR09WaFBWbkJKV0c1NlQyMU9RakZGDQpEUXBWTDNoUVZsUm1NM0pTT1ZWak1tRmxNUzlaTTBnclMyVlViMXBRT0VSbFJqbHZZMkpsZFVvMk1FVkJXWGt2WlM5SE9ESXdZMjlxDQpWMlF4V2xZTkNqSm5PWFY2ZFcxQlkxVnJLelV6WlhoUmExUmpNRVoxZFdsRmFXRnlRelpKZURCbFIyOW1Xa0YxZWt4TVpFWm1PRnBvDQpWMFV2T1ZwWFQyWllTZzBLY2tFeFNsVjJURXBFZUU1T1dHWk9ka04yUWl0YWRHOWtPVVE1ZGxkSlUwaEViSFJtYUdoU09WVTNRVXhvDQpka1ZoYjJaUmNqSkNUMmxhUTIxdkRRcHFhWE5IYm1WSFZVeHhkR1UyZFVoeVJ6ZGpNbk5vYkRWUlJWVXJhR3BxZDFSaGMzSmpPWEp3DQpORTVsTWtwc1ozaExkaXRSZWpBeVNqSnNlV3NOQ25GcmEyUnhXSFJ5YWtkUlVYcHhVVzVXZFhseWVETmFlbVZTUlZGWWQxaGFRa1Z4DQpjbk5hTjJsa1VrdENRWFI2Ums5blIwTXplRFJxWVZaMVRnMEtTMGhUYlRWUkt5dE5RbGt6YjNORVVXbFVLMDQyZWt4NGNURnhZamd5DQpOVWhKUkdGM1VVaEZlR3BRYTJOeFJsbFBLelJLVGtsR2RGaHBWMlpXRFFwVFRVMHJTRWR2WkVGNFoxWklhRlpQU1VaRk1EUkpRWGR5DQpLekkxVTBRMmVFSnBkbmhaVlVSd1RuQklNM2RPTWtRMVZXdGlOV014VVZreFZERU5DbTVHVjNWR1QxQkxhVTVCUm14Q2ExY3dWMUZHDQpNbkpqS3pGRWFuTmlhR3BqZDJkUFYyZHFURXBVZDJoaVNucHRiR1paV1RsMWJVMTJSR3BtZFEwS1JHbEpabE5RVm1VdlRFc3JTRkV4DQpZVWRQU0hWTFFtRmhjbFprTmpGV2JHUk5ObUpMYzJ4RWVWTnFOR05hYVVab1dWQnlObmxrUTA5T2NFazBEUXAxVEhOWlVIUnFOVXhTDQpRMVJtYVVSTlQwbE9jR1l6Y2sxTWQzcDRTakJPTlZwSU0ySldNV3RqYURSV01tVkxNRTlJVlRKRlVpdFFaRVZHUW04TkNuTkdUSGxuDQplazVLVkdRdmQzWTJVVVJvYTI1eVVGTnVUVlEyYkRRMVJrcHBiQ3R5Ykdsb1NYbHhhMGc1VDNGNmFuQjRkRU42WjFoeFIyc3JOZzBLDQphbUZPZFRsbFZWRklZMU5MZWxVeE4wazFlbVJ0YjJ0dFZFNUlka2haVTNoeU9ITjBRWFJUYkdKUU1teGtRbGRNVW1kbVZrbGpWREpFDQpkV2hGRFFvelJVNTRNMmcyY0dadVRGbGhkM0pEZUV4WVQyYzNWRWhqWldGR1VESndaRWRVYVRaSlluZEdjV1Z6Ulc1cEwzaGpRMVZrDQpNVVI2VTJOb1FXWU5DakpsTVhSUVJWbGhVR1ZsTURCMVRXWk9ZVGd4Y25WVmQyd3paVTQwVGpsNGRYZ3JhelIyVXpKT1JUQkZhek5DDQphRUpLZVZaRVdHZDRWbEF5VXcwS05DOXZSWFpQV0ZsS2FHaEpPR2RQTDJoMkx6SkdZMVpsUTAwM01WSldPRWRPV2tFclRFMTRTbkZDDQpja0U0WWt0NVQwOU9UbUpqVGtwTVVXSm1EUXAxTWtrelJHRTRPR3RWT0VONmNtcEhkMnRrTTBOSlZqbEhWVlZYYmxwbFQwbDBPVmRHDQpTemhLVDJkRGQxTm5Ua1ZrUjB0eEswcE9ZVGhUYzNBTkNrdzBOWEJ2V1hsSWJWZEhSbkl4VTNCRE0ybEdTa0ZCZFVwblZteEljMkZQDQpkRVpJY2xSRVZVRlBUV3MwUzBodkwybHpMMU42UjNreWJrMVBOQTBLYmpaV2NXbHJiRzVMTDBweWRYSk9NR2hrT0dGcVNGTmFTMngyDQpka1JxYlZnMmF6TkpkbmhaUTNFeU0xaHpibkJXVWxGUFNtOXVjV000YVRSWURRb3hZVzVoVTFCTEwwazJhMWREUjA1UmFHWm5RMDFYDQpXWHBXVDJJdk1HWXhVako1WTNwcFQwMVZia1ZKUWt0UWRrNXhhMVJYY2k4eWFGQTJkWGdOQ25SVVVUUk5ZazgzVjFabE1YZDNka0pWDQpPSGRWVlc1Q1QzbE1SV3hRT0RsVFpGQjNjMGxVU0dWcGQybEdUMklyZG0xSWMyZFlZbGN2YkROamR3MEtRbXRXV1RKV1YwVldaa1JYDQpXVTkyZUdaM1kwSkNhMEZ6YzJKTVMyNXdLekZ0UkZRNVRFZGtVSGhLY2tkSFQxWlpSbmRWUW5aRFpWZDVValp3RFFvckswVlpOalJ3DQpRUzlRYVVsRFJuUlhWbWxIVDFOVEwwRkVNMkV6VFVWWWNtUjRZamRLUTBkR1JYRmpOekpTTUdWaWRqaGlZbVYwUVdoVVVFSU5Dbk52DQpNVTlYWWlzMWFITlhhREF6Y25GVmRsTnlVSGh1ZFRoS1NIaHFPWFYwWTJ0UFVreHlORlJ0VjBRek1sSjNNR3hJU1ZGaFRFSkpVRk16DQpZdzBLZEZCemEwTlJOVWhwWmpCUGJrTmFMekJ3TWpCa2NqSkpaR2RtYlhFMGVUTmxWMlprU2xwWFZFNXdabEozVjFSVU1pdHpUemMwDQpaemh0VVZwMURRcEJjSGhRZVhJeE0xVjZTa1ZoUm5OaVpsQjZWRGxYY0VzMkwwOXNZMEoyTUZZMWFGUXhVRWx5WmpNeGJuUk9ZamxMDQpjR1JKV0RrM1VVcHlXVzROQ2pWMWEzZzVkREpwU1dWMlluQXdVeTlhU21KVFUwY3lSVFJ4U0VNM1pHWktRM3B2YkdSU2NGVTNSbWhsDQpVMGwxTjNreU9FeDJkMkpvZUhSTk1BMEtlSEkxUzFWVU1tSnJhWGxUTDFKcWRuaERlWFJ1Ym1SM2JuZEZSbWdyVWxaWksxaGphVTh6DQpURkJyT0hGc2RFNHJWVXgxWVc5d1NpdERVMkZJRFFvM1ZFZFBNMGRMZDFOWU0zQkpOWGxUVjFwMWMxWnBNSE5OYkROWmVESkZUU3NyDQpibmN3UlZsUVIwaEJOV2RXYnl0NldXRkRSRmw2YVVZdldVTU5DakoxYlhoQ1QyUkljMGR2TkVKMWNIWmFaSE0xZEU5WGEwOXJaRmxuDQphRVpyWmprck1qWkVTVmwxZFRWT1EzVldSWFpHYlZJeWJVUkZkMFZLU3cwS1NVTjFlbGhHU0ZWRGNHczBSV1oyVVhWalZFWlBUWGRHDQpOR2d2ZEM5MWFHaENSbE00VlZaMGNuWkpiRVJMZDNGVGRIUkNWMWhTU2t4cFVDOUhEUW8wVHpkT2FtZEhVMHg2VjJsR2VEbGtRbFJKDQpVVTgxVDBSTE9GUTBaVTVoWmtScVlrTkVUbUo2YURWaU5ERjZXRGRKU21jd00zaE5WV1E1YUhjTkNqVmpabUo2WVRKYWVXRTVTRkZ5DQpWalZXY25wMmFXNXVSMEp0VFZod1VXWmhhR2xSY1hReE1XVjNZa2RSWlVOdVlUQkpSWGh0YzJGTGRXaFBWQTBLYVRONU9GSlRTbU52DQpjMlpYUjNOTmJsbElUbkpMV0ZOdFJIcEZOSHBTUkRocVkyZFpibGMwVW5WVlNFSkdUVVZLWjJkMlVtRlNhVVk1YjNFeURRcGlLMkZpDQpUVTAxTTNVNU5FcEZLM0F3Wm1welkzQkVkVkpwVEU5c1EzRkpWWEpqZG0xUmRUWjJTakpGY2toSE5XWk9iVVpLVTFwTWRuVkZURWtODQpDalJRVTFaRlFXbHpha1F4VWpVcmJWWkdRMG92WWpGSGJrUXdOMWxyU2tSa1pUQjBkVUkzYVVKM2JHbHJWRlJaY0ZGdGJHODBjR0pqDQpORWszTmcwS0szSlBOU3RWTTJkUFZVdFpOVUZTUldzMWVGSjJibU5vU1dKTE1FZHZUbE5UZFVSblQyOVlWVzEzU1RnelZXaG1jblZCDQpiWFJHYlUxVVVIUTVEUXBVV21kUWRsVjBTWG94U0ZCV2JWSXhZV054YzNGMGNVazRZVTE0WW5KbWJqVldTVTlhWW5GemMzazVUbGxSDQpMMDlMTDBoTFdWSjRTamhSYkhRTkNsVnJkMlpVTWxGMU1VeFZla3RQTmxaalRVZHpLMDVSZDFkbk1XZHJkMDFwZVhvelFuaElka3g2DQpVVmwwVUZKUlJsbFFabXhCYTJzMFYzbG5ZdzBLVm1OSFptZFJZVmQ2ZDFwMVNHRlhZbTU1Ylc1bmFHbERRVFoyVjFKTWIzSkxZelJ4DQpkV2RLZVZkNlduTXlOazVMVHpSM09GWlVhREZQTTJGSkRRcE5ZM1FyWVhabGRtWnBaMlV6UkdSMFpIbzNhR2xyV2pGcllUZFRaMjQwDQpOakJvWWk5Q05rcDRTVlpyYWpacGFUaExjVmRRYW1oalVHeGhNR29OQ21ReVl6RklZelU1TjFrMVJEQk1ja3hYVGtjM2FFWkRkWFJxDQpSWFEzY1ZsRlVWTnphWFo1SzJsVFZuUjFUbTl5YUd4NE5sZGlSRTFLUTJkMFVnMEtVamhHYWpCQ2RHd3lZV1JZTWsxWk1UQTBaM1ZWDQpkM05EZFc1c2FFc3JabmRITlZJeVp5dHdUbUpSTmpORVRWQkNURmQ0UVVkaVJHNVpUbk16RFFwcFZFWjNUV2hOYVhwU1RsSm5hRGxwDQpMMjkyVldsbk1FOVVWMFZHYms5aWVsSnZWakJ3V1hvNGFuQkVSakZTTjNKclpFZ3JTMVZuZUhvNFJGa05Dakl2YjFaSVdrZElZakJYDQpjRVZWVkN0VlZqZ3ZUelF6SzIxaVUzWnlkVGhpVW5jek4wbEdURU5tVkZaSlpuQk1OMlpST1RSVE9YUkNURUkzV2cwS2JXUklTVXB0DQpaVTVYVjNKTldUWktTbmxQYVhWWVQyNUtUSEkyYzJFM2IwMXJkbEl2WVVwb01sQnVSV1JKWkVReWRGRklWRE5STTB4eGNrMDBEUXBqDQplVUpTVkRaalNrRnNWVXczUVZSQ04zZEVkMlJDZUdKUFJVWjFOVEZOVWpONmNHaDVjRWhrYkRkV1V6QnFZWGRDWTNoemJFdFdiMk5EDQplRTROQ21GclVXcFNiRUZJY0hnemFFVnpVVWRNZDFkMWFtbE1ObEY1UVRsbWFEQldWbWxxTVROMmNYaElkSEpUWm5WSmVEZFpTR05WDQpTRmgxYTFGTFRnMEtPV05tYWtORFMwUXZWRTVDVlRVM2RrNXFiVGxEY2sxMGNXSXdZazV1V21sb1pHTjVjbmw0UlZSNGJIaHRTMEpqDQpNMEV2VURaVlNtdG5VRkpKRFFwaVJWWllZbXQ2Tmxsb1dFZDNOazVrTTNCdU1sRnlVVTVCWTI5d09UbGFLemt6VEVaRVFXZEZiVlphDQpObWxWVURVMVNFaFBXWE5PUTJoQ1FXUU5DbTFDVjB0VmJtNU9iRzV1VjNGellscDRjR3hIZUV4a1YxSTVaMVJXUm5JelVGUlFlV0pyDQpRVzVFYURSbFZrUmhjV2d6VjBScGRIbDJWRkV2UWcwS1lqWllRVUUxUkhSME9USXdSblphT0hscGExcG9kemh0WlRoVWQxVnlVVFZoDQpkbEZSTDB4WFJEZHpXbFZKTjJRNVQxQnZLMlEzVGs1bUwxTjBEUXBtTjNKalJ6TXdkRnAzTldWc2JHaFdRVWxOVWxWM09HNUZTM1pTDQpORE5QVVdwR2N6VmhkRU5MVFRneFVuVllOVU1yTjJkYU16azJRWEJ3TUhFTkNuSkxUVmRvTkZkMWFHZHdkV294VkVaVVJEQXljelpNDQpSVmdyYUdsV01VSXhhSFpHV25kek1DdE1OazlCVEcxNWJGaHhXWGhzTkdSd1RWcHFSQTBLYXpOYU5EZG9LekV6Tld3eU5WTmpVVGN3DQpXVmhVZVdzNEx6Qm1hbTE2VVhkTVkxbFFLMGMzUWxGalR6Qm5hVVZCWTJvelRsSTFhMWxoTlVGU0RRcFhSMDQxZVhwMWNXUk1OMjU2DQpZbGRvV0Vsd1JpdFNlRlJyUlZCSEsxUXdWVm94VjAxQ2JsUjZOMWRSWTNNM0wxRXhWbTlVYld3d1pFRkhOREFOQ2s0elVUQXZTa1JtDQpVRzl0TWpnM2MyRlZjV1Z6VTI5Tk1rNTJjMXBxVFVSVVRXTjNSRVUxVTBwSE9IRjZWalJLVWpoQ1VWUXpaVmRoVlRCU1FnMEtWa1JrDQpNWFJJU1RKTE9HNUxla05yVVhJeVpUQnVRVWt5WldaQ1pWVTBWMGxYWkdSV2VYcEVaRXNyWjNsSllrbHdPREZXWVVNNFowTnRXRUpSDQpEUXBuTkU1aWIwVldZek5IUjFOdVp6Rm1Lemg0ZVdJdmJEUXZja0kzVVhkM1JUYzRZazRyVXpKSVYyNTJVa3RIVWtsSlRHTjRlbVZ6DQpZbWRYVEZnTkNrWkJjMDAwWm5SR2N6TmxaRVo2VTJsSlNHVlhVREpxTjI1bFRXeGhWazlsTVhkSWJrRlNXRzVKU2xadlQyaHdVbmhEDQpTa05EVVZoUmR6QnBjUTBLY2pCWU56RTNkRXBZYTFOVFJHMVVVVVpTVWpkNWVrNDRRbU15TW0wNU0ySjZlRGRCVlVSaEwyaHZkRUZtDQpOaXN5WVhZelJWZHhibWREVkVsbkRRbzBUbFpXYldwRVIwTjFTbmx3UXpWWlMyaHFXRE5QUTBjd01ra3lMMmhhTlRCMGRFOUdSRVYwDQpWRkozYjFWMFkxZEdiMEkxVkZZM1NuTm5Xa2tOQ21jNWQzWXdRbTFuWmxWUGRHRTVUazU0Y0VZeFdXRXhSMnRsT0ZOVVUwTTRaemMzDQpiVlV2VVRBMVZVeGlVWFEyUVRnd09ETjBkVlpuYUZscWVBMEtVRlV5UTIxVFJVeGpkV0p0VUZsWE56ZHljekI1ZERkWVJUSjNVVXgxDQpTMnA1VkdseFZ5dERjWGx3VTNaUlpDdHZPVTFTYUdOaksxUlRNM1ZNRFFwak1HVkZOMkZNTVhGM2RrMWhUR2N5UWt0b1NrMVFUWGhNDQpUblZGVG1RMVRFVkxTVkYzYm5WSldYWlVhWGxxV0dGVmRFVkJaRXhpVGxsd2RVTU5DbUlyVURjdmJESXhWbEo0ZEd0dVNUUlphVGgyDQpWbnBHWW1VcldIUk1UMUZsVmtGVlFsTnRTMk52Y1VkMGJVVk9jMVZCYlZFcmVreFhiMGR6YmcwS1JuWXdUMlpaWjBOamFtOWtaemwxDQpNalpKYm1nd2EwdFdUREJXYkRCNlZWYzFUMVoyTm1SSFYwRmtUVGxsWW5sRE1USm1aRkJGV1ZoaE1WRnNEUXBOVFZWSWVXaFdOREJNDQpjazgxTVZkU0wyUlpVV0ZpVG5OTFEyUllRWGRsWkhOM1JuVnBTM2xrUkRJMU0zcGpXVTVaY1hwSlprRm5MMHRvV0hrTkNtbzRaME56DQpOR3R3VVc1VFZUa3JlalZOWkhoQ2FsZzFjelJQU0dSbVlXVnBPSEpvUmpKU1VHZDJjamhuVVZOeGFVUlBhRXROUkd4Q04xTnFNUTBLDQphV1I1SzNJMVprMDVkV2g1UVdkRVozWnpRVTlHUVU5VlRXeFVjRFpXWkdGcE9EWlBURFZRVmtOWE9VdENibVZQVkVWd1QwUmphbU5wDQpUbkpWRFFwbU0zQXlRVXNyTURGamVUaG1WbkpYTmk5WmQxQkphRVI0VG05VlEyNHJSSEJaYVZBdk9HMXFVSGhwZFRCNVJUQmFaVEJUDQpTR1JTTkRVMU0yRU5DbEJKUlZGSlUybFJRaTl3TURSSFZXOUJaWFY0TldSbFZqQkdibFJ3Y1M5bldHazFkbkJxVjBsNFlUQkVhV1ZoDQphMUJVWkVkV1VTOUdWMVppVXcwS2NHOVpVRGMxYlhST1oyUktZbUptVGpNclV6TXdVV3BtUnpSb2VreHFSamhQYjBGb1FXNU9iMDhyDQpNRTVZY21WQldHbGpVa1JLWm1ScFpsZEtEUXBrY1RSVUsxbDVZblJYYkd4WGIyNWtORklySzJFd1YweE5kRTFKV0hKTVF6TlFTVFZ0DQpSMVZvUWpWU05WSnRUMVJyTlcwMk1uaFFZemN2UTJNTkNuVnlaM0J1VDFoek5rdDZkRE5uYWtKbFNEbHhZVTR4ZFVKamFrdzNWR3BCDQpiblJUUmtkMmRHeFNNM0lyY2xSWVNrbHBVakpZV2tsek16Um9SUTBLWVhRNVFVUk9VbEpGVkdSS0wybHJOMnd6Tlc1RlZtRXJSVnBqDQpSMHgxUlZJemVtVm1RVXhqYkhaTE9IUmxaMmhhUkRjNFRESkRabkExZEZkU0RRcDNNWEJKUlhnMk55czRLMGMyYzI1WVFYVTNjMkpGDQpNemN2VTJ4bVJYcDZhREZYUVdWME16azRhM0Z1VUV4T2VIUlZRbWxCUnk4d1ZFRTVMMHNOQ2pKaFpscDFRazVoYTFKb2JFdFBTamxZDQpSalY2TjA5RFdFUlRVRTVKTVdGMFppczFWWFZ5WlZWWWVuVkJUa1Z4Y1d4Rk5EbHpTbFpQVm1GelVBMEthaXQzZWt0R2RsTkhZazQzDQphVzlJUldSa2RWaEVUa1JTV1d4alkwMWhiVW8zTW5WdlMzVkhhWEY0T1ZGUVZYWndTMVoxWmpVclVVWjZaM3BIRFFwQlVFUjRlalIzDQpTa0pwVlU0eFptYzRiRUl5YkVaeVpVWktSVlpxVFhOYVlWZENXVEp5VURRelRuSklTVGh6V0dka05FZGxVRkJNWjFSSVoxZ05DbGRtDQpORVYwZUZGdk4yZzJkRk0zTURKS09FSmlSRzQ0V25oTlRsUndaVlV2TDFWaU5VdG1PVkZXWjJSU1NtNHdSa1ZRWmpNdmNtbHZhVEJ1DQpOQTBLZW1oblVVNUdMM1UyVWsxUFFuZFVibk0yY1hKaVEwbFhRM1p6ZVVkbFJIWTVkVU15YUVGRll6QlJaWEV4UkdFME0xYzRPQzlsDQpibFV5TmtsMERRcEplVGRwUjFwUlRVUjFNSGhSVkhOaWRYVjBSMGMxT0VNNE0weEtXRXhaUVZGQmNWaG1Wa1J3YWpKWmVGa3ZUSEYzDQpXVlpxYzFndmVtZzNia2NOQ21kWFVqZEpjMnQzTDJnMVlTOU5NVUY1ZEc5dU4xVlVPVkZPT0c5aVNteEJkbmhDTVVjeVZqbFpjekJQDQpkM0p1WTJoNlIwWTBlRTB2VEhsWFNBMEtkMUUyZUVOSE4xVldkRTV6ZW04eGJVbHliV3M1VWxacVVsRnJkbU5HUkVWclNXeHlPVmhzDQpjbGxsYVZoc2QyeHdXRTUxUVcxd1p5c3JSMWg0RFFwUVFXRm1ORFJyYUZaNlZXMXlRbUkxYkZBd016Wmxla281Y2pSSmMyWjVjbU16DQpTUzl0WTFVclVEUkhSRzAzWlRWRlRXdGtaamxyVFRWV1VFRU5DbVJTU2xoMUwxVkxWbE50U2tGVVVFWlZORE5tZERObVQyZHdZMEZzDQplVVY2UzNKTGFHZzFWa0Z2TVdGNlpYSktWSHB0TjJScVdUSjRNR1JhUncwS2JtaExTVFZ2YlVORmQwTjNSQzlRUzBSU2JIVmFkbVI2DQpaVzFRVmtoNmNGbHBTakp0Wm1sdU16RXlXRGxtVG1weFRERldkVVJaV2tkR1MyNVlEUXB6Wld4Q1NIbEpVVk4zTkZaS00zQkVUVGRqDQpVbVlyY0ZCNVFqSlJaR1JtTmpoRVNtbFFhM2x3YXpKRWVVTnlNMDlJVUhkVlFYSk9keXN3YUhZTkNrZzRNWGwxVTB0YWVGUjJSRzFZDQpLek5PYlRCMlIwVTRSa053Tlc5WGExWnlTVWszVm1zdk9FSndURGhHYTFJemFGbHpSSFZwUzAxU2JsaFBiUTBLYlZaWk1GVnJVVU5qDQphbkJtYUVob1RHeFdWVmhNTkdVMk5qWjBiSEpQTkU1a2RUaDRSekZ0YlhWVGRHUjBUV2R0WmxkQlozUklhMEZ5YWxKdkRRcEJOVXRTDQplbE5hWTNCeFYyUnNWR3BHUmxsc2NpOHZXa1JzV0hwc1YyWkZZVkUyUTNJdldqRjJhbkZ4VVZBMmRTOXpkMDV1UkhkemNXNXNSMDBODQpDbE5WYTA5aGFsZzFWelZrZGpOM01HTTFTRXhXTTJORVVrRnVaak56ZEhSS2JXZElNVGRVU1RZcmNHdHFTMWhWTWpkeGVuWkNaMWMwDQpZbTlRZEEwS2VIWkZUakZtV2tkRGFWSjJOSHB3T0Zob1ptaEVlWE5SWldaUE9FOU1ZVTVUZFdNMVFXOWlhakUxWm5oMmFuRlZURVJYDQpjRk5oT1ZacE5rWlJEUW96YTFSeU5IcG9XREpvVjJwNE1uUXZibHBMV2l0d1pWVmtLMUEyTkVscVVYZ3lTMjl1YzB4bE1UZHdNRXBhDQpVVE5XUVU4MVJVVTNja05SYTI4TkNuQjNUV2RxWkRFd1pFbDVNWGxLYkZwaU1XSlBPRWhIUjA1V1psUTJUbkZFU1ZCd2JUbFlOM0EwDQphMkZMYWpaQmNFVmFUak42WVdac1lrUkVUZzBLZGtsS1N6RjNVRGxTTHpFcmFYVktPR3RJTnpOelRYQmxhWEpFY0hVM1YyOUJkVEZwDQpkbWxqVmtsWVVHZHBja2w2Wm5CV1ZGcDFTR1pNV25sR0RRcDFMMnhST0RoclRuYzVPRUpQVmpWV2QxVnRNMFV6TkdFeWRtNTZjR2hYDQpVMVZoTUhWWVprUm1PRWxwVEVGaFYxTlllR2RNT0hNNFpGVndPVWdOQ2pSMWNsVjJaSHA0Ynk5NlpIUjVSMUpJTUZOQ2RHUlJZVkZYDQpWekZ1Ym1KUFZuZHRWbkpoU21wd1N5dHpNRUZ3VFhKT01YSlRObkV5YmpOb013MEtZM0YxUzFVeWNYQXlNa2hLTm5KUFdYVlZVVTVqDQpXbGR4V1daRFpVNU1iWHBzVFZwMk1tUlNUMWhUTUhoclozWjFRekpNVjFSQ1kzZHhhMUprRFFwNlRHMVFPSGhFV1U5cGNUZEpXV2hUDQpjRzltWWxkdWJrOUROekJUYUd4emRrcFBTbE12ZURaVVZVMVBVRkEyY0c5WmRuZHBkVmR4Ym5oSmNqY05DazlMUVc1ME0zUTBOVlpVDQphR2N2V2pOeFJ6ZFRkRTlJU0c1c1RqVm5UMVJUVjFONWFsVk9Wa0Z2TTNkVE5rSXJlRzlGVVVJcmNXeGlTVzQzUlEwS1dYcDJTak5UDQplWHBTTUZGalUzcFVVVGt5VkN0TlUxUjRTbU5hZVZaMU1XWnJNWEJaVlRSbmEyWXpVU3RLZFU1SlJHOHlZV0p5VVRSQmEwZEpEUW94DQpjVEF4VlZOSWVGVk9ZM2xJVGtkTlVYRTVRM2hQUzJoU0szbDFNMGd2ZW1OUU5XTndVREJuTVdkNWNEbFNRbXd2ZVZabE5sTnlkMWhHDQplVlFOQ2toNE5rdFpXSEJWU210TFkxUjBSbGx2V0VKdVpscGhhMHRzUlZwUWFGZHZiM05pVFRsd2JESkpkRmxhY1hoNk9VWkxia1JUDQpiR0oyVW1abFlnMEtSbkkyY2xRdmNEbGlXRGhWYzNKa2VVeFRhRGR5SzNOVkswYzBLeXRITldKUU0wRkdNM0JKT1ZaamVtUm5RbTkwDQpkMHRHYm0xTlowcDBXV1F3RFFwdmJtWnNXRXBWZVhKU2JGQkdObVV5Y1dwR05VWjVWVlE1VEhkbVVYcE1hVlV3YTNaQmJUQjNLemxQDQpSRzVzWVVwTFFXcDFXV2xuVTNreFdXRU5DbTRyVDBSNFQwbHpTRlJIYm5neGQyVllWRFpTU1ZNd2VrNXpjazVwYm5CcGRYSm1LekpNDQpNVGQxYkVSQ1lqazFXVVJtZFROcFUyVjFXRzA0WmcwS1ZtUnBLMGR6UW1aM2NFNXdPRVI0TWtsbFNDczVhRWswV1dsb1p6WllWMnRDDQpNRXhSVm1WQmVUQkNPVWhhZVcwMGIyRlVZakpFTmtGVmNuaG5EUXBYUm5aRlJEUnhWR1ZFUzNaMlZEVkhibWxWVFc5cVFYWkhlRWhTDQpZa0ZMUzBGYU9FNTBZVzVKWjFNemEwMDJkV1pqTlZCSVdrRkJWV3RvYlVnTkNtaHJlRmMxTWpjMk0wbDJPVmh3ZG5wc09HcEhSM0JHDQpRV2hSY1drMVdYUkNjVkJDTlhoblFWUkVaMUV6Y0hwb04zWkNPVzFuWWxJNU5rSTNPQTBLYVVwVlNYTlRVMjh5WWk5MmFYTmlMMWt4DQpNMUJ1WjBSa1FVVjJOelZqUlRWT05sRmFhamhtTUdaMk9VZzRjRlJpUjFodmFqaDFOV3RRTm5GbURRcERXRmRzTkdad1V6SlFORVZrDQpUalJuWkhaU2VYQm5VMVJ0YTI1RFFVNWpSbEZ5VWxocU4xQlljVk5WTW5CWGFrUlFaVTVOTjNaek9UaHBaVW9OQ2pSaFZpOUZkakZSDQpZVWQ2ZWxkRVZqSnBZekV3ZUcxVFl6ZHhRMXBEZUhwcFFrSktNR1JtVDNNeGRFWnpSV0ozYXpoUmNETlVkV0Z6U0doMVJnMEtOVXhCDQpNMVkxVkdOWmVrUmFOMDlEUWxWTVkxZEJjMkZRYUZGS09XUllUblJxUjNNMVQwNXhOWFJUZUU5eWRIcERUVWxITm1GUGEyTjJVVTV0DQpEUW80V2pOT1ZraDFPR0poTDIxTFNVSm5ZamhEVVZSQ1ZtRnFjWFJWTDBVMlYwbEplblpuVFNzeFMyeEZPVGx1V2s1aE5UaGhVVzU1DQphVFpwVTJNTkNtRjFZMWxDYWtReGRGVkdPVEpvUWtGcVJXaFRiR3czWkdOSWFEZGlMM0ZqY2tGNVIxUk9LMWRFUnpkTWFuaHpZakZVDQpUVzlXTUZoYVIybFhVUTBLSzFBdk9IcDRSVVZ4YXpaeU9EbHJZVE5DVGs1NFFuQXZVVUZDWVZkS1dXVnNhVlowYmpacU9WUm5lR1ZsDQpiSFp5ZFhaNlFVTlJWR3RvZDJSWERRcENOVWt2ZDJzelMwYzFjV1pJVDJWNE1WRjVOMXBJT1hvMFNrVm1VbVp5T0hNMVYyWllia1ZUDQpRalpaZW1wNmJVeFNWREZwY1ZRM2NHSXpPVWNOQ2tRd1VGWlJXRzh5VEdOVlRVSlRlbXBNUjFSbGVucFhNRVY0ZGtkeFVWTTJVRTloDQplbWhhVDJsdmRXbHdWSGRvZFhGQk5sZFdVa2hPUXpRMFZBMEtTVlZuVlROUU5sWldTMmszWW5jMkwyMHlTMVZHYjB4VU0waEVRVk5GDQpVREpyVms5RU5tRnBhMEZPV2xWUk5HcHJZVVJ2VTFsWEx6VjVaRUYxRFFweldqTkJkVlJxU2sxbGFtcDJiVlJaT0hCVWJWSktMeXRRDQplVk40V2pCMVRGWjZORXgzUVVJemJVY3hORlZPWlcxR1MyMXlWalVyT1ZwNVFXY05DbGhXUWpaU1UwNTNUeTlLV1ZWcE0wSlpjR1pFDQpjbU1yTm0xTFlsWTRaSEZ0U1daT1JGUTFVMEZtUjB3elZHcEhTa1pCYlc5T1Z6WmxNVXhVVlEwS05FbDFUQzgxWkc0MGRrSjNkSFJNDQpNbkEwVkhoalRDOUVVWE5JV25wU1RTdEhlalZpS3pKNmMyNWlNM1Y2V2tONmVFWk9RVXRVZVd0dmRuTnREUW96TkZKblpsQk9SSHBtDQpWVTVqVVU5cFRURm1WMDlwUW5JeU0zUlRTMlJEVWpoaE9XdHdZVWROWkhWbU5EZFBaRnBYWkZReFlrZzJZemRCU0VjTkNuRndkbXgwDQpkV3hLTkd0WlUxaElSVmh3TTJkUlQwWXliWGd2TmxKUllraERWekUzV0hsM1JuRXhRVEIySzNjNE1tMXlVR1V4TkdkaFIxcE9XQTBLDQpWMFJ6Um1WSWMxQlhUV042TVVFeGFrUkxZVnByWTFsaFJsaFhUVmxOVkhaNWJFeE5Ra1o2V0hKYVlXZGFkRk0wTmtaYVVraERObFZ3DQpOVkZ0RFFvd1ZWSk5OM041WXpKS2JGQktOMU5FVFZSRVowSjNRMGhQUW0xWVEzcHdXbFJ1Um1KeFpuaHdSSEE0SzNZMWVTdExOV0Z5DQpXamxhY0hKTldtc05DbEJPV2taU1RsRlNhM2RJTlhONksySnBNV2RMWWxkSWF6VjJTbkZOWkVvNWRpc3lUSEY1TkVOWlZIaERjRVJtDQpXVmx2VEVaSk1FVnhaV2N5TVEwS0wwTnNVMmhDTm01MVZEZHFSMk5FZFRsdE9VSkNWMWt4VjB0RGFVSnlhVEIwUWxGdVkwdFlSMnBVDQpXblpzZFVGMmNreFNUbHA2TWxJMmVFcG1EUXBUWjJWNVoxUk1UbVp3T0VSTlJVSlhZbFZsZFROamF6ZDNVaTlRWjFCaGVFMUJaMEp2DQpSbU5LUVROcllUVktaVmxxWW5OVVFVaHVZa1paU20wTkNrSjZTR3RKVFdNdlVYbHFXbWxLWW1oelFWVklkVFJ1ZGpoRFltRmlZM2RwDQpRMDVJV0VGTGVFMTJWVzlEYW5CWVdYWkVRalJaTTBwbE1EQnVZdzBLVFc5dVZpdG1XWE56ZWtwdGRsRk1XbWRMUjNWdmRFZEhNWEpxDQpObWR4UlRScWNpOUZTM2hvYlVOMlpEWk9PWGwwVURoa1QwcFVZMnhJTlhkckRRcFhSR3BtWkZsVlZuZDRUWE5QYWxkRFRtbFdMMFJVDQpTR0pXWlRWUE9EaEpNWEZvU205MFJIVnlZV2hYZGs1bFNYVm9USEl3YjBaV1NEUjFLMmNOQ2xadWNFdHlTbTFSZEhsbUwzSlJNbTl6DQpaekJrV0dsWmVIVlhhMHQzZW10MGFIUnRVRmhpUVc5WVNGWkxhV3cwYzFGeWNGaG1kbGxPT1U5akx3MEtkakF3UkRCYVJrMUhRbkZWDQplRVUwVW1kc2VHRm1VMnRWVVZkM2VIVk9jRUpsUzNCcEszTmFXWGxpZVhWbFdubFVRMVJuTDFGWGNIVklUWGRORFFwWll6WlFNblJyDQphVWhsWXpGalQzRkJjMWRNYld0ckwwZHNlRFpLTW5Wa056bEZSV2hCTVUxUlUzUTRhVXcwUVUwNVJIcGpNVU01ZGxFd2Qza05DbUZqDQpkSGhsVTNKdFNFZHhMM1pMUXk5U0wwd3ZOMnhuTkhWVWNtNXZXbmxwTmtoMk5XeEhOR053UVdsMlJtUjVNeXRDU1dWR1pHZDZMMnBwDQpWdzBLYlhwdVlpOXlVblZ3WVhSS1VrVnFaMEY0VDBkdGNVRjRkVnBKVW1wb1UxWndibUU0VFhWbGMyaEdNVTF2TmtoMlVGTXdaMWhFDQpiV3BqZUUxSURRcHNZVTlMTTJaVVZsQjZNMkV6ZFdrMldFSjNSblYyWVdOVWJIZGtWRk5JV25ST2NEVllURFJEY0d4MlkxRnBUa3hEDQpXVllyU0hSM2RIUXpUM0FOQ20xWWF5dHpSQzlzUWl0bk5WUjNNelJWZWtOVlFYRnlTRzVDWWsxM2NFNDJVVzF4V2s5bFZXVk9XbTFGDQpZMGx0UTNkM2VUVXlNSHBNTmpKV2JRMEtaVVpQY21Wb1JtMXdRbEJrYldKdmRTdE1RbFU1YzJNNVFubGhUMlZyVEVSMGJFVkJhREZpDQpablJ1YjFOckwybHNabmRqYkZGTU5FOXFVSEZ0RFFwSVVEaElSMU5UVm10NFMzVnBXSGhRUzFWcloybDJXRUZHY1hBeU56bFNlRUZCDQpMMmswV0hBME1IVk9aRTA0YzJOd05tRm5hRWhuWVhFNWVUY05Da1pOUWxFMVpXaGlXazUwUm5SRWRVNDNObkUxY0c4MGNEQTFORXA1DQpOVGROTlhoaFEyaHRPVVpXSzFaV1FpdFZaVEpoVmtrMmFUWXdXRzlNYlEwS1lXaHZkRE55UVdoQ09ETlpia3d5Y1dkd1kyRjBWelpMDQpVRlZzVlRKS01sQnFRMWxIYWpaemFFZzJTVlJvY0hwUGEwWlpWV1ZoYTNkRE1sRjREUW8wTVdOVVNURndkV1JNVUU5cmFrSTBkM1ZLDQpkV3BIWkRCVllTOXpNR2hSZFhwRGVFVTRjR281YjFwV2FYSTVURnB4U1Zka2NsQlNXRkZZTDJJTkNtdDJhbTVQY0c5eFNqTTNNVTkwDQphWFVyZVRoTllsbExla2Q0U0ZncmVtaDBZVlZTTmtsRWIwNHJjM2h3TmtGb1lXUlFTazQ1UTAxSE0yZEtUZzBLTkZFeFMyTXhRU3RtDQpRVkJxTjNkME9WcEpkVGhDVjBGTVoxZDNjekpQVmpGT2JIVkdXbVJITjFRM2FuQk5SME5tVjI1WlpIZHJPSE5yZEhVMERRcERWVzFZDQpjWEp5YVVsbVRFcFZNREF2Ym1sbUwzZEVjbWg0Vm1WbFIyY3ZiekZDU0RsbU1uZDRURGRFWms1UE5VZFBSVnBOVkZKbFJIZElOV29ODQpDbkF4TlVNd1ZsVlhjV2Q2T1dSS1RISk1Oemx2TkhVMFZVMXFXblEyZEcxcmFsZHZhRmN4WlVOU01FaDVOWEozTW14TWJVeFlOa05zDQpkek5pUkEwS2RYaFdiVGRhWkVoVVJFRXZPSFpaWlVkTldGSkRkblZaV0RaeFJHRnlkMUo1VVZOSVMyMXZVV2xtVTNOUllsaHBRbFJtDQpSV0k0SzFoU1dqZHlEUW8yVEhkM2RWTTNZbTlyT1VsclMyODFUMmxCVGpoM1RURmxOMm9yY21SemVtSldjVlkzVFc4eE5IbGFRV1pDDQpkblVyT1dsVlMxRlNRVkpEVFdrTkNtWkVSRzV0WmtWbmVVSXZWVlI1UTNwRlRERjFlbXhEY0dkelIzUlhUVVZTYVZoUFJYbGtWbE4xDQpkamhKWm10MmJHcHFhbEJJTjBKa1oxcG1SdzBLYTJKa1lqZ3ZUMDlFZW1SMWJqZHRXVVl5YUcwNGRGYzViWFpCY20xUE5XOHJWVk5PDQpNMUoxU2pWSE1VSkpaMlZZZERGamJrbFhLemQ0Y3pGdURRcFliM0ZCTm1aSWJWcFRSMjVYU1V0clIyeEJSMWsxTW5GU1IwbDNkMHRuDQpiakp4ZVZwQ1kzSjBWelZVUkdoTE5GSnlMME14YURRemNEQlNhVVFOQ25ST2RWZEpTVlUwWjJGbk1DOHpjbTlqZG5OMkx6WXZUbTQyDQpNbHBFTDA1cVdFSnZPV1J6ZDFsb0wyd3lVVXhhYVZGU2RFaHNiakpyU0hjclJ3MEthVlpMTTJ0aWJpOU1jRkl5U2xSTlRURm1jSFpSDQpPREJaUjJScFpqbFhSamRwYVVwaWNXZEdjMUIwU0U5VGRYWjFWVkUwWW5oVWIwdHhSamhsRFFwdmRscFNSRnByZUVaYU5uTndTVVJUDQpUME5VT0ZsNVExRnJiRXM0UzJwQ2RHeFFkMkZDZUVkV1lWUnRNM1JYVWt0b1JFaEVVVVpSVnpCSFoyc05Da2N2ZWpGT1NHbE1XVVJYDQplR2hXVDNweVNGWnhiR3RQVjBOMVlXVjRPRTUyVG10aVFWVTBaMjE0TUV0MkwzcGlPR3hFWkUxcGVtdzJSbEJTY2cwS1pUaHdRVUZwDQpTREZZVDI1NldGQTBWMk5VY2tSNlpHTTRTR0o0YTFKV05rWXdlSE5yTWpGVWRUa3JMMEZLVDBJNE5ETjNUVU5SYW0xaGNIUkdEUXBzDQpaSFpxTDNwWFdsSmpRa1J5WWsxQ1p6ZE5OMHQ1TDA5Q2NrMXJZbFJWY0d4MU1rMXVkelF2UlhOM2F6QlpaV053VmxsMFNuQjFaR01yDQpSVEVOQ2k5alUwVjFOWHBwTTNWUE1rdHNVMHRxU2xsb1dIWlRZbUYyY0ZaVFpXY3hOWGhLVTBveVNESlFPR0ppTm05T2QweEVUMEpoDQpLM0IzWkdFcmJRMEtLMlIzWVVkaVFXNDFUMFU1VVhwcFFuQmFZa2hLTDBzNU4xSXhabGxxYjFrNFFrNU1RUzlKY0dOV1RITkxSbXhIDQpRa3BPWWtKQmNFTnFkRVpGRFFwQmEwMWFNSEYyTldaT1RVOVdSRE5xTm5weUwwUmpZMjR4Vm5KclpHMUhOVUowZEZsSE4zaE9TelpLDQpiR1ZIYzNadmFGWndhRTlCTTFGT1drd05DbGN2VTBkdGNrNVpTR1ZPWWpSSWJreG1NekpxYVd4MU9WcE9MM2RsVjI1aVpIWnZNMG9yDQpVRkY0YTFrM2J5OXZZaTlyTTNJd05VSjZVRlp2UlEwS1NHdEplRzFQUnpsdk1rVndlV1F2TjFrcmRXRnVlbk5JWkhKQ01scFVNR1ZCDQpjVVpuYjNoaE5WSm9hMXBaTDFwc2FUWTFiMUJNZFVRMk5VcEpEUXBWYzJzeE5rOTJRa0ZKSzNaM01qQjNNM3BwY0hRck4ydHNhSFowDQpibVZvVFdOQ1VVOU5Ra2xTZUdwU1NXSk9NU3R0UVZCUlNVOXRSRXgzYkc0TkNqZ3pUV0Z3WlRWaE1UZFNaVGxEWkhrcmQxUk1UMWR4DQpaVzlETlhGaVpXVmhOakY1VkdZdmRuSnVibGhSTHpNMlRHRklOa1Y2TmtkNlRHTm9iQTBLZFhGaVJtRXpURTFWVlc4NU5qSnBkWFJRDQpVbFJsZDNNek1rbFVWemRZSzNoRk5sbzFSalJ3WVUxdVRtSkZTMFJoZHpWSlJVOVJlRXhDUmpOb0RRcFRLMnRwZVhvM1pXTkZaSFZ5DQpVREZNVkV4TFRrTjNXbUo1VDJKWlZVTlJjeTlSUW5WTE9GbGxSbWhRUm5kbVNERklNbWxtUm1aME5XMVdZMFFOQ2poWlVWRk9PWFEzDQplbVJrUzFkSE5HUXpWV014UlU5dFYxSXpkMjVFUVV3d2NreDRaVXM0VjFFeGEyWnNZMkV3YWk5SGVUSkpWVmxETlZCcFN3MEtkVEJaDQpibmRTZUZGWFMxWmFjWE5xUW5sUWFIVldhVU5UWjA5R2FGUnVVMnBtYUhoamMxaFFaWEozYkVWSGIyWjBkbGQwV2toVk5FOVhjREpIDQpEUXB1UjFWMFQwMXRZMVF3TURSSlRUQlZWVlp3UWxJeFJWaE9UM0ZoYVVSYVIxVTFXR3hOUmxGRGJsWlpUbWN4WWt0b1NURjFXVFJoDQpLMnhaUnpFTkNuRXhUamhrVkZsQmJrWm1jM293VTNjd05VTjZVVEZNTlVwaFZIZExVR3BvVUhnMlpHVnVhVlJHZWxOU2VYWmFaQ3RsDQphbG8wT0hsd2MyOW5SQTBLY1ZoNVdVeE9SRW94TjNSUGQxYzFRMVZpVlZGT2RuaEpiMU5aV2tGdlRubDNaWHBwTVdaUWIweHJOMXBZDQpjR2huVFdoV2FsVk5kbVpIVFc5MURRbzVlVU5GZVRKNVZXMXhWRmc1V25kVWFXTnBlVVE0Wnpkc00xRmtRM2xzV1hSWlVYUjJWbkpEDQpZMXBFUmpKUVYwMW1VVGxDYW1SMU4wbEplVWdOQ2xRd05qbGpZVWxGZFV3eVpUVXplbTFpUTNGa1UyVnRhVUp5YlRRelJrdGpUazEzDQpiMU40ZFhCRlJ6QmxjbXhKU1RGTFdsUnZWekYzVG1aNk5BMEtVa05oZDBveGJDc3dOeXRhV2taVGNsSXpUamN2WldWeFUwdFNiV0pXDQpOa05YWkZWQ09VNXpka1J6VTNvMlF6aFZXRVI0V21SR0wyUm9kemh3RFFwSWVYWXpSVE5NVGlzMVRIVjVZa0ZQWWtSRE5WRTVTbXBPDQpiVzlwT1daa1UyWlhkWEpIWW01eVJtMXhiVlEyZVVsUVp6VmpNSHBPZGpsdlFrUU5Dak54U2pab2IzcGpNbEZIWkhwWVYwTlhWRm94DQpZVlJVVkRZeFNHdFdhRGMwUVVkTk4zSndTVzFqZDB0NVUxSlFPSEpTTWprd1JEbDNRV05NTlEwS1RVZDVWR2RzUWxJemVrNUpXblF5DQpjWGx5TW01cFNIQnJWVFZ4THk5TGRIZFVVMnN5YTA1M1NHTlVObkpUVEdsS01WVXJhV3hKVkhoeVVIVnlEUW94U3k5U09HOXFZVnBLDQpaR1psWkZoUGVXc3ZNemxwWkVNNVFXVjFiV3BEV1VkdVdUSm1aR2xrZW1sWE1HRmtSV0U0TmpCUU4ybHNkMEpuWm5ZTkNqZE9SVTl3DQpUMjR2YWxsS2F6QmpPVGRsVTIxR2MwUlNMMjFvTWpCWVFqaExUVkozUlRCRU9GVXhTemw0Um5OdkswTXdkVkpIU0c5VVdGTmhidzBLDQpUVk5CYW1KaE5HVTBiMVpGUXpSclNGQnlhVEo1ZVZORWVFTkNUMGRuV25kb2RVWnpNWGxsY2xGMFdqaFpXRVp2TWxGSFpFUXlRMjAwDQpaUzltRFFwUGVWTm1hVFpZWkZCTU9FRlJRWEZ6TjJsSlNrSnFVbTUxYzJGWmEyRldMMkpYUjIxeFR6VXJTMUkwYmpGS2FVeHlObEZqDQpiMHBaYWtKTVlsRU5Da3RCY2tSTFMyWk1RVnB1YUd4dFFrNVJNVk5KZDI5NlNEVnVlV0pyZWxGUk1rRjJVMXBoZVdwelQyUkRVVWt4DQplaXRDTUhaUU4zWnZZVVZpYlEwS2F5OWhkbXMzTlRkeFFrRlRXRXczZGpSb2JrVldTR3BNZFVkdGVrcGpSM0pKTUdWMmRISnlTa2hXDQpXazlLWkM5NlFWYzBkRWR3ZW10ME9IVnBEUXB3VFdSNU1HUnVPVTl5UkhGS1ZURktUek55VW1kdmIwRlBUVFF3Vm5FdlVscFNNSEEzDQpNalYwWlZwMFoycG5iRlI1U21ScU4za3hZbWx2Y1drTkNtcHVjSFJHTldsTWQxVk1iakJMVTNsck9XMHdNMFprWlhGcVQyeE1VakJHDQpRbXQxY0RkdGIwRmlZelUwTXpsWFJrZDRjREYwTVRaaE16RjFkUTBLT0N0SFRuWnZXamxpYUU5TmEwWnJhR2RwZHpWTVVFTXdaWHBMDQplbU0xZDFwWVprWnNlR3d5WmpoUk9EVmxXRW94VFVwaWVHMXhhSGhCWmtWTkRRcHhjMUZtZW01dGJ6aHNjSEZEUmxGNldYRkJjbVJUDQpia013YTJsdlduWllNbkZ1TkRsYVNVdEhPRlJTV1ZGb1VFNHJXWFpuUlVoS1lUZFNaamtOQ2k5ck5rTlFXVVkxT0VNelkxVTJNR3RZDQpNa3RYUmt4aVdYbzRWVWRMZVZSMGRFb3pLMHQyYWtGcFNXdHpSM3BCUkhOUGFHNXBXa2RsVlUxUWVBMEtPV0ZZY0ZCM2FuWnpNME40DQpNa3N6VUdOR04yNHdUelowVmxkSVkzRnZTblZ6U1dka0swTXdURk13YkUxaFJFVkxOMU5GYnpaeE5IY3hURTFxRFFwa05qUTJRbWczDQpOM012UlVaVllqWXlMMHR5Y1hwQ0t6Tm1ibE5DTURSdFdEWlVSMGdyWmpCQmJtc3lTMnhXUjJvd1psVm9XVk5vTTB4NVNIa05DamN4DQpWekZ4TDJaVVRXaGlTRTFEYWpGcFFUTlNhV0Y1ZFhCTVQxUkNVRk4wZEZaSlVrMXVWak16YTBwVGJEWlNXRGhXVEVSNVR6SmxiV2hEDQpNZzBLT1haWWNubEhPRzFXTmpreFNYZ3lZVzkzWmsxdlpGQmhOV1JWTUZaSlptb3dUMmxNUVZCR2NrUTJNMVZxZGxSU2JGVXJTV00yDQpUR3N5WnpjdkRRcEhiVVk1UTNjMEwwdHVhM05CU2tSUVZXRlFTMk5VWkZCallVaEdaV1J5ZEhwNlZVazBTell4WkRoSlZFSnRWVnBMDQpOMnROVDFwRWEzaFdTR3NOQ2pFeFNVRnBWM0EyTWpoaldVTkpMM1V4ZDBGUk1UUkJhR2x3UlVoNUt6SXdaRkJzUW5SMlpGWkRNR00wDQpRV0o1V1hwMU1tTklLMU5uTlRKMGF3MEtVaTk1ZVZBdlZuVlFVbkF2U1RkU1dXUXJhMnRhZW5sWGIwNTZRUzk2Wm1welpsSnFTRUZ2DQpWM3BUUzFwRFEwaDBVRGxLWjBvMmFuQkdUWGRsRFFwWGRFTjNVMWRDV0dFeGRXZG9NMnBDU1hwa2FWUnRSVzlMUVZkRFJYQldTRGxODQpSbGhKWkdGaVNqVnZhQzl0ZGpoVFRsa3lObGh2VWtKdFEwTU5DbVUxYVVOcGNtTk9WaTlvTVVkbUt5OUVRM2N5YWxsell6aFFTVlZYDQphbkZwVVhSYWQzcE1hMWhZVm5vclkyd3lUMkpPUldJM01HRnNiV0YyYmcwS01EQnhaRWhETm0weFRrWTJiblpzY2tveFJqSnBWMnN2DQphblJCTjJ0MmJHMVNOelpsUTNneGFIWkxWa05pT0U5MVNUaHVlbEZxWVROd1pYcEZEUXBRZVdJeVYyUXJWSGNyTDBwRE4wNWxkV292DQphVXBvTkZVeVlVbDJhMEZLWkRCRFoyOTROemRpTjB0SUwxaFJiSEl4ZURneVMyWlpaVzR4VG5JTkNuUjZibVZtU21VMU16VnBjRFpNDQpVRXhvU1ZkNGN6QjJTMFpvWVVsV2QzaFlkMHBoU0dSaGVqWlhXU3RWWWxOWWRGTlBZWEI1U2s5Q2NGZENUUTBLY2l0blpGQlRSRTg0DQpiWFphWW1GMFVtRXlhRmRtYmtwT1NEZGxVRmxzY0dkb05VRlplR0ZVUmk5TmVITlJRbXRwZVVORFJFRlBNVUVyTkZaR0RRcDRVazkzDQpZazR4Vmtad01sTXJZMk42VFdSbVFYaHJWRWRJUVU0eVJXVndaekJ6WVZZNE1UTlJNbmMyY1c4M05Dc3paRzA0YzJOeGVtRlhSMmtODQpDamxaY2xSamFXTk9ZbmhNVTNJMGVWZ3dZVkp4YW1WVFUwTjRTbE40VUhkWVExWlNSVkZXTmtJNVIweHhXVEpXYUhSWFNXSTFUbWMyDQpkV0k0V1EwS1NVMWhaemx6VkVoMVJXSXhNRWt2WVZjeWVWcEpaQzl3WW0xelVqWnpLME5QWjIxcFVtUlpXa0YyV1RsSVRXdGtMekpNDQpUMXBLYjI4MVJUaEpEUXBKYlhKM1RVUmhNVEp5V21zMlJWbGlVV2R0ZEVNMlNrVkZla2xJUldZME5XZFVSVE0yT0d3ck9IVm5ZM0ZNDQpjMFpCUWxSWmEwZzVZWFJQSzA0TkNrSkdOVlZQYjFaYVZYbG1XbWRSU1RWSU1HWnpOR0ZVTlZGVmNteFdSVkpWVW5KQmVFRlNiMlEzDQphMXAyYTJKTE0wVTVZekUyYzBWTk1sSnlOZzBLVUV3dmRHTlpTRzlWTDFrd1FrbDZNM05pYjFGNFJVNURTemh2UjFoNWRWUnpVRTVCDQpjalZMUld4amNFazJjV2dyYW1kU2RubzBaakZTYmt4YURRcE1lR1F4V25VMVQzcFJWWEZEUmtsU2JVNWhaMkp5Vml0dVRTOTRNVlZ3DQpaRTFoWVROalFtc3hVVFZ2VldkRFdHeDZMMGhMSzNWcmEzSnpkRVFOQ2tkeVRuaDFVbE5XV0ZSWllWZDNTbVpzWmxwR00yZzNja3B0DQpWVXBqVWtaM1RUVjJObVozVGpkT1pFVTBPVnBqY0dRek4xTkpNbE5TWkN0TVNRMEtZVzF4U1NzME1IcHljWGxXZW0xU0t6bENURFprDQpiRGt2UzNkRVJtRkhUazFFTVhsc1FUVTRTemt3TTFGSmNXeFplazVMWVM5eFIxY3dZaXRRRFFwSldqbHdlRTFxYlUxclYxRm9SRTB4DQpaRTh5YUhGemJHZGlORGhKZEhveVQwOW1PV2h6UlhFeGNVbDRUVFJvWW1wb01XNUZjM2RuYTFOck1GZ05DbEJaZUVWMk1tWkpVVWhQDQpPVWwzZVVNeGVUbGxOR1F2SzA5RGVuRmxPSGN4ZDJGQk1pczNWMlozVkRoNFVVb3hWMGhDVW5WTlpHWkpNazEzV1EwS1RraGlXV2c0DQpVSGRuVWt4emVITjBNbWxZY3pkd01FNURaV1Y1YTNwS1lVb3dSMEpKTWpSR2VtdDNTekJVV1c5Q1N6WlZVWEZoV1hGSFFrNTNEUXBXDQpkRkZCZEdwcVZuTk1hVUY1TWxOQ01FUnFielphVGxKalJqQTRURFJQVDJNNGMxazBOVklyV0ZkNFVHVldVakptSzFFdlZUZzRZbGRhDQpSalFOQ2l0VlkwaDFRV3BsSzIxdVJWcGFZMG94TVdFcldHVnJTakpSVjBkemFXRlNTVzlCTVhKV04wZ3ZXVGN3YTJaNGIxWkdjbTVHDQpPVkJNWVhKTFlRMEtjbVYzVWtGUUsxSmhWa056VEdSYVdubGhPRzlUVldvM1JYaEtOelowV0VWblFtczVTMW8xTVVRNVduUkVWazl5DQpWbTlsU0VOdWRrcHNNWFpSRFFvM2VIUTVlbm8yWTIxM1RrUjNSMEZNZUhsa00wdHhkWEUwUzAxaFpVNHlWM0p5TkdaSVVIWXZWbk5IDQplRUl3Ukd4SGJWRjFVV2M1TjNaNVZub05Dakp6ZW1WdlMxQlhXbFEwYTBKWFFtNXRjemgzZDNVckx6QXdaMDlIVFhwWWFrOTROWEJWDQpTVWRPYmtzNWFrZHpVRmxVYm14c1JuQm9ZMFkyY3cwS1JrRklZUzlxYlROU2FEQkdWWGh2WnpsMWMyWXdRVU5wUm5SbFpXazVka1F4DQpVWEp4TUdSR2JrRktZbkpHYkc1UkwzUkhMME42YWxWSFJuZFZEUW8yVFRWRVp6SnNUR0Z6ZHk5b00zUXhNbXRvVW1sb1ZHTkhRazVyDQpiemRLT1RZMFJqZFNWVzE2WmpVNVUxWmhhMFY1WkZsdlJ6ZDNTMUp0Y21RTkNuWTBXVUYxYmtkaVpVYzFiRVF2ZEVoelpGbDBjM2xaDQphekZCVUVaUmEwaDNaakJaYVdOWFUxSlphRlJVU0VVNVptSkhjbUZvT1ZaWE5VcEdRdzBLT0Uxb1YweGxTMVJoVkdsVVN6ZHNRVkozDQpSeXRLVlhBeFlTOVFhRXRRUW01eVZXcG5aUzh2UlZwRFRETnZkR0oxYUdONGFEaHdkSEZyTnpWeERRcFRhbFFyY1dWSE5VMUNkRVpLDQpSRXRSSzJaR01YbEthVGd3TlhjM1ZqTk1aMUFyYlV0U2ExaFNjMWsyUjJKVU5tSmlRbHBsVWpsbVVrZFlOVkFOQ2tjMFZFUnpabGczDQphRlpoYVRsNkwxVnVjRGxYY2xvM2RrWjFXSEZFVUdaVGEwMHdWbEl6T0VodFpHTjJTMUZzV1hZNE5ubG9NME5YT1hKS1RnMEtaSGxVDQpWVlo2YTFReFJtaFZlV3RPYkhBMlpDc3pTbXRrTTFrNFZWUkdhMnRRVWpaMGVHSkZaVFZZY1hrdk1ITkZNbmw0YVdablkwcHhaMk53DQpEUW8yZGxodVdIRkVPVXA1T0dRNWRESlRRMjlxY0hNNE4wVnphVU5FYjFOelVFVTNhVVYyYW1wVlQxQlFiRFpOVFRBM1VGVkxjMFZVDQpaMkY1UkRFTkNuQlNkM2h0Y25GMk5XcFFiMU5VWVZSM1VWTmljV1UwWlVNeWNGTmhhVEJIT1c4MGVWSk5ka1pEV21wUGF6Qm5XVlZEDQpVVzVJY2pjeGN6UXhaUTBLTWxCRlVWSjNWbk0zVkV4QlJWbzVVMHBOY25kUVRHMWtOVlphV0doTE5EQjFRbVZTTjJ0eVVVZDBOWE5pDQpVM2h0YXpSa1dVZHdOSGs0VVROVURRcERhbEZ2U1RWS1NVSXJSRmRKWlVoc1VsRkRPR294Tm01cFFsTTBMemRJVEdkTU5FZFpUMjVZDQpkMGw0UjNaR1UyVTNWMFpqWjNkRU9HaDVVMVFOQ214cmMzSkVlVFZsWkVSNVZuWldOR1JtVFVwbU9EaDFjMHBMTmpCaFN6VnlRazlxDQphbFpGUlVoNU0xbG5USEl4TmxRemEwOUZNaTk1UlhCcUx3MEtTWEpzYlhkSlJ6ZFJTRVJ3U2tGbFZIQjZMMGhxYkZsdFFYSmhNR0YyDQpVazFYWlZKWFlUQlJTVzVpUW5BelR6QTBSbEkwVEhaTVJGUmFVbWxtRFFwSFJIcEVVMlUwUkRoMk9WUXdTakZXY1cxNWJXbDZTWFZzDQpRVmQ1TkU5dVpDOHdiRTlqUmpsdVluVnlhQ3ROV0M5YVRIVmtiR2w0V0U5dGFuWU5Dbk16ZEd0WFRFOURLMHR1U0VSMFVXbG9kMUI2DQpZelVyVmtweWFXaHZVVzVRUW0xR2NXZG1UazlvVkM5M2RETnBTRzFVYUVrelIwWm5Ra3RGTWcwS1FtcHZUbXhvWjJSSUwzSkVXSEZLDQpMMGsxVlM4d1QyWmhjRzFMSzBkTk5rcHdXVlp5TkhoR1lVZHZTVEJDVGt4aVoyZHFTakpRVm05c1dqQjREUXByY3pORWJ6RTNjMkpvDQpUazVhWlZWS2NuUjFPVXc1U0RFeFZ6QXpVVXhYVTAxWVJHaEZkelYzYTJoYVNVSjFkbmxNV25ObWFtWlpLMkYxZDJrTkNsWlZOMVp5DQpVMFJ5UjNCUVlUbGxOREJMZDFZeksxTnFNbTFrV0VwVWJHWjVUWHBYUkdkalkwbFFUa1YyUWs0NVNVbHBVV2RIV0dOUlNFaFBNZzBLDQpZVEIxWmtGaFFXRnZSMFo0Y0V4VmQxSllkbmx2ZUV4TllTOWFlVXR0VFhKRmNVdE1lRVJ5TUUwNE5GSTVOMUZKUVZScVZVVTJhVFo2DQpVbXA0RFFwVFNuaE5aemcyZHpkS2NtOVViMVYxUzJOcVJrTkZZblJKYkcxbVdXTldkM0pyT0haNFlXeHNOVFJLYnl0WlFYSkpZMWx2DQphbTFJY1dGVlpHVU5DbTV2WkVNek9FTjBUV2hRY3l0UFdXNUVkMHRSYUdSelJrMXdRblJDYVVwVVJXNXRORU16Y21wSU9VMTFWekV4DQpTM1pRUWtNd1drMVpRbEZLVncwS05EZEZSMFUyTlZaWVdUaFpMM1J3WXpSUVpVY3pWREZVYUdONlJsTlRjR3RQWm1oSU0ySjNkMlZ2DQpOVEF5WVc5UVZXWjJhbXQzU1VSYVpYUjVEUXBoWTFOUk9XdHdVWFoyU0dKdGVISkZURlZzY2paUE1ITm1hbFJJTUhWRGJGSnBNV1ZsDQpabU5LZURoV2JteGxSRWQzY1ZCU05pczRSbGhGZHpZTkNqVTFUWFp2VDIxRlZUVm1RVWhrS3pKcVpFaFdNSG8xTDNaYVIxTXJhVGhYDQpNR1ZrZDNCalNqSk1Ubk5VYms4cmFrdExiRkJyTkVOWGNWVTNSZzBLUkV0bE1VMTZaR1JqYzBwdlozVXlXbUUyZFRaR1RYRlBZekZSDQpObFpoYjBKNU1XZFpkbTVETjFGT1pqZ3ZZVVUwUTBGUk1HUlNXRzl4U1RkMkRRcG1iSHAwV0cxVk9Xc3djbk56T1VGUlpWSnJWRTB2DQpjVE13TjFoeWRqWlNPV3RXZVROWE1sZEdRakIwU2pGNVJITlVja3RZY1VacVlXTm9ZamtOQ2pkVVdIQnBXa0ZLTlVwSWFFMVBUazV0DQpVbGhLVW5Gd2RreE1SRVl4TVc1U2MxZG5VVTVzYVhKbUwyeE5ZV296Y0ZWcVZtSjFWbnB3WjNsb1pnMEtSMEVyUWtSME1IUTBaRFZ2DQpUVlpoU1N0T1EwUmFUMDlEVG0xS2NqbFRVV01yTUZSb1ZsZzNaMUF6YkM5dFlsQnZTMjl6WW10UVFscDZXRWd4RFFwTFZXUkxZaTl5DQpjMFZVZEhkTVF6WktLMlJ0TmpNNVR6TnpSMHBXVWs4elpsZFZabFJDUXpJeWIxcGxSemxRUjBWT1ZrVnVkMWRaYUhFMVJXVU5DbVIyDQpXRGR4VW1OaFlWUllkbmw2TDJ4VWJ6UnNURk5OWldWWkwyMXVjVUpaWTJKUGQxSXdSR2hRTm5reE9FcGFaREJ1Ym1NMGFHRXZVMlY1DQpjZzBLVVZaNldHWlZaWFZSVERSU09XcHJkVU13TVRScGRrTnhTbXRUUTBWM2FUQm9iRVF4WW5wVFRucGpWek5YUWxkVE56WjBURGRGDQpUV2h6VFVSTkRRb3hZMGxhV0dSNVoxcFhNRXRUT1hSeGIwY3pSbUlyUkZoelptWldPV0ZXYkd4dkwyVlhNMmhhWkVGVE1rUXpWRmhEDQpXWE5aSzNKV1R6bDNiVThOQ2xCelIyWjRiMmxTYTBoVlFVd3lOWEpuTkVkc2VUWkxWMU5KYVVaS1RHMXdkVzlrTmpCaloyMWtjSEpQDQpRWFY2YkRKU2RHVjFaMWhMVkdJNUx3MEtaSEI1UnpZdldrRnBNbFY1ZEUxTlYxRlZSRTVyUldKeFkydDVVamc0WlVSWU9GUmhUbFpuDQphalphTkUxVk1qWlhaV1J2YVZWMlZqQnFkVE16RFFwT05sUXpRMHRNYmtWQlJqTk1RbkJZUTFOd2JUbHJSV2syVFU4eVdVcDNTRWRzDQpVazlpVW1Sa1lWQjFUMDlpYW1SWlNWZ3hOekk1Yms5QlJIUU5Da2g1YjI5WVl6QXhjamRTSzJKeFNTdHlTR2s1YUhKdWMwTm9WbmhyDQpZVmR5YzBWNVkzaERXUzl4Vm0xQldGbGhNbUZKVjI1RlpUTTRMM1psYVEwS1IxRjJaWEZSU21sSk9EbFZSM2sxWlZsa2RtazVNVmR4DQpWM0JPS3psUFZrWkxSR1ZSVm1kV1JIcFNSR2x0UkRWSE5rVXZXRzEyU25aTWJrbHJEUXBTVDA5R1MyWmxhR3RZUVRjNWIwczFUV1JaDQpiVmN5U2tSTlpYQjJkSFV2ZDNWc1VFeFpWelJ1YVZkQ1JsVjNSRzlLUlhwWWJVRkNlSGt6WjA0TkNuVmFjMU52UWpSR2VsQkphbHBhDQplRUZrVm5nMGJXUlpVMjlsWW1oeVoxWTNaRXQ2Tm5wQmJFSnVhelV2UTBFMlIwRlBVSGhwSzFwVVdHMDRZZzBLY2pOeE5XSTBTVVZCDQpZa1pJVGpKNlRVcEdhVkZaYlZCdFRYbDFhWFZ6UTFod1JEYzVZbWg2T0hoWGFYY3ZXWE5QVTNaemFHdzJlR1ZGY1VSWURRcHdSblIwDQpTSGR5V1c4clZIbFdVRTVZYkdaQ1ppOUpTVzF6WlRobFRHUlBOM281Um5oeFpDOTRVRWhMTm5Sc1FuQlhWRkJHWW01WlpWVndUMndODQpDazlvVkc5aVFYRXpRVk41VW1KMVZWRlpaWFF2Wm5VMVp6VlpOM280TlRFMmEzZEVRa05STUZnclRIYzJXa3RNVVZkbFpVMDVXRzFJDQpjSEZ4S3cwS1ZERklNRTVUT0RaUlRsTlVkRUZIVEdvMlpVTXJSRFo2VFZOSU4zTjNMMlpqUkhaWFRVTnRaRkZ3TldjeU5GaFdRakJhDQpUMko1V2tSVlRuUTVEUXBPUTJsd04yRXdSMFpHVm0xc1VXcHpUemt6WkRod01WWk1iVWQwVFdOclUwWm9UUzlVVUZWT01VNVJiRnBFDQpXSEZMUm1ST1ZsSkdVME0zUldVTkNucEpNRVY1UWpsRU9FUnZNelJFUlRSa2JGRTRjRGN3ZVV3NWQyWjJiRXhoUTNRclIyWk5VbFZwDQpibU5vYzFRelYwOUljR3RwVmtsbWNFeDFidzBLZVZaNVJrSkthV05yYldGTFMybHJTMmhOYmxCeVRUbElSVmh5U0d4d1dteGhkRkpQDQpUWFpST1ZKWk5qaFFTbU5EYkVGelVFNWhNa2R5Wmsxa0RRcERWRkk0TWtJeVJUaFVlV1JNU0dzNWFrRjRSa0ZVYmtWVlpsbExSblp2DQpVM2RsWVdNelVXcExjWFppZERaMmFHSmlNR3hyU2pCMlRqVXhlVElOQ25Sd1JubExhbmczY0hoQk1uTlRZbTVwY0dGcGFGTXlXVlJsDQpkR1pRWVc4NVFrVlZWbXRYUTFwcllWaFJjME5TYUdaNk9GWkxLMGd4VmpkQ053MEtkbmRMVkRkRlIydFZkamgwT0dwRWNsbHBiRE5ODQpSSEZxYjJKamRVRmxhMGhLVVRSNU4wTm5UREJzWVhWVmJreG5ObkZDZGl0blNuUmtjMmRtRFFwNldtVnpSMk5vU21sblFrZGhRbkZQDQpiR3NyT1U5MU9FMUdjMjl5WmtGamEydFBjVFV4ZVM5cFdVcEdNM1ZETVhoRVlqbDVSRk5KWlRSa2JXME5Da1ppYkhOdGJubGFjQzl2DQphMnRCWXpCeFJGUXdWRTAxTVVkVk1ITTFPV1ZqTVVsbmNIaDRkWEZWYVdaRVpWYzRORzVrTUU4NFl5c3dTMHgzV1EwS1JFWlFiMlZ4DQphalpuV1VOVFEwWjVabWt4VkhGak0wcEpWVXRwVW00dmJuQnVNbkZSTW1JMFRHMWpLM1p6U0RsT2IyZDRhMGczUm1abk9UVlpEUXBWDQpNRXBKUW1GdVkyVnhlbTlTU1doVE16bHFiWGxLVDBaTFZWUmtiVkp0Y0dGTlRtRm5VM0ZJVGxkb1dXOXhORTF1VlhSbWRrRmlSRmxxDQpibVFOQ2xoU1l5ODNiVmd2VEZwRWVHSjFTbGhLV0hGNVlXeEZWemhtTmtsbVQwMURTVXB6VDNkS1JqWjZXa1UzY0VaeEsyVlBUMDVrDQpiWEJZVURnell3MEtTelo2Vm1KSmNqZHJWWFYyV1d4SlRGUTBPWGxoY1c5dk0xWjFLM1J3VVU1clRrTkZZVUp1U1VoTU1sQm9kVEkzDQpkWEZLTldoMlpWZzNjMHh2RFFwUVJWRm5hbUl2ZVVnMmJIUnFaMWhIZW1Fd2R5OW5SM2M1T1RsWFVETjFUREoyYm13MFJYQndLeTlDDQpkRmxWTTNoUE9WWlFkbGxOVXpsNlFrTU5Dak4zT1VKV2JVcG5OMVIyWTFoTlRUQnVkRWR4ZVc5b1RVbFNkVTlYYVZwQk5WSmhialZODQpiVmQ2TDFocFdreFRZMnh2VTNKRFJXeFJRemR3ZFEwS1lUZ3lNbWxvVkUxa1ZXMUdWRGMwV1UxblRIbFpUbms0TVhKUFZGSnhhRk5qDQpTMnA2UzFoR1dIcDFRbmRLTnpGaVEyRjJZakZZWld4MlVXOUVEUXBpV1hCMWQxRldXbGhCWjBac1JHeEpWbWs1TVdjM2JXTktUR2h4DQpOWGwxYTFwRVFYQnFSVGRrVDNobmQyZFNTRlZQYlM4dmMzUlNZMFZ6WWpJTkNtdFVTMnQwWVdVNWRqZzJha0pVYms1Uk1ITnNZVXBZDQpOVFJTVGk5aFlYRndUREEzZWtWSE5uZG1Va3BPWTFObVVrdG5MMVZVWmtrek9GUjNPQTBLYlRSRFNqVTFhMmhwUkhjMk9XRmtSbFprDQpNV1JUTDNWNlVYWlFZbTFpVEhsT2EzaFNlbTl3WjNKWlIzQnlZMVZZVXpkV1psbEhVbWROY204MERRcEpTMG81UTIxbWQzcDVZa1JFDQpXbTVEV1RSa1ZYaFpWMnBFY0hjeFpIRjZiVkJEVkVZM1MySjFRekZ3VkRsdmFHRjJSMHhLYVc1NE5rRlJhR01OQ201YWVrZ3JlWFl6DQphblZhYVRaV1kzaHdhMWxpZFVsTFZFbFBSVEJGWjNaU1ptUkxLMlJ5SzFGU1pHdG5VRzFpTUhsdlN6bFhVWEI1ZG0xWFpRMEtWRkprDQpTVUUzUzFwc2RXODBkMDV5VFZWT2VtMHZWV0l3Ym5kdlNXTTBVakJRTTNCcFRWUjFjVmxzYTB4UlVETlpWV2hDV0UxRFJDdHhWR0pLDQpEUXBMY21rdlkydFRZMjlYVERGalFWbDBkVTFHV0N0WVdVUnNRbVJ4VkVkR1NrUXlORWR0YW1neWFHeDJVM0pUVVhvM1IyRmpVUzlUDQpWVkJTYlRrTkNreGpibVZFYldoS1JUVmhNMWxHVVhFMWJ6TlZRMWx0V1VSdlNtOU5SMkZFTmtWSWJWRnJNbGR6YUdONlprUkJUV1ZVDQpNVXAwZDFSQ1RWbzBiUTBLYVZBMldrcG5ZM04xVWxkNU9GVndTMW8zTjNocGVYZHhNMU01VDNORFNrdHRNRWRuSzAxb2RtVlZTRkkxDQpTMjFvY2xwaFZrOVlObGhoY2tZNURRb3JWRmRSZGpKdFFWcGlhRFYwV1d4d2RVNXNTMkZ4UlhSWE5Fc3JOVVpTWnpKb2FFWnFRMVUzDQpaamRTUlcxRlUxY3JheTl5ZDFoM2NDdFZRa0VOQ20xVlJHRkNXVTVvTjJGamJucElNbkF3THpGdlRXRTJaWFJtU25KcFZsa3ZZazR4DQpORFpZTTB0MWIzRk1WMGxHZFRsM2RGVndhbUk1VnpsbVVBMEtiMjg1TmpBd1lWUnZTV2xPT1ZsMVdVUkRSbmxQVkRselptTlZVRE4wDQpWMmxEVlROSE1IRkZjMjVPV1VGTFkyVnBlV1VyWkhoWWNFczFaMFV3RFFveloxTm9URzlWVFVGblRGSnBZaXN6TDFKWFozZG5jRWgzDQpTRmxVT0dKMllpOXROQzlRVmxCd2VqWklhMEV5TlRGMGMyRTBhazVKU2xoRmMwSU5Dalp1TUhsVE5sTkJMMEpuUW5wSlFWRnNNR3N4DQpNREZhYjAweFlXVkhTMFZ4VTFWVGEyVlBXbE5HZEZwM1l6UnhRemhxVUM5RGJWWkxWbUZUZEEwS2JHVjJOSFZtUkVoUFpsQkRjVFZDDQpWME5FVVROcFZEQm9ZM2RoZFdSM01ERkZURkJpTTBwSWVGa3haVmMxTlN0QmFWbENjMmg1U1haTE5URXpEUXBKZHk5TVVVa3JSa3RLDQpkbEJKTm5SVVpYUjFaMjEyWVVKbWVVRmhXbHA0Y1ZwUk9FTnRUeTk0YUVoeFJWWjJaVFJ1ZVROblRHUnVjR0kyTVVRTkNtOXFURmhXDQpSMkUyWm5oaWNXYzJkbWsyUmpkM1NreENlblJ5TjFCdWJDdExkazUyZWk5NlV6QktVMkZoYlZWMFVGRk1NaXRDVUhRNVEwMW1UZzBLDQpNbWd6YjJjdlRuVkVNeTk0WlVwa1RWUjBNMGhoTjJOck1WaG1UVWRSUTFONFVrODBTVXAzZEV0ekszZEtXbEZzUVZsa2VUUnhlakp1DQpSVTh5RFFwdVpsZEdWVmtyZVhaeVQySjZVVTFWZWxOdFVsVkVlakJwYWpkVkwwTnBUWFJYSzBWbGJpdDFkVkJuWW5GdFEzSTRTVUZtDQpjVFl2WW1GNmJXa05DbWxrVW1oU1NYaFFiWFp1Y0dKMmEzQXphRFYzVm00NFRIZG1kV1J1ZWpBelpWb3JOVVEyUzJwNmNFRjFlbTUzDQpTemRxUjFkWmRHWTBSVFJDVXcwS1pIZEhNbVZxYTBkYVFXZEpjRFpDY2pSUk9HUjRNRzAxZGtGbk1WZDZhVWhFVEhkWlFXOURUWEIxDQpXbTVZUzJWb1ZqVkhWRWxUTkRNNFlXdG1EUW93ZWtGaFJGbG9aSEZIYVc5dmNGZEdRWEJIWW5oSlUxRnFNMHAyZGpSUWNUSkhkbUo0DQpVRlJzZFRKb05UTktTSHB5UkZKcE0zbDBSVGhYYzNrTkNtNW5PREZqSzJwbWVEbHhaMEZRYUdVeGExWTBiMkpLWWpOVFpuaGhXVEozDQphWFZIWVdWemNXWlJPRzlhVkM5MWRVNWFiRmR4UnlzeVdGRXJRUTBLV20wMVVVczRhVkYySzBOMGVqUmtVSEJWWjJNeVN6VnBlbWQwDQpjRTV4VlRJM2MweDRVMlIwVXk5eWNuUnljVkYxTjB4aU1rcHRjakphUW1WekRRcGFPR2wzU3pkcVRYSmFWazQxYUZCc2MxVXdNRFJsDQpibWxoWXpGblZWcHhVRGhsVEd3ck4xSjJNMEZQUkZFNVJHTmplRVJuTVZnNFdHUmlaM2dOQ214aFdFWkxSMUJEUm5vNVJuWnJSRVF2DQpSM1ZzVjJaMVEwSkJlWE5YWmxCR1oyMWtTRlJpZDNKWFduTlRkU3N5VUdzMVRXNTBVVGx2ZEVGbWVnMEtXbnBSTTFSQlVucEdTbFZQDQpRWEpZYW1WMVdXSXhkQzl6WWl0TmEybFRaR0pyT1dwd2FVVTJSRVYzWVVwa2NuZGhPWG8zUzB4alRWRkdNMDVJRFFwc09FMWlhSE5QDQpSVGwzVjNreFVsZHhZVXBtU0V3MGNGWnFabU1yTW5wV1NqVm5UbFJ4TVRoVk1GWm5iRVZtUzJKTVJsWnZWbVp5Um5GYVpXME5DbWs1DQpUMEpqV2xVMlFWcDNla2MxV1ZOcGJHa3ZWMnBZWWtOdVEwRmxjMVJhYzBsU2IyWmxaVkZhU2pSV1ZFMHJibGx1ZEdOM1RUUk5PV3R5DQpMdzBLTDBsUWN6TXlZakJzTTI1RGFrTktTbWRrVWxoTFZUaFBWVkJITlc4dk4zcE9RbmRXZEZZNWMzYzRiME5tTVdKVlRGUldUVGx2DQpNSEF2WWxsbURRcFhZMWRtTjNkRmEyOXBSblZ1V2twRVlYcFlORWRHYlhoRmR6bE9kVUZLYkdaTmJVbHhUMDVFYUVkTFoyUlhiRWt6DQpWM0phTVdac2IxTTJlbThOQ210alEyOWhOeXM1T0hONE4xTllaMUJOWjFaek5VcFNjRkJaUnpSRlFuQjJRams0UXpCSFNDczRjVmc1DQpOa0V6V25kMk5IazFUbFp4V1M5SGN3MEthVE5RUWxsMU9Fa3pkbTlYTm5GWE1XUnpiM3BRVkVWMk0yeG5XblpsT1RkUlEyOHZZbkZCDQpZV2hoUTB0TE9FcHpTR3RzYWpjM1luUTRkMlppRFFwc1ZURjVXVTV2ZFdsbVJTOW1kRzVtVDFkdFVtaEZWVlYyTXpoclVuZHRlWGQ1DQpObXhLYjFKUGJtRjBVbGxVTmxSaVVrazBhV2xPVEd4cGRFa05DbFF3UVd4RGIwd3ZXV0pVVjBVdlMyaDNSbGx3WW1OcFpVaFdUSEY1DQplRXg2UmxoMWRqUTBaWHBQUTA1b1dUSm1iRzlTU25SR1JtZGxhamxNY0EwS2NVSmpjR055WWt0WmIyWm5ia2R6VDFGU1kydG1PVEozDQpTalZxWmtWNE5XeHBRV2N5YlV4bVpqVnlOM2wwYUdac1MyTnJSMVF4VERBd2VVMWpEUXBqTTNKelJUSXJLMmx2Y0Zack4yczRNaXQyDQpTbFV3Um0wNFJ6SlhXVkpZT0dGdVZITnRjbll6ZGpoc1lsSjNUVmhGYVc1VFEyRk5kRWt2VnpjTkNtMTBaRTkzTDFKMFEybElkWE5IDQpUa1JSV1cxMWIyVXZlbXQzTVV4b1ZIbE9TWFUyWmxCTlZWUkRTV1JNUlZCS2MyTlNRbFJsZEhCVk9FTXhSUTBLYTNwSUwzaHdlbmg1DQpiM1k0TURSSFJrSk9SakZFVDA1cU9YaFFTemRDYVVZdk5tMXlURnBtVmpoelIzVmtPR2t5VTFKelVIRmtjREpyYVdNMURRcG9SM2RPDQpPV3QwTVdJelpGTTRXVk5KZW1OdE5WaENTalJOU0VNMVEyY3dUbWhCTldneVdGVjZRVGxPVEVOME1razJTVlpNY2tkWGJrZHFNVVlODQpDbEJEUkhWS1NIbEhkMDl0YjFaUVZYbHNhME15ZG05VVZqRnJhWG96WVhSR2VsUnlaVVV6VFV4WGJEaG5RUzh3WlVKS2JYWmpOMWxDDQpXRE5HY3cwS2JHcG5RbTAxY0U1UEszWTJjMjVGYjJkRVlXVk9TMHhrYVRkbGJWTnNTaXRwU0cxcmFrSXpkVWh5VFRoYWRtRXZVREZzDQpXVmhsTVhkSWJteHBEUXBTT0hKdVZqRXdTVk42TjNsVFZEaDZLMVZvYmxOaU5FZHFUM1pHVFVkNU1VcHBVMmRZUTJoaFluQXdZMHBoDQpRa2c0U2t0R1ZrOXVUR2t4V2tvTkNtVnFkVEpIVnl0VE1VSm1hSEpvYzNKcU16WnVRMUpUYlZsc2NVRkJVMHBSUld0RllsQlpSVkI2DQpkM2RsVVVsRFNIZFBNWE55VjI0eFlTdFpkdzBLUWs1eFoxa3dSRzF4VG5veFVVOTFXamRCZW1aNE9FUmhVREp3YWtSWVYzcE1PV2MzDQpiUzk2T0hGQ09IRnJOMUl5UmxJMGRrc3dlVEJRWkdKekRRcFFURkpqTm1GR2RVMTNVM3BKYUdoUVJsSlNaa2RGVDNkMVNtaG5kME56DQpXVXB0U2xsR1ltOUhZV0pqYnl0Q00zUmtSMVpwTW5WUVZDOVlUSG9OQ2pJclJHUkRTamgwTlRoRVRYSkljMGhhVGpZMVRWSklSekV2DQpaamszWkVKSFVEQm5WWHBHU21kTFRESXZSMmhLYkVRMFdFdHpZMWhHVm1aalR3MEtiRE56UXpWMWRIRmFiRGRpTDJWeVZrd3pWMnRHDQpNVFZtVW5wM1QzVmhiWEpzZEhvM05sTm5URTFKWkV4VlpFWkxWMHRJY0VsT1VtMXRTVXRqRFFvNFoxWk5ZM00yV0dkVlZtdHhOMm8xDQpUbmxYVURacmFrRmxVRUZIVTBWNGQzVnZjbGRYV2pGQ1NISlBZMlExZWxKNWNYQmtaRXBzYTJkWWNIUU5DbE41TmxOWlF6bG5aRk0zDQpjVkZxTDJoTlVXTTRNSFI2ZDNReFdHY3JRamxQYjI1Uk9HWjRWWEJPTTNFMmIwSkhaSHBMYkdvMGJsUkdSazE1ZHcwS1RHRlpSM1pyDQpWVE41WVZOSk9Wa3lMekpRUlVSdE16TkVZMnhXV1VWeU5WaHVlRWxNUW5Sck9HNVpVVFpQYmtFeE4zTlROakpJT1hGdFlUTnJEUW95DQphRUpLVTFGR2MwcEJhMFZoUzNCWWJucHFNVWRJUTFKSU1reFdNM3BUVjFGdmJ6SkRiV1JOWjFBNFFXVklhemRDTldOR1pWSTRWazVEDQpWa3dOQ25oaVpVaGFNbWw1YWswdk0wOUdTVVZCYW5ONE4xbGpRWHBFSzJRNFRYSXZha3d2ZDB0d1VYbFdSMGhET1Rka05FSldVaXNyDQpSRGhvVDJrelZBMEtNR0ZKUVUxUmQyNUJURVJIUzFjeU0wSkROamRoTmxReGFrOUNhVUU1VFZCRGVuRnpOWFJSVEVJdk1ucEhlVWhSDQplWGMzY0dORGRXb3pWemhpRFFvNU5rZFBTMmhRUVZKbVQwOVZZVmMxYUVadVExaHdhMU5xY1ROU01sQTJjRUZMZEVwa2FEaElOekZQDQpNMk54UlhKeGFHMHpkWEZwVVZsMFJVb05Da1JUWWpBMVZuTjZaMGRWVWxKRlNHaG5jblpRVTB4SmJEQmhOVnBzVW1Oc2VUUlVUR1ZJDQpaR2RCTDB4eVpURkZObFpwTjJkRFZIQTBjMUJqYXcwS1EydDJlSEZ1Y1RCMFlVWkRXVlJoU1VOWlZFSnZjbUZ1Y2taNGNHbHRRV3c0DQpUVTkwZFdKaFlXbG9ZamRwUVVWQmVIQk1kM0ZXVGk5RE9HNDVEUXBDZUdOMlJXazNOelprYjI1cVZEQXJlQzlYV1UxcmRIcERaWEF4DQpVR2h6YW5aaVRYWlBjV3MzSzJ0SGMzUkxSblF6YUcxNVprRXZiV1ZST1ZZTkNtaElkRlY1YlRKak5uZFhRVTkyWWpkdVpIaFRVa3RoDQpWMFJCUnpneVNUQlZRMkZ4YlRSd1FqSjVTazR6VG5OSlYybzNRemx2TlhkeWJYWTNiUTBLY1VSTFZFSXZiWFZSVFM5d01rUndXVGhrDQpSbTV2U0hoS2JTOXNTek5hVDFSb2NUY3JVMU0wWVdsVE9XRjBSMmRIV2xGUlZHNUxhRFJxYW1RdkRRcG9jRUoxTHpWUmIzbDVNMUpDDQpja0Y0TkRkQmR6bGFabVo0VVV3Mk5reERiMU0wTldkeFNWbDFLemR0TmtWVmNIRjNNWHBSYUN0aUwyZExabUlOQ25reVozRXdMekYwDQpaRlU0ZG5KWlJFbExTekJzYTJNelNHZFZaRTQwWnprNVN5dHFVMkY2VTNVMFdrNHpZWFZVWWxwSFQyNTBkbEZEVFdoa01BMEtRaTk2DQpMME55VkU4NU5EQlphbE5qU0VodWRIUTFORUVyY1RaRE1VTjZWa2M1VTJjNGVGTnVka0ZWVjFnMmNVSldVVzVMV2tkNGNtTXZiV2R0DQpEUXBDTlVkNWFVTnlhRlpIUlUwMmJWUlpjamh0YmpZcldHNWpRbTVwWlhWbVRGQnVkR04zU1daaldUWjVLMDB4YlVaVU1TdGFTM1EwDQpXWFphUkc4TkNtbGtaMFJpWmtoWFluVlNNRVZ3TlVWQ1JWbHBjRmwwWjJOM1ZVNDVWRVprTTNSeWVFWjRkWEZ4TkN0WVkwSm1hR3hLDQpiM1ZVVVdGalZrOWlZUTBLVDJKdE1FNWFNVWhhZEhjeWRXRmFZemx1U210b2JYZHdOVUUyVEhKeVJUY3JaRGhsUjJaa1pEQXhXV0p3DQpXVFpIUml0S1ptNDBUV2xpVGpkdURRcFBhazVXTHpreldFMVdSbWRTWWtOQ2JYQkZSVmR4UlhCQmJYcHpZMElyYlhock5ta3dWR2t6DQpWa2x0UzJzcmRHTjZVRFZ1Y2l0cU9HVnhWalVOQ2toUGQyMUNZMjVVWW5WTlFrUnRZa2RLY1hWSk5tSXlibEJ3Y2xodFRtOXBXbkpyDQpiakpUTmtGT2MyRjBZME5uVHpCalZtMTNkVTFNU1UxclVnMEtlV2g2WjIxSVMwSm1XbGhCT0U5M00yNVdaM0JxU1VsRGNWaG5kWEZZDQpSbXBNYjNWa05WUm9iMW96TWtkbVVIb3ZhRlJYZUVGdWVVcHNSRmwyRFFwUlFWTkdTRTU1VTJsSmJUVmxWalJSYmtoblYxcE9jSE5wDQpNbm80UzBaRU5XNVNhRFkwU0hNdlFsQTJjVE56WkhWM1pUbE1URFJDT1ZaRVRDc05DakJtY0dkV0t6TTJkVEI0VWtWdk5FUTNhbXBFDQpRWHBoYzJ0c1EzQjJkMk5GUmpVck1WcHFNRkZJUWpCTlZrTXpWMmM0V0N0VVlXcHliR05RVFEwS2RVMTNORlJNYlRGRlZtOTJPVGQyDQplWFZZUW1sM1lrRjRXRXRtV0c5UFNtNVZSV0U0VVhORk55dEJPWG8xT0dWT2QwcHZLMjF6UVhSd1MyUk9EUXBTTTNKcFJFRkVabGhRDQpUbk4yYkVab2FESlNLelp6V2toR1FUZFFhblI0YjJoMVZUQkhRVXRDT0VZd1IzRTFLM0Z4WjB4UFRITmtZWGhTUVRZTkNtRlNXR2hSDQpZakZ4VkdWblpEQmlMMXAyWlZKTFdsaFFiREp6YWs1dFJYbE5RbWRUTm1GSlRtcHJUVE5wWjNoS1l5dFlTbVY0UTJ0V1dWRmFhUTBLDQphMnhzVGxCRmVEQm1OVVY0VkdVemFscE1ZMms0VVM5NE0wWmFZMUZ4T0ZwMlpITmxPVVZNTjJnMlZURnBTa2xvTUU5dGRWcDFjVlp3DQpSakpyRFFwVUswUmxMelYwVUVsQ1RVRmxRbFUwUWs1dVVFWkJVbFJETVdoQ1Qyb3hXbU5RYjBOT2NIZFFhMHhvVVU1bFJHMXFOVTFuDQpiRmhrYkhkaFlXME5DbUk0VDA1R1JHZzBTV3BKWW5oUFUwSkZWV3ByYlhwVWN6aFRTVFJSY1RBNFZFaGtha1pQUjBwdFN6TlRTRWxGDQpVR281VWsxVGRsQjZjV3BoVVEwS1NHNDJla3AwVDNoNWFYVjZUU3N4TUd0dFIxbzJORGROUlRCa2FGcGpNM1JOWkVaRlVWRnBiMFIyDQpaMUZST0N0clkzZDJaelEyVUhaVVRGUk5EUXBqVFRoNmNYTXJXVmRTU1dodmFHZE1ZVzlFTUdWVGJYVTNaWFZpWkRCVVpFMTRaV05zDQpTR2d2ZFUxak9GRTRTR0ZDVmpkWVZETm5OVEJ1YkhFTkNqTkpTbE14VURGb05sRlBabTU2YkVOdFduVnlaWEpuUVhGV2NuTjVSekJvDQpNRlIyVm5Oa1VXbDZTM2x0Y0RGaU5ITjRhVTFsVm5oS09YWTNiQTBLVkVwR1RsaDRNVWhoWVRFMk4wMDFVV0ZYU205MGVsbHBVa2RaDQpURmxhTUZoTGRscFVVRkpTZVU1UGRVbzRlU3RHTml0UE0yMWpWemgyUmxCRURRcHpaRFkyZGtrM1YweGxRVXhKZEU5cFNFUnJTWFZ4DQpXV1JIZUZCT2JGVkxhbkkyU1RWM05rbHdaVGhWVFVFMlZUYzBURTAzVGtVelVtWTBXWFVOQ25CelNGVjJWM0p6Y0VaT2RrcGFWakE1DQpjVlpXVmt3NU1rbDJiQ3RFUzFwSVlWQnlXVEJ1TUVScGEyc3JMMjVGWmt4d2FubGljSFZsVXpoTVNRMEtUak5aWVcxRlYwcGtRV0pVDQpRVzFKV0haUE5HeHhjMVZOYUdoTE1sUjZiVGx6UkdGMFpHRlNRelJ2TkRscGFuSnBORkZaUTFVeFlWSXphVFozRFFwbFFqWlVkMFJxDQpOVVJVUlZvNFJHeFhha1pvZGxsS05sRjNRa05xWkU1SmF5OU5VWFpqVFhkM1RFUlhXSE4yZHpJdk1EaFJOVzFYV1N0ME5tVU5Dbk5wDQpNSGh1WlhsQmRYbHFaRE53TUdoMmFWVjJNbUpNV2xKUlZYZDZWWGh0YTNWb1VsZFhaQ3Q1VFVsMmRIbHdiakUzVkZSRGJrSmxjM295DQpNUTBLWldOVE1tOTFXVzVhTVhSSU1tOW5VVWd5T1RnMk1WRk9ialJJUW14Rk5sVk5OV3RMYzFsRGJtdHBSVFY1TWtZeVpFOUhla0ppDQpaMk5sT0hoWURRcHViMFZMZGl0bFNreDJLMVZvWlZWb1VsTTBUbEF5YVVkemNXOXZTM2hvYnpKR1NHWlllbUY2UzBoblVEVm5ZWEpvDQpVRUptVm5kWEx6TndNMWtOQ2xsUmJrd3ZVVXR1ZWprd1RrNXZla2d3WXpreFZsa3lPV2QwZWpKRksyMWlSMnB3VG1kSVZHbHNURXRxDQpWM0V4ZEhFdlFtRnhUbVJoUml0elVBMEtVMVY1S3poeFJYUjZUVEJ6ZEhCa1VVOXFVWEpCYXpnNWNYcGpjRWxpVEdOV01IWllkSGxqDQpSM05HVWtoRE9FWjROVkoxZGxWdGJrdEdMMGg2RFFwNk1HUTBhM2xIVkhaclVUaDRNRVpUWWpReE1UVlZlVWhQTm1wdWNXUm5XVzE2DQphbVpOWjBRMVRtaDVkbTQzUW5aQlpHTmhkVUZGZFhRcmRYVU5DbVJIUVVaYU1WYzJURlJ1YkZwSWVHaFdjSGxEV2xaaFFtczFTbVJ4DQpVVFZ2VEV4UmQyWmlUMUZuYkdwd1UyTTFURlZNWVRFMmFERTRWRUZEWWcwS1dtTmFkSEZ3WVhCTWVtdHRaRm8zU0dveGIzWldhVmQ2DQpkek42UWtKUWNUaERkMFYxWVd0SVJsZ3JXWEUyU2k5VGIyZEVUazFFUldOVU0wTkxEUW8yWkhObVprcGFWM0F2WTBkelpFWkJWVWR2DQpVbUk0VEhWcVpuSnNWR0ZpV0VGeWJqUlFjalV6U3pkWGJEWjBNRWh3VVdJelpHVTRZMGM0Um5vTkNuUlFWMWcwYlc1alJuSkZNV2wwDQpMMUZtY1VrellVaHFLMmcwU25Fell6UlliV3d2VW5STVlWaHpTM05XVTNnelVHNVVUREZoVTNCNFNEVTRaZzBLYjFSaE1reHNLMHQwDQpRa05pU25kQ1JtcE5TVXA1UWt3M01HSkRNbVY2UmtaQ2IwTjBORTVMTVhwaWFscGhZVnBxWW1nMlNGQnhaemhMUlV4NkRRcHZlVzlZDQpZMEpWU25oc2VHaFNabXN3U0hGSVNFNTNlRE5WUWtGVWJGYzBSVEZuZDJ4eWIxUnJORXMxVjBwRGVEaDFVa1pLYVhSdU4xRkpWamNODQpDbnB5WkdkdlZTOUthRVJZZG5kMVJFbE1hMEpIT0hCeE0zRnRjRFJJUTNNeFVrZDVVREV2U2xwWkwzSTRhelI0ZDBWRVRHNXFUVkVyDQphelpvYmcwS1owcHNSRE5FY0V0UmFtTlpReXRrVFdsU0syd3ZTamxUYkZBMUsxQk5SREJ2YlVRMVFXeDZWMDE1UldwaGVFZHlNMVpuDQpaemMyTTNsSlNUZFZEUXBTTVdGbkswZFlNVFpQWms4MFEwMDRZbGx3TDB4aFlrSnZZak5vVjJ4NU0wZ3ZTRGx0WWt0MVZUVlBOMmQyDQphbTV6Vml0TU1IQldkVGt4UXpJTkNrTktWVXN5WW1SQ1JrTnFlV2hLV2tWemN6QXJha2hDVEc1TVl6TjZZM1JqTTJkSmMwNVdTRXRqDQpjbXBHVW5oMUwwaHhSVTFVTWpkR2MwZ3lWdzBLZEZkaGNVNTRNazF1VkRScWVXUmtZVGhOWjFaNk9VcFVORmN2TW10Sk4xQTVkMVJJDQpZMGQ1TmpOWVpIcENWRzVtTjBGUFVGTkZlR0k1ZUc0dkRRcGxSalpoZEZKMFJHUjZOWEVyTmpkR05HUm9iVXhJY1U5QmRXaFBRMFlyDQphamxGVlhOemFubHdielpwVFZKRldXMVhMMk53WWpOVmRrcGhaemNOQ2xSS1FsbEpMM2xxVEZJM2NEbFZjVmRXYTBwWFEwUm9SRVYxDQpaV3cxUVdFNE5UZE9la2ROVFZSdWFFUTNObnB2VTFGV1dWWm9kbk00UkRKeGVnMEtTMGhQWW1wRVJqZ3lUWGt4VjJwclR6SnpMM1psDQpOa2QzWVhaNFNFcEVZa3Q0ZWtwc1kySXlXbGxwVVhRMFNqSXJhRGRMYW1RM05IcHlhSFY0RFFvMFVWSTFkbUlyTjBZdmJIRnNZM04wDQphM1Y1WWxORVFtRmhWVE13ZDFoamVpdEVhbWQzY0M4MVJGbE9lVGhyVkdKVFJFZExhWFJ4Um1saVJtY05Da1pSWVZaeVNIaE5NRFV4DQpkbmxaUm04eVExQktVMWRZUjFGdlpHbFFUMmMyZVVwSlNEWjZTakF5VEhSV04yWlVaV000WWpCUlpFNVFha1U0TWcwS1JXWnVUbTF6DQpVSFp4VDJScWNXNDJZekJQV2xCdGNtUnNhV3N2U0VwNVozVnJZVUpQYWpFeWMwbHVOak5MV0VaWGIxbG5jME01Tkd4M01rTjNEUXA1DQpZamRFUW14TE5GZzBZM2cwU21SeFVURlNRVWhHU1VnMFREZFVXa2hSUkZaV1VEUnVXa05OY2tSUWIyUlhSR05ITjBGNVJ6ZzRiVkZaDQpXWEVOQ2xSSWNrMW9SR2N5T0d0U1dqSk9kMEZXYnpSdFowZG5RVlJ6U2tKVFZHSllaRzFEVFhCeGMzQjNORk5EV25KcGFXZFBhVnBCDQpZVUZ6VlRrd1FRMEtjekJXV2s5T0t6VlhlVEl5TW1reWMxcEZZMVJYYW5GM05IVkpXbFpOU0dWQ1pYRTNRMVJsSzFWNFpWQlVXakZ3DQpiako2VUZoMmMzWkNSRWhQRFFwMFoyUXJiVkZ3VG1WTEwyZFhXVVZWT1dOWVZtVmlVMWRLU1hOcU9FUkVRMFl6YzFKbE16RnRSVVJSDQpXakZtY1hodlVVOVNjRko0ZWpoYWNGQU5DbEpuV0dsMWMxWjZUM0kwV21KUVYyUjRNbFZxSzBwMWNYWXJabWxxYml0RVVXazBSMVZCDQpWbVl3U1M4M1NFWkhNWEJTT1RoUlRqVllWbmxKYkEwS01WaEZRME52TkhFNWRXaDZSR2gwVlZocE5GQkZVMjE1YjBaV2FYaExMMFZqDQpTbFl3WkdNeVRFVkVNRk5SVkZWUmFGazBhMmx2V1hCWlJFTmxEUXBIYzJ0dk9URnZNbnBwUm5FcmFtRk1XRWhDUldsMGJXRmhVMDVMDQpaRTlpVDFWVGFqSmhlV3NyVFZFeFkwZHdVMHB5UTNwWVNIWlVNVkZtZDJRTkNtMVBSMnhYVEZsV1oyTk5iU3N5WkdoaFlVcFBjM1J0DQpTVVpGV1RCVllYcFhiRklyVXk4dlVETm9hVEZVWWxCMmRuRkNiR2RhU2l0UlVraE5SZzBLV0Roak5WbHJiVmRSTmt4aVVuZEZiWE54DQpTV0UwY0c1dlZqWTRZV05xV0VFNE4zSjZVams1VDI1dVl6Y3lWbUpCVjJGTGNESm9TMUpaTjI0NURRcHJhSEZPUTBsSmNFd3lOVVpKDQpWaXR5TXpOemVVbEhkSHBYWm0xNlZXZGhaR3RXVVd0MGRUVnpWVUUyZFhsbVowSXlOM2hXTXpnMFpsTnRhak1OQ2taR1FsUnlkVTlFDQpORzU2V0ZCaGVtMHlWM0kxVTBSbVRrMHhhRGgwY0U1WFdHeDFZM0JPZDFwb04xRllaeXRPV2tKcVFWVjZURlJqVUd4RWFRMEtRWEJUDQpNRTVQVEdWa1ZFOXBabWxpYjFWb2MzbG1hMlF2VjJaaVpGWmtWMWx6WlcwM2JpdHNUMVpqYlhkclYxY3laRmRzV1RWbmIzRjBTWGswDQpEUXBFTDJReU5FbzFjWFJ1TWtZemJISmFhV1ZLYVM5UlEzRkVhRTVyYkhNdldpOXNZa0V3T1VKeWVtNWFiSFZzTkhsYWExTTFRa2x1DQpUa0Y0Um1vTkNrZHVURUZuUkhSSlJqRnFlak5CZVdwbVZIWjFUVk5KZW5aYVZqZFJXbmxZVDFodVFsVTVVMDFNUzBORlFXbEZUSFV2DQpUV05tUlc1SlpYcHdadzBLZG05c1JuUTNRbTlWT0RCelJGVmljRU5UTnpGeVRsaFFNRVZNU0V4eVYwbFZWMVk0SzNrMlRFcGtiMjFyDQpRelJJV1ZBNFlsTm1hMDA0YzFZckRRcHFXVXhLWkVOVGRXVm1hMGhIYjJSdE0zSjJRM0VyVFc5dmMweDRLekZoZEVVeVdFSlBWMnBEDQpNMVVyV1ROb2JIcHlRV1Y2UWpWdGEyMTVTWEFOQ25oVFNscExURFI0UjBjM1EyZDFUMnB1VHpkcFRGQjZVbFJuSzJkaFpTOWthR1JRDQpkSFpuY2tGQk1sTkdOQzlhTUZRelFqTlpXVE42VVRkVFFnMEtWa3BJTlhGeVowVlBObmg1TVdGd1JDOXFhbmRaUWpkTWQyTmpUaTg1DQpaVEpwUWpoQk9FOTVZbE5xVG1Rd2VFTkJUMjU1U0RCdmJtMW5Wa2RERFFwSVUxVXpPV2d2TDFocldHVjVUSFZ4WVZKNlZURkJZVTh3DQplVTFoUlhrdlNrNXJVRkIyY0hOS01uRlBLM1ZzZG5wYVZXbHpPWEZ3U0dGV0x5OE5DbWxYUkRVM2JFMHJWSGR3WkU1U1MwcDBLM0JyDQpOa2d2TkZsTGNUUlRTbU13UWpOVFJITjFkRzFCVjBOd2FuWlFjV3BXSzJwV2JYaEhWMEZ6U0EwS2RrcFlkbkZIVFVkaUwwd3liRkJ6DQpZelp1TWpGTGNGVlJORUZOU1dwTFkwTnZaVU0wTUROMmJ6WmhlVXd5TURocE1qSnRia2RaUW1OaGVEZG9EUXB5Y1RSWlRUTkxla3B4DQpWSGhFZUVVMmFrUnVOMjVqVW05VGExaDFkV3ByYzJzd1dYUnFPRVZETWpKbmJqZzJaRmRDTVZRM1praEZhMlV6VEhvTkNqSkJNbTFUDQpRWFJSY0c4M2JGUTNTVXRQU21wVk1qQlpXVTVpZFZCTlpIbFpWbmxqUTBoSVpIQlhNRGw0VTBSMGVGTjFVVEZVU21wbFFVeDVadzBLDQpWSGxwYjJaeVUwSk5TSGRJZWtoclVIcGpSbE5ZYWxneWNqTndNVWsxVlRKUGVHdHNPRVZOTkc5Sk5rWlhaV2xqUTBOVWRHTk1abGxKDQpOamhVRFFvdk1ucG9iakp2TWt4NGJGTm5LMU01TkhoelZYbHRVMjlCUW5kV01UUlViRFJ4YzFSSVIwazJUWHBxY0U0NFMwTjJZbkpCDQphVXREWjBaRFkwY05Da2RQZDIwMVlVOXpTVWhGUm1aV1IyUnVkRU5QY0cwMVZtcDFOVVp1Ym5oRFQwdEdTVmhqV0RGTkt6WlBWelJYDQpjMUZJZFdKeFVETlpXakl2TVEwS1F6RmpXbHA0VW10dFVrSkhkMXAzV2xKSVpsYzVPWE5GZUhCNmFIaG5ZbXRETVhoVFFVMVNPV3Q1DQpTRzFsYkZsR2IxaFZVWHBXY2paTmRISkdEUXBNYTBWMU9YcHhTMFZuVTJnM1EzTm9Rbmx3T1d4b1NHOXpjSEZqTmtSUE1VTjBlVzlFDQpObGh4UVhZNFEwOU9iM05PTW5ocWNVcHJVRVJJVFVFTkNqTlhWM2xHWkdNM1MyRmFTR2xzVm1WM2NXZEdXVW96ZFhRd01WUlRSVE4wDQpUVXAwWXk5dVoyY3ZVUzl3YzNwVGFtNVNaak5qTjNoeWNYVkZNdzBLUzJWblJ6bDZPR1JXUTFobVZWRkVXSFJ2TVZvNFNIRjRUMEZyDQpUelJJV25CeGJrRnJXSEJ4Ums1UVRsWk1kREJ0UmtSWk1FSldObFpSVEdZdkRRcE1iRVJWYTFSNGN6Um5iak5wZDJSMmJFUXpkbVJODQpjMU5DV25Gbk1YaEtUbUl3VlM5NEswMTROMkkxVlRWaVRUVjVPWFkzYTBSd2VXcHFhekVOQ2pOMldVdFVXR2wzUW1oTlJYUmpOMFZCDQpUblZwVURWalUxaERXREJLYlVGTVJITkxkSEo0V0ZOU1NubHVkMkpOTURRMmVWaFhkVVZXTTNNNVVnMEtaMUpYYTFBMWFTOUpVa3RzDQpNVFJUT0hGQ1RrRTJiSEpWUVdoNFduTjJURUkxTUZjMGJtTXpaRXM1TTNSSGNIWjFZa2QzV2xseFNVWkNTVU56RFFvMGJFSllWRFoxDQpNRGxSYjFFMFlscFFObXBvWm5oeUwzRm5jbWhFTjNaUU1HUmhOazFZVlZGclZsTk5Ra2h3Vm1kdWNsZHRkRFp5VEVORlZGb05Dakp1DQphMGRYYUd0cFlqZE5iR05VYjNOaGFESldlV1JtZUZVNFJuVmxjUzgzU0UwMVEzVlZVbEpvVjNwSlFXaHZTRWxwZEdKQk1HWTRRMVZhDQpRUTBLY1VaV1luVkpjRkJwVFhoNlVYQjVXbGRKT1hwdmJYRkNWeXR6VFU5VVpETjNUM0IyUW10dlF6UlNNVmhFTWpsaGFGRjZjakpWDQplSGxZVHpSWkRRb3JXSGhGVWxKbE4zZEVSbXBKV2t4WWJYSlllVWRKWlM5d0swazVVVmRETWxZcmFtZGxZM2RHYlhFeE5tbERXa2xUDQpWa3R3VURGUWJGUkpVWGNOQ25WRFdFOUJUVGR3VUd3ME9IbDBWMkpwVFUxaGJEa3daakZEZUhCSFp6RnhZMFpCUm13MU1YSmtaR3RFDQpRWEYyZFhaSU5tdEdiMk5RV0VRMFVnMEtPSEZHVFdoS2IyVlVkRTlwVFhaUldUSXJWbWhPYTBWRVNXRjRjbTV2ZW5RMGVEQnlPWGhTDQpOM2xCWkZsbVN5dEZMMkZ2VGxFeWQwUm9ZMWxpRFFveVZuZDRZbEJxTUVaUE0ybzRjMmxJVUZBNGJrUkxZbmxzWlhoUVVYRlpVRGx1DQpaVzl5Y21WeGNXd3pWMjlxVjA1VFl6UnhSVkZLTUN0WlIzSU5DbkZyUkUweGIyUnpUV3BQV0VOV2RqVnZSbmRCT0dOT2VHNVlRak00DQpNemtyWmxSR2RFaGpRMFZtWlhSYWRHSnRlV05rVTI4eFZrOUxlWFpJVmcwS00wdHRXV2xqZEdSUFN6WjRPRE5USzBGdldtdENXalpFDQpOV3dyZERKclRsQjBNa0pDTkN0eE9VaHdaakJvTlhkbmFHeG9NbTVFVDJaeWVEa3JEUW94YjFoeVNrbHdjMFJ3UTJsQk9GRmhhM1F2DQpTbE5ET1ZCeGRucEtZMFZoVjJSeU1tVkJSemhVZUhwek5URXJUVXRYWld3eVFtUmxUM1ZxT1RBTkNsZFlVVGRGTkhORVJWWk5kV1JLDQpVV0l2TTFCaU1tNXdjWEJMV21RMVkxRlBVVkpQYlZGbFlVdHFNakZWT0V0NlIwbFdTWEkwYm04MlIxRXZlUTBLWjNCM1RHRnJZa1pyDQphVFZPZFhKRWJWbGxjMnN4UzBwWU1FeEZTM2xCVjJjNWQydGtiREJsUjAxa09UZEtOVGhFVmtGdGExRk1RbXQ1TTA5V0RRcEdabXcyDQpUbFZFVDNkaWJWWk9lVEpJY0RORFJrWlJXbXgyU25RclQzbHROamg1Um5KTVRIaHJORVZUTlZVMlpUUlNURGhsWkM4MllUVm9ZVlFODQpDbFJDWW1ob1JWTXdaV3BHYld4TlVXNXRNeTlxTUhoV1NXdExlRFJtVGpkUlNYSm1aR1JVWVV0QldrTXlXRFkxYzJ0UWEzcDJRVU55DQpaR3RKZFEwS01YbzNaQzlzVURWMk1XbHRPVEpVTDJSamVFWjVjMWN4WWtKV2EwWm1XbUl2ZEdwS1VVNW9hMU5IUTFaa09WRnZlVmRxDQpWMmd2UlhKNU5sSldEUXBYVmxwUU0xaDRVREJVV1ZGMGVuWnFaMHQzY1ZCS1pFaFliRkZaUVhKemNXZE5ibUV3TlhObVkycGlOM2hXDQpWWGhuV0hwTkswdEJkMGcwVWtFTkNpOU9iakJqZFVWeFVGWk5SMlYzUWxoUEsyMWtjbEJJVURKSWEyVTBOMWxEY0ZFeVExSlBkVFkxDQpjMjVRTDNwamVtTTRMemgzVEVOUlUySmtWdzBLVkZSU05uUlBTMlZ4UjNoNFZHY3lTSGhsZFhOM056WlZkVEEyYzFZMFZGaFlPRGwyDQpPRkZyVW1OeGJDOTRhWEphWjJnM1FWVmhlRXMyVVdwM0RRcGplV1JXUVVKelFtdDRjVzFWSzA5QlVXRnVjMlJYVWxSbWN5dHpTVXhJDQpNR3d3Ym5Gd2RXSTFWR0ZQWW5KalNGaFBPVko2ZWl0amFtVlRXR2dOQ2tNcmFtOVRNWGRUTjNwcGIybFNkR3BOY1RSamRsTldMelpYDQpOVFJuUzA5RU4zRkJTRmxxZG0wNFpVSTFWRE5OVVVaUGJVZGpOVTAzWVdsR2JRMEtVbWt6TVV4cWFWVkdhMVV6UW1sb2N6WXZSV2MxDQpVREZqVjBkYVpWRlpRM295TUZSa1FuQkxUelJRT0daNGNVdG9Va2x6TWtGNlV6WnZXbEZURFFvd1JXUkRkRTVIVGpSVVMyeGtXV0pODQpURE56TUVWaE5WVk1LMjlOY1VWclNFMUtiVzFZWWpOaFNGcDRWMVpYV25CaU9DOUVMM2Q1V25aMk1Hc05Da2QxWVROc1QxVkpUMFl4DQpiakJwZEhaNlVHNDFLMlJJTVhreVZVY3hUbE5RUlVad2VuVkRhV3BuUm00MWNUVlhNR2R3VlRoaVMyOWljVkZxZHcwS2NraFZSRFZLDQpOMDR6ZUhGa2NFWXhPWFExTDFaTmEzb3JkalEwVFhobmJWSXdiM0JKZDNWR1JVNUVPVzVqV2s5cFdHMVZOV2RDTTJFMFl6UmxEUXBqDQpVMGRHTDBWWVVUUldlSGhtZW1zMVp5OU1NVkJXU1dWc1JsQlhSV3RHTkRKaWFrUnFhRU5RVTNSVFRYUjZTVmcxTDNWVFpsQjZlV1Z3DQpZa3dOQ21kNVZVTnlTbXhxZVU4M1ZHaEhSVXRPVkRaT2RtbElORk5XVERWM1dqQjFkRkJVWW05SE1WaDNha2hQTW5weFZYbGFlVU5xDQpkMlZuTm5oMFNRMEtjSEpxV2xGbUwyOXBObWhZY0dacFowbDFSMWhCVmtNelZ6ZHVjakJ5VmxKT05WaHBaVE5XZHpCaFpucG5UMHBwDQpZMUJDY0VZNGFqVkJORE0zRFFwak4zUkdhVGRoYzNSVldFazNlR3RxZGxORk9YQnBkemx4YVVsNE1XVTNMekJ1TDBWMlYxTXZXV1JSDQpXVkprTWtOV2VtWktSRFpoWm1OSFIyd05Dbkk1T1ZSM2RXZHpObFJUZUVSeE1FNUpVblkwUkhJNGNXbGtTWEpYUVRGVlpFWlVibkJXDQpjRW96VGxwRGRFWmFSVk5PTlVKVFZsVkNUR1prTncwS1NYSlZSRmRJT1doYWFUQkpkVGd2V0dkR2NFUmFhMHBKTDNacE5rTTVWVVJHDQpNakpIWkdaQmQzcGpNVzVZVVRnd1pHbFdkR3h0YVdVeE9EQkJEUW8wV1hrNVRuaDBUVmxRTTFsdWRWVjZRMlpDUmxneVpFOW9XRTlJDQpaR1YxVDBOalIxaEdlR04zVFhFMlVYWmFZV2x5UVVkbmFYcE5iRU5pVEdNTkNrbzFhbll5Vnl0RE5FcDNTR3R5V1ZSamNXSnBaMk5YDQpUMUpEZDBSSlRWVjNiekpoWTFOM04xUnZaR3BuYURaamRuaG5aVzl5UmtabFVrZFlTUTBLYW5CUFRHSTNhVUp3ZHpCWFNrTkpORk5xDQpOVUZSYm5rNFVUUnphemR2YWxGbVUyOURaVmRsVWt0bGRVUnZZVVpUVFN0RFRWZ3daa1EyYjBFM0RRb3JWM1JJYUZaa05ERmlNVFVyDQpabUp2VVdWWk5qUTBSa3BYU21jeVdHUlRZbXhhY1dKdlExaHZjMmsyTld4WWVGYzRaMGh2U3pCSVYyUkJVRUVOQ2xndlRGRmhNRlI0DQpOMkYwVmxsT2FuRmpaVWsyZGxwWFIzVmthSEpuTjBsNU9XMTFVRTk0U0RCa2NrZE5OV3M0SzJOMGVXbGFjak0zYXpOdU13MEtLMXBPDQplVGg0Wm05UmJWSjZUelZtZHk5d2FXUjBibE5zV20wM01IVkpOM0pTZEd4VWRraEliWEV5YkZsSksxZzRRWGN3YzNCeWRUZFRSMDlRDQpEUXBhWWxCQmJqWm9Wa1pDVG1WT01sQTNSRFEyVDBsRU1FUktaVGhyZDFaUmJYcGhUbUYzVDFCUWJ6bElTV0V2YVM5b1QwRllOMnhODQpWRGxTTlZjTkNsWjFhRGxPT0dwdVJHWldNV280YkZKNWF6UTNkMmhIVFZNemVYUlpRVGx1UmxGV2IyeGxVRWh6ZGxkTmVqVnVTa2x1DQpWWGxVT1VWc1IwbFJOQTBLZFdNemNsQlRObUo1TnpscWJUUlNNRTlvV2xOTWEzQlRNRWhFYUhCYWRrMU5lVlZtZVVNd00xcG1NMk5IDQpjMEZuYjFKT1RWaG9WSGx0VTNWNERRcENZMlp3Y1dWVWJISmtWMHd4UkRoTVUwSjZNaTlwZUZVdlV6WnhVbWhTT1hVdk9VOUZWR3RODQphRk40UXpkTE5rVkNNVzFVY3pKbFlYWlFZMDROQ2paVlRraFJUVlUxU1hrMVltMWpXR3dyWm1GR1NpdDNSakpMU1dGWmJVczFUVGxTDQpiRGxFZDJjMlJHczVaMjVQSzFoeGJFNHJWbkV4ZUV0RE9RMEtTSE40ZERsa2RuZzFVRkJNZUZkVWJURldVRTlPU25kclVUQklNRmQyDQpXREZSYlVsTFpsQlVjak5sYlVweU5XOXJiMVIwWTFSV2MzQk1iRnBDRFFveVExRnpSelZxYUROS0wyaHRTVXRqVjNKTVMxSkpRVFZvDQpRalJDTm1WcmJVRjJLMHBNTkhWMmEyWXZUbWRzYkcxR1RqZHRVVGRzT1dGTGNWRU5DbXdyT0ZKUGNVNU5SbFJOYlRNdlJqSnhNM0JKDQpUMnRXVkZsUllWbzVja05JUjNsNmNVcHZWVVZKUldrd1pXZHNWVXhsWlRoVGFUTTJLekZVZGcwS1IxcHpNMVJtVkRkd04wZE5NRE5QDQpUME5yT1U1eU9HNXNVak5yV1hOb1pUQTBOSGRrTVhaV2RrNXpSVkpLY2tOSWJUTlZPVXRHWjBGWk56UnREUXBWTWtaV2NUUlZZbGRXDQpSM2g2Ym1kdmQzSmlkRkJNVkZCeFNEVjZNbUppWmxodFNISllhM2xYYkdkWlZpdEJNbWgxU1ZBelExSjZMMGxsWTBZTkNsUjVSVGxtDQplV04wWXpsS09VOTNNV1ZTWlVob1FYUTRaWEZ2UzFaUk5tTmxSRnBJUlRCR1ZtNUxUbVpaUlRKaFZUUldWMXBzYVd0S1RYTnZOQTBLDQpjM2hIVW1Jd01VZGlhbTlXTTFkdlRXbDFVemd5VGpFMVlXa3ZVME42V1NzNWFDOWlSVXBMZW1keFoyUkZSbXczTkRONVlrOUtWRkJKDQpiRVZIRFFwQlZIWk1SRnAzVUZoaGJteFJWWGx6TlU1R1dYZHpXQzk2UVdzM09FSnpRbkZOWW5scU5YSXljVzVpZUZsWGFsWnlURXhDDQpiRmh6VTBaaGFWRU5DbVU0WjAxU2N6TkdkbE54VkRBMFRtVjBiblpoZWpjdmFraG1iWGRZTlhNM05YRlNaMmxhT1U1M0wyTXJVMG9yDQpSRFpUTkhJMVVrZHRabmRETmcwS1RHdzJialF2WnpKWlJVRmtZbFZRVVhkUVN6TnVLMFJxUVRSTVN6TnBha05LVlhWNVZtcGxTazFqDQpXSGxrVG1SUWVpdG9XV1ZKV2t0aVkxWkhEUXA0UVN0d1JHZHdTVVpoWlhkc1MyMXBaMWtyVEZwbE9FMDNRbUptV1RSdE5GcGxPWGhGDQphMmhwTmtrd1ZuTnViRXB5VERsUGVWRjVWbXcwVm1VTkNrVTVNekZLVjFSNFluUlRjVlp0V0ZBMFJIRnFVVWd2ZDBSR1lscDNjVXRRDQpZbk5HSzJsTVIzZEpjVm8xVjNGTVNUZEdjVFExUzNodGRrSkphQTBLZG5SaFpIbDZkaXRLYmxBMFpWSlNOU3RJZFZNeVQwSnlkV05KDQpPVTV3UWpWMVNURXZaRVEzVWxOWVFqbEZVemxVVG10dGVHRmtjSGxZTTFkQkRRcHJWVkJITlVsWVRGUTBjMDVKTVhZNE9YVnZWMk4zDQpUREZNVEVWRlJESjVPVXh4TTFoNFZUVmpXUzlLY2pWQ2NIUlpOR2RzYWtsaFJXUlVSVFlOQ25OYVpURjROM0ZMVFdScFRuZEhaVlIyDQpVbWhyYWtKV1ZHRmpTa0U1WldGRlEweHFNRTg0U0hVNGNGaERXVUZEZG5CblRFbEZZbXhETDBOUWVnMEtSblIzWnpWd1FVNXlVa05ZDQpkVVVyVm5adk5VeDBXREJCUjNwRlMzVTJNSFIwZUdNeGRrdFhTVVJaYTNRMlNuaDZhMjVQYW14VGFFSnlOSHBrRFFwU1JXSnJlVk56DQpUbFZ2WmxoeWExaG5VSFF2V2pKT056WkZVVFF4T0hGMVJVNVFUbmg2U1RCaWVVVXhWM1ZIV2pSQmVYSXdjRTkyTVhoRGNFME5DbGRTDQpOMGsyZWxKblZFUTBZM2RoTkVkdVppdFRVV3BhYUM5bU1VdzJaamhwUjBKS2MzVk1TV2hTVkROc01VNXNNVFJTVkV4WldtY3hkamgzDQpUQTBLVFZOWlRWVmpZM1ZpTldkdVdWbEZaV3A0TnpGcGExaHFNVTQzSzFCbWRXRXpZWEV2VWxSMVdXTlVlbE5sTlVwamRsYzFUbVZsDQpaVlJOZDBOc0RRcDNUV3BGUWxWR09VVkdha3BJTW05SlVTOTJWQzl0VkhadkszWTVNRWhXZFM5UGRFNU9iV2xsTW1GcWNsZHNSa2hhDQpTelJvVUhVMVJWVmFOM0lOQ2tnd1ZWcE9iWGxvTkZSTmVTdE1hMFZuYVRJeE1FeDBkV1ZWVlhjeWNYQXpXbkF4YUVscWRVb3Jkbk5HDQpkSFpLWkN0cVJGbFZZVVJySzNwUVJ3MEtiRkpWUmtkb2FEZzNWbFYyZUVwVE5HOHJjWGxVYkUxSlJEVmtkMFJGYzI5QldVTXdUMVJNDQplR3cyUkRGTU4ybGFPREJSS3pWUE9ETlZjVlJDRFFwSVJFb3dORzFLYVc0Mk1IQmhTakpvUTFoMmRtRXdhMlZQTjNkTE4xTXZNbE40DQphSGhoYVZKS2JIQTNUMEp3UkhsdFFrbHNVRk55TlhWMlJta05Da1F2TlZBM09YVkpRMVJJYldoSGRrWlRUM2xsSzNrd2VFWTFWMjFMDQpWVlpCT0V4RVpGWjRlRGhaVUhkNlMwVjBZWEJ5YVZaSFZqVXhOMFJUY0EwS0wwNTBNRmRUV0M5clUxcDZTRUk1VG1zNWFVeGlZamhMDQpVM1ZRV0VsVlRuaENLMEkyZGpSdWMwWXlWWGx1ZURoUlJWQlZhMmhWTVdrNFdFOHlEUXBUYlM5VlJteFRla3hQWkZSNmIyWlRNMGxJDQpNMVZ4U2tsalltVTBWa2R0YzJSWGVWbHZVVkJCYWxVd05VNTVkVGRRVWpSSVMwUnZjRkJJVW1VTkNtZGpRMFZEVmtKV2FWZFpNV2h2DQpabWQ0YUhkS1JtdzJUR1F5Tmxwa2NVWm9jMUYzZFhVcmNGbEhjV2RWTlZWcVVETTBiVFpITkZCdVRUZE1hQTBLWkVrek9VczBabFZDDQpjSEJNYm0xYWJXUXpUa3MzYXpGVlZrSnlSbmR2ZHpCc2RYSldkSFk1YjJ4MmFHTlRaVWRtTTBvNFQxTlVkMGRzSzNWRERRcEpSVkpRDQpXRlpTU1ZwcVFUbFRiMEpJYlZSc09FZFdPR0ZYVTB4eVVqaHVZblVyWVVOUGRWUldaMHBUYWxGYU15dE9hRTB3UjBwcGJqWkJkR2tODQpDalJxTDNaSEswbG5jbFZZVkc5cVMwUm1USFIySzJnMGJGWmFOM2s1U0V0dmFWbHlkVWx1VVZkMFNVNTZkakJhV1haWWFHMXhNMkVyDQpkRmx3UncwS2RIZHRNUzlhSzFCaFYwaEhVRFJDWjFaRk5tRmpZMHMwTVhSbWFGQnZZalV3U25ZeE5IWlFXRlF4WlVNMWJEaFZXWE5uDQpWVlEyVGxoUGRXeElEUW81V0ROMGNIVndibE4xWkU1a2JuVlJSV3RSU1RsTWFtMUpNbGhSYldWTlRWRlJhMnROYkZkWk4ySnFPR1pVDQpWa3MzZVhWRmVEVktZVmhJZHlzTkNrSkhNbTFFZDNOS1VtcFhNRUZrT0ZWTFIzcEJNVEJRZW1NelltOU5SR1pVVWxwRFZYWnRRMWh2DQpUVk5RTXpOTFlsSldVVVp3TldRMWFqaDJadzBLYmtwSE0xQnFjQ3RPUVZFMlNVOUdTbmRDT0RGcWRqZGFSako0YVVWVE9URjJTeXRFDQpVMWh2VjJsTVEyeHJOakV4U0RCNVdsVkpkamRpTmsxUkRRcG5aemR6TDBkaloxUXdhMFJWVFhaUFRXZEVkVVExYzFsRmNDczNPVGx3DQpXVTlNYURaMFZrWk5RMEV6Ym5FeVdXSndkMjFXVTJwTWRXY3JVemNOQ2xaNFpXbzFjMVF5T1VjMU1XNVJWWGREZFRkbFluRnROM1JaDQphMFoyUlZaT09XMHlZblJRTjIxb1NFRkhjVVV4YkhRd2FDOVJjbWd4UWl0cFJRMEtNV3BoTjJ4WWRFaHZUemRKYjFad1FtUlRXSGMzDQpSalppU0dOYVdFRjJRVkpUVFhWYWIzVm5Ua1Z6WkRkcFpHWkVVSFJMZVVVM2VtMHlTelJvRFFvelEzWlBNWFJVUkhBNU1VVXlRV1ZKDQpiMmMyWTNwcFdGTjJjSGw1TWtFMldrNTRUbFpTY1U0M1FrVlpiM0k1WmxsUlVtRXpNRXRXWms5U1JYUU5DbmhvUWpkR1Jqa3pMMHg2DQpkRlZCY0V4dk5ITjFOVEl6UkdkdmRTOTNVa1JpUXpreGVXZzVja0pWTUdKTVJHeExNVzVvZFZsU1UxUXhhRzAxWkEwS2NHcFNVbXBKDQpSMGRtVVRSTloxRllZbXBSTDIxa1lVUm5ObVZrUmpaRk5sTXhkMHAzUms1b01YbzNVazlEZDI1bmFHRmpiSFZsTW1zclVpOW9EUXBYDQpRMlpTZWxGR1RqQTVWSE0wVGxjeVJEQlBOa2xuWnpsWFNFeHViakJYV21aWWIyOUJWRGsyV1RnM1dHSk9jbGh4YUhoWFkzQjZhVE5vDQpXWGNOQ21SV1QwTjRaamhGUm5WQ1pHWkhORm8xVWxkdGExaG9aMVpHWms5TE1VaHhaalJFYWxoamVsQmpiSFYyTkRaTGRHVkVZbmR2DQpkeXRLZUdWMlJnMEtRV05OUkZZMVpVaHlabWwwVFhWTE5ITXdOa1ZEYkU5a1JVdGhUMFJzYlVOR09WUjFWRmREUTJoUFJHcDZZelJIDQphMVZXVG13eGMwNHpVbXB2RFFvNFlrVktUMHhVU1VGaE4yVjZWMFJyUTBrNWVrWk5RbWxqWTFSd1ZWcG9XV3BHYlRCRFNXbDJVVFZqDQpaa1pOV1ZBM09HWXhNbFUzWmtodVZIWU5Da2h5ZDB4MGJqTm9OMnhDYVhSR1UweHVjSFl6U25ONVNWZGhOR1ozY0hrclpqbFdjQzl4DQplVFJLU21GTU4wUTJNbmM1UVM5bloyUlhZMDFaTUEwS1RXWjZRbWRFYml0WVMwcDZlblJ4ZGtWNGVERlFha2RFTVRsSFprVlNOV3BoDQpRVWN5VTBKS1dVbDRhbmsyVjFoemNEWnJSVTR4U0RBM1JrRm9EUW81VTJONVNqaDZOREkwY0dvNVNrWlBUR1ZWVm1RNVJYYzBiMHc0DQpTa0ZXUVZOM2RHOTFjRlZPZG5KaVVrRlRWMjFRTUZBeFQyNDJUelp3VUZnTkNsbFFXblZSYjBoSU5sSXZka1U1TW1ad1ZVazBNVEJJDQpRWGh3VkcxVGNURnlkR3c1VW1kTWFEYzVMMmt6ZGt4SWJtaE1NbFpQZVdaNVMzZ3lSZzBLZUZoQ1NtVlZPVEpKU1c5WmVrTkxiRzlHDQpSVVJ6YlZSMVZ6SlRPWGx1VXpKdGNWUkhNVVFyYkdwVGQxSkpOblZpUlRFNVZtVm9hbEZuUTFVekRRb3JjRGQxU2tsSWVVWlFOU3RwDQpZamRtU2s5a05VVldkVkpXTjJoR1MycGpTMlowY1N0alEyRnhXVmxQTVdGdE5WSm5NRWN2Tm5GR1p6bEtVazBOQ2t0RllVUjNVbWxqDQpOR1ZtTkU1RFNWa3hSRlV2UjJkeFkxbG5MMlJ6U0ZwelVVVjBTSFFyVTNaQ2NWSkhMMmc1VEdSUFNVcG5RVmhtY0dONGJBMEtXVEp4DQpiblpJUlU1T09IRkZXRlZ2T1haVFVWUkdTVVZXZUU1b1ZFOUVibFF6TXpSR1kyVTBlVUpUTXpsbFRXOURNVWhUVFRkamFHYzFNalpvDQpEUXBWUkhCa2NVRXdjakI2U2toUGMyNXdhbkZGUW1odlVHVlRkbFJQUkhRNGVVWTRWV1k0VEdwak5XVmpZazQwTkV4cmJtUlNkVTkwDQpMelZ1VXpZTkNuQkJVWE5XTjBwcEwyaHVSR2gxUTFGS2FEQkZlazlGTUdaeVMwcHJUeXQyU3padWFDc3JSVGRvYkdaUlkxbHRUMnRWDQphM2RZYkZFNWNGZDFRUTBLUkRkcEx5dFVTRmsySzJKSWNGaHBOeXRrWTJ0cGFVNDRiMGRhZWtJMmN6QkJVVzhyTVhoWVkwUk1SMVJsDQpWMU5GVkc1d1owUkdRV2xVYWtNeURRcDZRVmRxZUhGWlJsZG9hV3RLWTNvNU9YUmpVWE12TUZFM1UwZEtiM1JpYldFek1qVkpPR0ZrDQpRbVJITmt0bGJrVm9TMGRhWm0xUGVsWnhhRW9OQ201QmVqWlRNWGxuUTFVNGNpdEtVak4xUlZGUlNEUjZhV1pHV2tOeFVIaG5lSFphDQpiekJHYUVsa2Izb3lWVE5KVGxOMU56Vm5ORFpLU1RWWFZRMEtLemhpYUdaWU0wVnhTVWh3TkdoVWMzbHRkRU5JTm5CTFFUWjNZVXBPDQpaamRQV1VFelRFTk9TREY0ZUdodVNVdzNXa2R3VDNaR01EbFFVRk55RFFwQ1pYVnNNM0pTUVhoQlFVWjNaRE5SVGtwdVFrOUVjeXRJDQphRXhhZUhJMlduWlRTa05uT0RsNlMydFROVkZvYzBsMGJtbG5aVGhuYWxKcWJrRU5DalZXU1hwcE9FMUVjeTlZYkhJM1dHa3haRzlsDQpVMHRZZVM5aFpUZEZiVnBxTWpOVFlVaFdOa1JPYkZrMFVHRjBibFprZEZJM2JXZEtibkJuVVEwS2FXY3lOWFJxVEhkcmN6Y3ZiVEJSDQphRkJvVDI5WFRHeE9aSFpQT1VsWVVWQnlUbnBJWVd0SE5FVkZRamRvWlM5cE1HdDFhSFZMWWtaelVFUmlEUXBaYVhaalNHWnVNbTFYDQpla1J3YkZNM1dTOVhPUzlGYzJkQ1dIWkdWSGhKVFZCcU1YcHhRamgwVjI5aE9FUnFOVzF4VkhaSE1YcGFVVlkzSzFvTkNtWkdkblIyDQpkM0IzTHpKeWJuTlNVR1I2TW1aYVRHbDJla3BSZFdOd2NXZHVOVEJRVlhGQ1luaDNiMDlTTDBaM1NtbHlhMHBpU1c0NU1VeFdaUTBLDQpibVJNY2xwb1NHeDNTMlF2WkVsSFJqRldaa1ZhUlRSUFlWUmlPV0ZWYWpkeWNUQjFWMEpFUjNoME0wNWtZaXREV2xSdmFFNDFiVEkyDQpTV3RRRFFwNk9HMWhLM2cyYmxOMVUzb3ZlVmRIVGxNMk0zazJTRzV5YUZKTEwzVXpWMjV4V21KMGNEZHhjMDlPUkdGQmMwNXpXVzVIDQpXVFpvZEhWNFdXRU5Da2R3YUVNelZ6aDBWbEZRZUdSQ2RGUnFiekpLYUdsd2FtVnJiak5pUVRKamJYcHBVMHh6TlhWa09VRmFWMHBEDQpaWEZCVUZBeWNGWjRZMkpxYmcwS2MxZHNZblp5VlhSUGRYVlFNWGs1Umlzd2N6bEdTMkZyZDFOdVNFOUVlWGhMVkRJd2N6aEpTbWQ2DQpNREZuZVhOME1FeDZaRWxaUXpRelFsSnFEUXBqYVZKcFQzcElWa00xYmxaNGRVSTVVbVE1WTFSa1kxbFVURkJMYkhnNU5HVkdLMmt5DQpVMkZrU3k5NmExWTFXbGcwU1hsak5HbFROakJ5Vm1nTkNrUklWMnR0YjNCUmJuUmpaWE5MTmtwaFMxb3ZTMncwWm5WRU4wMHhhVmxuDQpVMjFQZWtsS1Fub3hNRXBKUTB3eFpFeFJNbVp1Vkd0U2JXUkpNUTBLVG0xNWJuQkJNSGRJYTFZck1tRXdUWGsyYTNoeE1YY3laMEZ6DQpRekJPUVVaTFpsWXljM3A2TjA0d1JHNHJZbXBuU0haMlpuWTFSVXN4VEVSckRRcE9kRWhIUzBack1YcFBVVEZyZDA5aFREWTVSVVZxDQpWME5YZVdWRFUwRXZORnB6UTJoTWRGRTVkVkJCZVM4NWIwVlROVTh6ZWt4NE1ub3lZWGtOQ2tWMGIwODJkVEJLT1RJNWNVRkhWa2RIDQpOWEF2VG1WaWNURTVkbTB2VVVFd1FsaFphRU5OY1dRdlFWbHVNMlF6TDNKeWExbEVjMEZXVEdoM2R3MEtNVTVIWkU5cE9HSTROWFpZDQpTSFEwWjFCYVNraG9RbWxwVG01WFYwcGxWa05GTkhCSEwyWXdXbnBXTTNkWVpGY3hXVm93WVZJNVRXdHNRVEZVRFFwS09XRnFTM0p4DQpkVlZUWkVjeFRIaHpTMjQzUTFWWmFYcFphVGxyWWxwUFlVRXdMMjAwYVZoUmVUZHZjVzlqU2xaRk0yMU9OVmd3YVcxWFVWUU5DbTVaDQpVM2t2TjFkclkxRkdNbVpIVGtocE5YbGxSVTVtVDFJMFRtUm5ObGgxWTNSeU1pdENXbXc1TnpaMWEwdHFSVEpYWVVONGFHZEhkamRFDQpaQTBLVm5CalRGVkVWM0ZQVTFZMVdEVnlOMDF2UmtKa2JrNHplRXhhUTJoWGVtSkRZVWd6WnpWeU5XVXdOa0pPYkZWckwyVkpVRWRSDQpVQzgzVEdSSERRcGpkR3QzZWs1QlNFWXJWbHBPZWxGWUwwMTVia3hTTldRcmVuTmljME5pTmtWRmFIQnNaVEV5VTNCdVl6ZzNWRVppDQpXRUpQTDBNM1NVWjNlSFlOQ25STmJITlBWa1JwV1c5SU5rUjJNamN4WjJwV01qTmtLMWt5VkVwUldHNUdORk14Y0N0dVdHOUNkbGhVDQphUzh3UTFGYVlVNVVZbkI1Y1c1SlJRMEthblZ5TlU1U1dFOXViRlYwZDJoclZIb3pTUzh6TmpKUmVWaDVaelZtWkhCNVRqVTJkVGh2DQpLMWhOUzNOT1JIVjNXVEkxTUZBemFqSk1PSEpuRFFwblRGZElSRkZHYkM5TFkyUTBNbWd2Y0VZNVpuSmlkblZWZDBKTVVrMXRUMjg0DQpNbU5SYVhWMVFVSmhkMDkzZGxRMVIwaEdZMUpETlZFMlpsTU5DbEprZUZocmRtRTRjbmhFTUhKQ05FVTBlbVpTUVUxb2JVRlBUWEZpDQpkMDFuVkRoUWFXZFpVSHB5TWpacWFHaFZlalZDV1dGeFJGUnRVRzVpYkEwS2QwOXVPV1JQYzNOSFpqaDRNRzEzVEc0M1ZYSlFNVVYxDQpSVE5yWkVsU1JHa3pObEU0YUhObU9VaEJWMWN2Y1RSdU0wY3hTRFJhVWtoMlZHTldEUXBvWmpsdE5ETlZaRzUyZUV4dVVHbHJOM1F5DQplRXd4UlZveVFWZHlSRXRUYlU5TlIwaEhSVVZvYkRoeFlreDFOSGxVYW1kaWNWVklPRU5GVUdFTkNtODJObWxtV21JM1JVOVJRM0ZDDQpWbmxHZDA1d2QwTnFNSE52ZW1aUFl6bFJRazFxZUZkNmVHUTVLelZVZFZSR2N6VlZTa2xUT1VReVRITlllZzBLYURoR2FIYzJUbmR1DQpObE5pYTBSelVGWnVjR1Y0ZGxkSFlYUnFjMlZVUmpaeGJqY3dNV1JsZERCdVRtc3hka3MzU3pGNmNqYzVURWxLYVVGV0RRcEhVVEZLDQpOV1JQYzNoRVRITktSMmhEZHpSRVpWUmtRbkZLUVdwcWJtMDBSRzkxTUhSS2NUZHBXaTlUY25GTmVDOTJkM2N6YVhkb2RpOHpUM1lODQpDbmhhT0hWdWNXSXJRVGswUTJwNVVFaGthRTVPVmtNeUsyUnpiV2huVTJScVlVcHJURkJuTWl0eU5uaEZUWHBDTmpkaWRHMUVTblJ4DQpObmxpTVEwS1JGaDNNMUV5Um5GdWVYbFdhVXRMVkRoaWQxcEpOalV6VG1sbFJWSjJTVmhPVldZd1IxVTJOV1puWmtwQ1VFTXZWVXBNDQpSbVZYVVROelZqSjREUXBGVTBoNlRrcFdLekZ0WVVGQ1NFaFVURTFuTW1Sb056aDZhVmxHVmpNMGNVRTVTSE5PUzBkcGRIZGtlRFpPDQpRVlU0Wkdwb1JEbEhlRVJDYVhVTkNrRk1XSGhQVG0xTU9VMURibGhpTm1seFozVmFVRzloVDNWTGF5dERkbHAyVlM5VVNWUnNhaXR2DQpaRmh1WkRkWlFtUnlUV1UzVTNOdWVYSjZRUTBLTjNCbmJrWkliMmRyWnpkU1UxTlZNbXBDUkd0cVVWbGFhbTlDVTFOSE4zZHBXRVl2DQplR1F3TVUwMlkxSnZibkpHVldoTU9TOXNlbVpqV0M5bkRRbzVTRmhGV1dkWWVuVlVlSE54UW5oTk1FVnlaa00wTXpjelVuVlBVREpDDQpLM1V4WTIxdFdVMVBhRE5NWTJkM2MyTk5kWFpRY0RsMVQwVktRbk1OQ2tsSEwwaERhR0l3TkN0dWFqSnNSSGxzWVVSalIwOVhVV05uDQpURnB3U2toQ2IydHphRlU0V1hwTmFVNXZUbE56YTJkT05EVkVRVFJZVEVJemRBMEtjblppZFc4M09GTjZTalZRVlcxQ1JFNHJkR1JaDQpSbGd2TkROaVJFRlhkelJUTkd0WmFuZHRjeTh5Tmt3emFrUjBNbWRuWlc1UGVqVXlLM1p4RFFweU0ySjVWMHBKU2sxa1dXOXNNREUxDQplaTlqTm1GTFJuaE9NRlJxSzFOVWNqVTNaWFl4U1VaeVRGZ3ZReTlYVjJkVGIxZEpUR1pvS3pZMVEzVU5Da3BUV25SeGVVNVZla2RxDQpPWEJGUW5veVVqWjBiM1ZTYmtGamEwVXJZVU5aWWtsNFYyMXBXbFUzYm10R2NrTmpiMWM1WW5kcVEyZHNiVmhEWlEwS09GUmxOa2NyDQpVMnhGY25SMVRFRlJkbXhhV1dWc1lsRlBWR0pPYlU5dVQwWTRSa1pyTHpCdGJ6VjFXalZvTlU1UWVXMTBTMmRsTVU0ck5IQXlEUXB1DQpURFJZVjBoNk9GUklPVXRHUzFCbFFXTkRVRlZwV2pjNFJVdERWbE42VG5oMVJFWm1SMGg2VXpKaE9GTmtiMWh1ZEhOWmNrZzVja2hPDQpNVzROQ2psSkwwWnlRMEp3ZVU0NVYzcFdNRVZIUmxsak1UaExXWFI1TkhSSE4wTjVWMk50Y0ZCWk1UbFVlWHBuVjJreFRXSm9WR1prDQplakpOVWtSbFpBMEtlak5rV1M4d2JWUk9VVXQwZDBwdWJHWmxlRkF5WnpGeFlXRnRZWFJaU2xOVFoyZGxZMDh5VVdOWWVtVjNUbkIzDQpkR2xoZFVVMGNWWlhTSEV5RFFveFV5czJhamhVVFVoTFNGcEdPV1ZQVlVwbVRtcHZSRTlWT0Zkb05qSndNRlY1Ym0xWlNuSXJZMWh4DQpiVzQ1UlZoQ00wRXpPRk5vTHpOMmR5c05Dbk5PYTBJM056QjZTV0ZUY2l0a1oxQXJORWRoYXpSS1RWcFBhVkoyTURScFdtSlVlRXRVDQphRTk2U0ZKRVVETlJTV0ZwSzFCcVEyaFdaM2gxVFEwS01WWldVMmRtYjFkeGJuaFhUMnhYV1hsb1ExWmFUMlpoVkM5S1QwVkpORE5NDQpZV2RGZWxwbk4xWkZibkJhTUhRNWVEbElUMUJvUmt0Tkszb3pEUXBxZWxOWVJUWmthRU12WVc1UWFHcEVlR1JKUzFJM2QwRlpiM2xVDQpOMmxQVVRCYVYyUjFiMmg0ZDBRd0wwMWpPVk4wWldobWJqZFFOVVpsZUdvTkNrNW9VWE5DZDFadGVVWm5NM1kwWkRaWWRWZzFaMjgyDQpObkl4UlZneGR6bEZaRGRNU21SSVdUTXJjVUpNWWtjd1REaERTVGwyUm5sNE9FSkVRUTBLYjI1MEx5OUJLelkwVjNkRk1FNUNiblJEDQpSM0l5WnpaQ1RUUk9TRk5tVEZSUk1VWkpVazU0VmsxUE1rVnNMMHB5Tm1odFUwbFJaME5TYlU1SkRRcERkblJuVEc1U2FVcFpkMjF1DQpSRlZMU1VsM1lraEJTRFE1WkRSSmNFVTJUVUZFU3k5RmRHNXhSRlJXZFhVeVpHVnlRbFJEUzA5WlYyMW1ka1VOQ25WbU5GSmplVWRTDQpVVFZTUmpWbmMzQTJZWEJtYUc1dVJYbzBMMmR5Y0RSNFUwNVNORlZvWkVOcE9YRnpTbmhoWnpZMmJ6bHVablp0YVd4clJRMEtWMVpsDQpRMVkwTUdrelIwSXhhQ3RrU1RaVWIycDJZVEZPSzNsRmFYaFVlRTAyZDFOVFFtZFNNVGRZTUVweVkzaFhiMmxvTTBWMFVYWnZSVEZDDQpEUW8zV1hSNE0xZHRSbmhDVERGR1FtNVdOQ3RJYjFwdE5VdFpRbkpMWmxOUFUzbFVWMnRKSzA1NFZVVmFaa1JpWW5WV2RYRnZPRXBODQpUV3hPSzBzTkNsSnNSMHRXVjNBclRFOXpRMGRqVjNWcGNEbDNjVWRxT1RZM2IwRklSVEJpWVdaNlZXWmFSVlYwYVdSSFRISlhjbWxTDQpZbEJGTldoS1ZVZEVOZzBLTWxCNmRXeDZjV3cwYUZad2VIQXhWWFZsTUhsRGVVUXhZeXRJTm5GaVRFRkZURGMxVFVoME9XMUJja2xhDQpXQ3RWZGtkMUwzRTJlRWxIZG5sWERRbzBhVmhyVEdaQ2IyVlVXbUpyT0hjMVNVSXpWMnB2ZEhSNU1WUllNbWt4V2tFeU5qQkhVVXB4DQpiM1EzUm1WWVdXUmllREpJVFdWTFZVTXphUzhOQ201UFNFNTRkUzh6TW5wT2VUZEJVVkJxZGxObWVYRTBNbmwyVWxGSlJtUkJSR0YzDQpTVlJUTWtKTmNUQk1jbVZoT1VObE4zWm9PV05oY2tKbk5RMEtlWEo0UjNCTlJUWlphbWN3WW5aWGJrcHJNelJNWlVOemN6WmlhVk5WDQplRUp1WjBGbk0wNXpaVGRYTXpNM1JXMXZhM0JIVVhseU9XRklWRU42RFFvNWNFTnBMMkZOU2trNVJIbHplbnBKY214QlRrb3lhVVEyDQpZMWxpUlUxWE1VaGxja1pDV2psUmNGVlhORzFyUkVWalRrNUtOR1JET0dkNVdESU5Da2RYVldwbFMwaG5UV3hFVTJWS2JFSlhWMVpxDQpWVmgzVW5ScmRGTktjVTl3VTJWNFdYcDZUMkprTWt0VGJsTkZZVU5QVURKbloyb3daazFHWncwS1VVOHpOMVpqYWxoUGVuWnFjVTlaDQpNV0prTVZOU1pXWnlTMUp3WldsM1ZXNDBORWRsTDFoV0wxb3lPRmxYWjJ0VU9HRnBXa1JyYkdFdlVYbHNEUXBxZDIxNE4xRkxRVFp2DQpUWEprZERaMk1tMVBNVmRoVDI1R2NVZEpjMkZ6VGxGeWRFaENNelpzWVdkblRsaEpkSEJNWXpkQk56bGxNVVJ2UkhZTkNuaFBSbmw0DQpTRk5CYW1GVk1DdE5NRXBLV0U5V1VXUnhVbFZXYkRoQ1YyZENlRE5WVVZaeVVqTjBZa1JLVnprelFtbEtSM2xMTVRWeVJWVnlidzBLDQpMekE0UVhsUmREZ3JVVW96ZUd4SlVtUnNibVpHV2pNeVNsY3lWMkZPWmxoeWJqWkxOa1pUZVdwbFRUTTJUbHBuUVU1Q2JqazBXRkp2DQpSbXRaRFFwME0zZFFUM1ZvZDNwSmJVUkpPVWxwWWxsdmRHY3phRmhzZEdSaWVuSkNOWGx4UlUxaVducHZObFowYUVOQlkwVTBkMUpPDQpRMmxhVUdkbmJsY05DalZ2ZVdaTlVXeGFOMVJQVjFGa2FqRkVZbGMzUm1WbGNuRm1iVmRJWkhneVpXNXhVSE5xUldOd1REWm5PQzkwDQpibFJSTkRsNk1rMW5WVFl2U3cwS1pIWnFNMUpNZURSbmVYRnVVbkJuTW10SlFUZE1RbmRyYTJwaWNFSXdRM053V21GckwwbHJRMGcxDQphSEl5ZDFoT1ZTOURMekpJVjFoT1NuUm5EUXBSVjJwaFpsRkhPRE4yVlVsc2NpOWtTRGxZWVV0UVdFZFVNR1JXWlc1WWRqUjNaRzlwDQpjRnB4VVRGaWVuTXphbXRvT0hkdlJGUmxUWGxET0dZTkNrNWtSRTl6VmtwYU1XOHpiRVV4VXpKa2NWaGxTRU5qVEdOaE1VUmhNVlI1DQpiRWxJU0hrMWIwdG5VWEJVUTFwRGQyUjRObTh5TkU1VmMzY3ZWZzBLT1VGSVJsUldURVZhWkd4NE1GaFpWRlZyWnk5NmNHaHhNbU5UDQpSbVIzWmt4eVZ6VlpkWE5OZEVaSGJISlNkelpPZEN0NVprODJRVzFPWTFCTURRcEthaXQ1VURkMGNsRmhjWEJPWm1abVdVSkhaV2RUDQphRk5PTUdrMEsxZDZMelUyWTJWMVVtRkpka3dyYkVSc01sRlphMFJtTjJwSFpGSk9ZVUVOQ210WWFsZ3lVSFZKYW5OYVJWQkRlRmRVDQpObFV6Tm5GM1FuWlVRa2d6UW13dlQzVnRZaXRWYld0dlp6ZHFUVVo2TlVNMVNGUTRjV1ZLWVU1U1lRMEtaVFpaYW5CUmRqQnRMMGxWDQpRbloxTW1OVE9XeEJPRFpxVmpNcmQwYzFVMWhHTmpoSEsyVlRSbE5CZVhZNU1DdEJWVUphT0dSclVtWlJOMlpCRFFwaVNuSlFRM2RCDQpRM1JJYjFSU1ZEVnpiVmx0Y2xaRmFrWnpSMjl0YVhoVWNreE9lRnAyZFU1dlN6WlBNbVI1YnpSTVEwUllWbXMxVFZwUVJYWU5DakZJDQpkMHBzU0VKMmMyOVZhVmQzUmpacmREWnRSa0ZDVWpSb2RVMXJPVFkzZDFWc2MwSlZSVGR2U2tjeE4yTnhNMWxTVGtwNlptZHNZbXh6DQpUQTBLWlhWMlNtVjFhREJPV0hSWFlsRmpNVkp6UW5sYVlVcFRkVU5wY2pKd0swZEJUVmhyTVROMlFUTnlPRTlNWWpWQlJtcHVTMDVUDQplblZpU0RkTkRRcG1iRFpWU0ZjeVNsWndZV3A2UlZvd01IQm5aMGxFWTNOVU5GUXhXbWMzTTFSc1JrRnliMGxHY2twVllXNU5jRTgxDQpZMWhxTDBSak1qUk1kRFFOQ2xaMk0xZFhNazlGUTFkS1ZXOXZVMVZxWjB4WE1XZ3lMMHRpVlV0WFFXUndObnBqZW1rMWJHaGtVbkZGDQpkblpLVW5ZdmVUaEhRMHRTWjB4MGJRMEtVWEkxV21kMVFXMTNTR3hXV0hOQ01IUm9NSE5YZW1OMWVtSlNTVTgyTHk4M2N6ZGlZeTluDQpja1o2WVhaMk4yRnJhblJUYW5RMWVtRm1lVXBQRFFwUlMyTnJUSGRsYXpKRVNFWnVibEo0VFdzNGJrTnJUVUZRUlVkdFFsWkViM0p0DQpURms1T0dsU01uWm5VMHhGVUhoVUsxSnpORUZVU2pGUFZDOE5DbnBwTmtkTWQyVkNSbmswZUZoTGNHMXVZa2gxUkd4MWIzUmxjMkpHDQpTMk5KTVdnM2FVdzJOblZoYTBkWGRWQm9PSHBxT0VOQ0syVXZWbGd5V2cwS1RrMXhOSFJFUWpRM1dsSjJjbkk1U2xnd04zTjRlRFpNDQpTSE5JWVdGQmNUZFNWRkEwT0VkclpFVTBWVXBwY2tSS1drTkdkMUpLVWxJdk1UTjVEUW93YkVsMlp6QlpTbHByUmpCblVXeFlSSEpLDQpjemdyZWxsMWExcEJNVXhNVkZSdVdrRkdaV0ZaVTJaNGRFbEdWWE5yUkV0d1lTdGpaMlp4TjFjTkNtUXJRbGx1WmpCRk1VRkJkVkIxDQpWRlp6VG1VMlN6RXdkMHd3V0dOT1pUZFpaR05FZHpWblNEVXhNek5YZEdWV2JHTjRRVmhuU25nNVFrbFVVZzBLYVRSb1VqbG9lRWhIDQpNVzFSU2k5NmJtRTRTWGxTU0VsYWRGWnViVGR5UzNKeFlteHRjMjA1WWxaUFFtVkhVbVJWVUdOQlZFUnJOa2xLTWxkR0RRcHNNM0ZPDQpZWEJpU0RaNU0yVndNRGMyVHpWQ2VqQmlTbXB5V0ZOb1p6SndRVWxtY200M1ZWRjBjV2cyZUhsc2FVeFdkRk5qUm1KUldrczNTalFODQpDbEJ5WjFoS1JUSm5lVlZvTVdOb1ZqQjRTV1ZvVEhCMGVrRnpXa1V2TkZsU05IRTVNVzR4V2xkcFQxVTJhWE5TSzFSbk5ub3pOelpYDQpUVWhKUVEwS05HTlFiME5vVlVkUVNIRlRVWFUzUkZsVGJrdDVha3B3YkVKTVJteDNWbk5PVVZoWlV6SkhRbXcxTW1SU2VYcDFjbmhDDQpVM2RhWlRsU05VRmpEUXBOYUU5cFRFRXpkRUZxUTFaclpEazNjVGRJWkN0WGNrMU5NMHRNVFRkRFowOXNTVkYyVTJFeFUwOXZiR05EDQpjRGxpUzNGek5WWk5Sa1ZwUW13TkNuTktUalEzY0VwcmEycERlVVk1ZGt4TVFYUXZSMDhyUWxOVlNYcGpSV1F6UlVaVU55dE9VMVY1DQpkSFpYZVVkbmMwdE5NRVEzTUdaQ1FsbElaZzBLUm5GTFJEQjZSM2RrVms1a2FFZ3liRTVvZGpJdlpYTkplRWMyV25wVWRYbDFNVzFUDQpTRVZMTjFKamJXcDNkVXg0ZEZSQllsZHpRM2huZEhJNURRcG5XV3gySzI1Q1FUY3lValZ0VlhGSlRVd3dSVmxtVEVScVduWk1Ua0ZNDQpia1ZNTmtGSmRUTnNOMjF1WWxsaFF6SlVXRk5wWm5kVlF6aExVV2tOQ2taWmFGcFJTbXBaZDFJclRrZG9ORGgwZURKa1YwNUdiRWswDQpVMDRyY210b2NtOW1NakpPYVhNd0wzRkZTbHBYVjB0VVEzVnhaMWczVGtaalVBMEtSMjQySzAxUlRXVmhZazVNWTNNMU1EbEtaRWt2DQpkemg0ZEN0Tk1sZ3ZNa0U0U0V0RVRGWldVMk41UldkcmRXMTRaMUJWYlhGM1NtaG5PVGhKRFFwTk4yRmxjV0p0VVhOalVqY3ZiRUZ2DQpkSGxYYzNsaVRtZFBVMVE1ZHpaWmRuaFFWRzFuT1Zsa05tWXJXVmRKYVZSaVRUVjZWVFpTU2t4Uk9YSU5DbTVxVlcxdlFuSm5hR28xDQphSEpOZUhGcmIwNWxWMGhqWWxOUGJGTm9RVXN3ZGtwRVQzaGphVEZ6SzFOelNrdFJhRVZoWVhsbWFVVnVPRzVNU3cwS05FOWxjbFZZDQpXSEZvUlZkeVJFNVBSSGhFVG1sR1ZGQlhkbFpqT1RCMlYwZE9OblpFSzFOWGJuRlJSRGhDVDJ0TmNEUkpTa2s0YmtGWlQySnFEUXBUDQpSbXBsT1hkMFVtMTVaamh0U2pSb2JIWm9kbUp3ZEVGVWVVRmtlblZVTlhBeVMwNXlZVWQwV0dZNGVrSmFTelZIZVRoTE1uSndRbU1yDQpPVWtOQ2xOM1JHWndVa2R0V1VSWk5HNW1iR3hzYjJWcVkwaDRLMHBWWTJ0alduRmFlV3QxTUM5dmRWQjBNVWRRYW1kellXMDVUWEJ0DQpOMDVMVDBseVVBMEtVbEJtZVhSV1FXNW1jWGxSY25SbE5EWm5URVI1WkRGTGRuaGpURTB5VjNSRmNrWnFTMnh2V2xCU2FWTXdURk4yDQpVVGhXWm1wa09YRmxkRFU0RFFwV2FWZHpaVWMzWW5aNFRGUlZNV0pITTBkVFFYQTJWMjE1TW1rMFpGZGxWV0pGU0dWSmJXRkNRaTlrDQpSVXRTYzJSeGVISm9kak5vU21aVWJsQU5DbGNyY0hKUk9YQlVWa2M0YlZGeVMzTlJNMjVrU0ZSMGVsRlNUSEJzUmpaYWNIcENhamsxDQpaRFFyWW5KVGVHNU5TSE53UWtrME9ETnNPVkZRYUEwS2FUZzNkMnBsWjBWMFZ6RXJhbk5rTkhobWNsQm9iSFl6YzFOckwwWnFjbkVyDQpNbEUzUlZaQlNtMVNkR05LY0hSdlNscDNlbU5ZUzJWb2EyVnJEUXBhU1RGdVJpOU9aMFEwZUdsWWEyZGtZamhtV2t4VGQyUTVURk14DQpXR01yVFZwNWNsbFlNSEJMTkZCaE5scGtkazVvUzJsUGRraEtiR3AzUTNrTkNrWktaRTh3Y1dremN6QnlRamh0VGxGRFYyVm9TQ3RCDQpSbVprZVdWUVNsTkxOeXR3YW5BeWQyVnpTM281WVhObFdrUnZURXBRY0dwb2VEWnFNZzBLY2pSQmVGRlRWVXhJUkROVmJEUnVhWEZKDQpRemRpU2xjd1EwVkZTazlxVlhSdE9FMVFPR0lyYVhrdlpYSjVZMjFuUlVOUGRtYzVWWE5aVUZKaURRcFpXbm92ZG0xdldYZEZVa0pRDQpZbk5wUjNCdEwwaERXV1JzVDBkbVlURnJhRVZCT1dvMU5UUm1WMWxIVEhsTk9VWXlaMlV4THpkUlNEZzBaR1VOQ25Jell6TkdRa3h6DQphamhaWkN0aVJtaFViWEZtVG5OclpsWkpUalVyY21sb09XZFpNbWRuZVVGelVXVjVhRWhxVWs5a1JHTmFOak5CVFVNdmJnMEtNMnRTDQpVRzVwZERWM1lVMHZTbFpKUjBWaVlUaEpka1Y1VlV3eldVcFZVQ3RNVjBjNFJIY3ZRMU5KZERsVVRYRkpTQzlDVTFkT1RWVnRibEJaDQpEUXB5VXpKTFJtaG5VbTVLTVZCVFUxUldUWEEzTW1OSWFHZEhXWFZ4Y21vclp6aG9ibkJhWXlzemJrcHVSVk5EZDBwR1RVbGpaV04xDQpXa1pZYkVRTkNraDRUR3RUYlhkek1UZHFVRFJtVUhNMVQxUklTMHBLY2xwdFltOHdOV0pJY1hWeWIycFRVWE5QWkVWallXVXZNWEpUDQpTRFJqUTJoQ1RETXJNUTBLWVhscWRsWm9TWE14V21SWGNYRkxNa3hNVVhWUlZGaEVVM1JQWkZOUGNTdFZTblY2T1dOTk1Ea3hjbkI2DQpaVk53VFZGSVJrSkVVbEZ1VDNoekRRcGhjbU5UWjJSUU9HaEdTV2h3YkdWaFZESmhlakozTVVsMlVrMTRWV1ZFZWxob1ZFUlRVbmh0DQpWbEZvZHpWSFFVVjNiM1prUkRGTk1DOXVaVlVOQ2tOcVVUaEJjRkZ1WWs1RVFrSnVaSGwwV1N0d1JFeFpWMGxXZFZneVlsbEVPV1JqDQplU3RuZURGdVkyMUtPV2xyWkRZck1YRlVaRzB3Wkc5WlJBMEtPRGRFZG10S1QwUktaVWRuTTBKUFYwUmhhV3BqVm1oTldYcG5OVlF3DQpSa1lyVVRKeFJtRkRjbWNyV0ZSTmNtcDJaMkoxVlZwdGNXdFFRemw2RFFwak9VNU1WMVJ4TWpKMEsxSnJMM2hGYnpORVdITkRTREJPDQpSbkp6Ums5bVptTTBaME42TVhRMlMzUlVSeXRHTmxFM2FsZHdkRWxvTjNBM0sxa05Damt5YkZoVmFsZE5WVVJQUm5wdlpGRjBWR1IyDQphbnBMY1VSdlUwcHBOMUpuT1ZSRGVGZHRXRTFpZVdKWlJFRjBWRGgwZDA5cVZGaExTME5qVWcwS1MxaG1LM1JUYlc1NVQxa3llbXBTDQpLMnR3YmxabFdFSmtkelp1Y0VkRFlUWnRZbHAzYVZsUlpHY3ljVWhDUkZGUWJGWTBhR3BtUXpaNVJXY3JEUXBUVFhaNGEwTXhZWFZ1DQpRMHhyU3l0QlJXbzJUV2QzZGtVeU1FbDRWV05LUm1GYWVXVkxSWEZaWVVobVRFcDVUM1EzTTNWc2JEVlBXbGRLZDBzTkNtRTBiR2gzDQpPSFpQWkdoMFZuZEZVREZ5V2tReFMzUlFhMWtyWm1zckwzaDNhR0p1WVhSbFMzWjFNMUJST1V3NU1rdEhRMGxaV1c1SVdHeGFiUTBLDQpjVkJHUkM5YVJITk5NVFpPTkhSMGJqbHRUMXBqYzFocEsyWm1ZM1ZYWmpCbEwzbHJOVEZHWlVaRlVTOVBOemMyWm5CdmFscHFOV3h5DQpiemgwRFFwa1lsSkdWMmMzVTJWRGIyUmhWbWwzV0RkVFZqSTNUMHhQYUZsTVFubENkRzVSYkRWc1FYTnZNRVJCT1ZwSGNrOUljMjFzDQpjalJrUm5KYU9Wa05DbEZWTnpoblprbFVhRXB5UTFwc1ltZE9ORUpZYWtzME0wY3hMMDVSVURsU1QxQldVWGN5T1hneVoxZDFUVVZ0DQpMekJLUmtaR1NuTXhkV2t5ZGcwS2RGcHliMVpvVjFsVlJYRm9jVUZSUzNjd1ZreGFkRTkxTlVGWmJrRkVabGd2YlRaamRreFNiMjlDDQpLeTkxV2tWbmVuUktOVGxrWmxGdlVsSldEUXBOYzBaclkzbzFZaTlxTTFkWlJqSnlRalZJVWpOc2J6RmthM000T0RaR2JsaGhWbWhRDQpSRVZzY1RSYWFITkRMeXN2ZEZoelpuTTNjemhaWkVVTkNtVk9VbU0xUTBGRVVsWlBVemhEV2xoMldrWndSVzFKTVZaTlNsZzJOVWhPDQpZMUpJVHpGYWRrUnJPVFJ6V0hRclEwVlFXRkI0ZDNOSWRuVXZMdzBLUWxsNWRsUmlVVlUxV25OclN6TkRMM0J2Tkd0eFZWZEVSWFZUDQpjWEIwTDJWUmQwMUpiSE5XWVZBMk5VeDBPV3BNVnprdlV6STBhR1Z4WTNCVkRRcEZXVE5YUlN0NVVIcGxVMDUzYjBkbldGbDRXazlSDQpRVTgyYVV0SlZtOW1TMDlEWld4MlFqY3ljekZSYjA5RVRsUk9SSFZ4ZW5oeFVHbGlORTBOQ2tWNFN6bFNTMWt6VWtScGFFNXdPRTFhDQpOalUyY21oRmFVVnFWRlEyY3pOeFRFc3hNVVo2ZDFsbU4wMXFRMnRTZVRnMGFYcDZhM0p2YzJWWWFnMEtkM0pCTmxVMmVGaDNOSGRvDQpObGd5Y2xjNVdFSmlTRTVhTld0WWIyMDJaSFF3V0cxamNuZHpRaXRKYm5kalZsaHBiSFZvUnpKNWRrMUpNMmhKRFFvMFVubFZXbGh1DQpVWEYyWkV0UFprczRkVkpsUTFsb05teE1kREJoU0RkRGNXNUdkVTVvVGtwQmNGTXpZbVp0Um1kUk9VaFJhakUxY0hwQmNFSU5DbnBQDQphak4zUVV4bEsyNVBlVkIyTTJGSVJtSkpVV3RqZEZGNGNTdDRWVEJJYzIxVU9UQXhhRFJpTm1aS1UxUnBSbm95WTNOMlRtRllheXMwDQpWZzBLVmtONGJFNUZibWxJZW5oaWJFOHhiM0pQZEdsVWNscDZaRVFyY1daUGEydHVUWFEwZUVNcldXSkdaMVJ5V21GaFZtdEdWazlSDQpNSEZGYzJKcURRcEJUMHN6VUdKNEx6WkVVSFkxUnpSc2JWRkhOVXAyYzBGRmNrRnRTM05SYlROSVluaElZU3Q1VHpkcldDdHNOMFZODQpka051WW1oT1YwVjRVbU1OQ2xGb2JHTlFXRXhqYjFKQmVVMW5iMFJsYlhvd1l6SlVOVTl5VTFkMlIxQmlhVVF4UmxWb1ZDOU9UV05vDQpSVFJVU0dab2FIb3JWM3B6YkZBcmFBMEtjREJRWVN0UVYxRkxWMGRVUjBoTmRqVmlabGRWWkVsQ09EQXhSMjUzY0RJMlIwdFpTMUZpDQpPWEYxYUhjdmFFUnVPREZMUkRKVGNFUlNPVEI2RFFwcVVFVXZWRnBvYVZwd05ERk5NVEJxU1dkeVozTmFOM3BvWkdsRUx6bDZXVVZqDQpLMmMwT0hnM1VYSTBVRUZZZG5ZMVVEVkxVekpaVEVzdldrSU5DbEpNSzFJNE1EUkRZWGwwU20xaGNubFFVMDlrTUdGME9YSlJNWFJ0DQpjazkyZUc5NmRqZEdhMWRrYUd4MWNHUldiMjVhZVZZMWRVSldWbmt4YmcwS1EySlZVRzk0VnpOT1ozcFhUVVpzVXl0UGNGbDZUM2xxDQpVRnBFV1dock1FNXBhVFJyWW5ka1VFbHdibXRuVVZKdk0wRkVSMjl1U2taVFZuTmhEUXBuYTJkT2VVcG9ibmRFVDJab1NrNXhhaTlzDQpWMkU0WjI5VWJtc3pWWEUyUmpnd01sZDVPV3AyV1hKSFpFRkpVa2RSVVcxb1N6WnNZMlIwU2tvTkNuaHFWRTlyYVZkME5YQjJRMk5UDQpSbHBCWjBwMU5sQjBPR0lyVjNBMVdrSkdjVEpMT0RCNVpqWm1lbEZKTVU5dU0yWlhjR3BLYjJNd1oyMTFSQTBLUVVGVlREUmxaRUZGDQpTamg1VVhOemJscHRObEJRTVdSNVkwNDBlVFJYVUhOSUwyTXZSRm8xTVdZNEszY3JVR1JVYTJkWlJtODNOekJIVURkdERRcGtWVE01DQpSVTlSV2xOaFJpOVhiV1I1TTBoRVdsWmtaV3BrWm1WblVXbE9XRWxCYkZOTGQyRjZMM0pOU1djeFFtUldlVFJFUTFadFZYRXZTVWdODQpDbTV6VG05cmEybElhV1JXTkVSaVJVNXhVMmh2UjNoNFdFUkZTU3ROZUVWdlYwSkNZWEZ3TkN0V09FSXZWMjUzZURSQlRESkhWR1ZaDQpjWHBaVFEwS01GQkxiVEZaZFhSUFRsTlFUbUkwYlVsTldXVnNjMEpUWVd0Q1RrRmthVE15WVZjNU4zSnZRekJYYmpsd1puQlNibWR0DQphRTFoTDJ4a0wwNUJEUXBNU0Rnd2QwNHZhVzFIU1U5eVFrTldWbWhrY2xCWVF6aEdXbFU0TTNjMVpVVnJWMmRwS3k5bVZqVTNNMlJxDQpTVWRvUjJoUEx6SjNkVTFJZW1VTkNrUjRLMU00UXpjME9VSlZjbFZLTTJsNGRUSktRMUpDU25vNFdYVXpRak5FWW5oUFlWaE1iRWhqDQpSSEZYVVdacmFEYzBaME56YW5GVldrTlRaQTBLUkdOWk1WTkdlSGRtYTIxa2FGZGlNVTlDZEd4clYxSldSRmhMTVU5SmVGQm9kbHBuDQpaRFZYTDB3NFFXUk1VRmwxTm1keVF6QkdRM2szU0U5SURRcDBRbTV2SzFSNk5UTldTRE53YzBnNGR6WkxRazVCUlRoUGMzUm9VM05HDQplRGhCUjBKV2IwTlFNRk5CUmxaeE1uTlNjRzV1UW5sblQxcHhSM0VOQ21KcVVXZFRSV2xUVkdSNVVrZElNakZMV2tOa2NqWlZXRkpyDQpkalYzY2sxWFVFaHhiVkZ3SzFsaVJXVmlSRXB5V0dkdk1rVkNiRnBzTW5KcWNnMEtNVmRhTm1KTGMyRm5WaTlrTVdjNGJrWnZNMkoyDQpiRVpDWVc5V1oyWjRObG93ZURadlJFVkhhRE0wVGpJMVVWUk1WM0ZPT0VKeE1IRjNOa0pQRFFvM1FXcDZhMVYyZGxOMVJWSm9iVGgzDQpaVU5oTkhOd1ZGZEdWVmRwUjBNMmEzVlRhbVUwUldJclNGUlpVbXBCYVU5V2VqSlBkVkJMZFVab1QwRU5DaXR2VUdReGEzZHhOSFI1DQpUV1poTVdZM2FHbHBjRE5GTVd4eVpqWk5SVm93Y2xBeFNFaDBPVmR0TjFkWVZXcExhamhMTTNsU01WUXJSR2t3UncwS1pYcENTMEl6DQpVV3cyTjJoak1ITnJaMFpzVUdSSVpHVnNObTVKZVdkWUx6VlJVbHBqTTA5MmNEaHpVemd6UTJsS2FsTm5aRkJoTXpKWk5rUkdEUXB3DQpSV3M1V2pkRVRtMU9Oa0ZHVm1oWFEwMWpVVVpZYTNaTVYxcFZVM0JCY0hKMlJscDFWWEZyZEdkRE1sRjZNRTFKU3k5NE9GWTJNR0o2DQpjVFFOQ2k4ellqWklVV3RLUkRBd2NUbDFaR2gyZFhGc05WUXlhalVyTDJsVWJFOXhaSEJFVnl0T1FVbGlTelZRWTA5WVIxWkRkek5SDQpaVFJqZDNaWk5RMEtjbmQ0TjA4cllYWjNaMk42Unk4MWFXUXJhVkpUTDJ4dWVUbG9TRnAwWWxSNFIwSkxkR3RwT1VRclQzWnBiMUV3DQpNVTlYUWpWSlRtaDJUV0pNRFFvM2RYVnFjVk5SWVhsVldIRnZjMlZJTkRNeFEyaFhRMjAxWTBwcFZrVnNWMGh4Y0ZCVVduQnNRWFpwDQpUa014VFVVM2Nsa3hjQzlGTkV0T05GTU5DbFZEUld4UGVFeFBhbU4xV1VoRFNVYzBiR3RJVVVKTWFIZEpibTFrV0RoV2JrdGlkMUZLDQpVSHAwUzNsbFlUTlBhbXRyY2tVd2JYVmlabXR0TXcwS1J6bE9UVTQyUlVoWmRqTjBXVFpSUkd4UVdqWXlVM2RGSzFZMlNYY3dVSFo0DQpWRkJRZHl0RFIzSjVTM2QzTWtwUk1VaDROeXRMVWt0dGIzTjNEUXBLWTAxSFpqSkVVR2RKV2xSR1kycEVURVIzVEhCc1FVcHFOMEk0DQpTVTVvUmpablRWb3hhR1V2WkhsSE5uVk9lVWx5ZFdoMVdYZEpWQzlDY1dvTkNub3liRUpSWld4VmIyZFRkU3ROU1RsSFNtTlpjbmw1DQpjRUl5YjFaYVMxSnBPVzVhYWpkWmRWSTRTVzlWZEhaNVYyaDZZVFpZWWpaQ1FWZG5idzBLUjJGaWEyeFdTVFJJVm1adFFWa3dWME5rDQpVRFZoVEdoUFFYUmlVVFJCWW1aTVkzTk1jbGMzWVhBeVpIQXJaVlJZV0dzclVVWTVNMGx5WmpOcURRcGpSMnBhUTJ4dmJrMVFWVmR3DQpZVWRDYVZSTWRUWjNiakpRVjA1b2RUSTVja3BUVURKNVZXWnJOV2h3SzI1UVpFUmxka3czZVM5Uk1WZE5kRzROQ21oQlJtWlpTMHBZDQpiak5IWVhKNWNIRjZSRVZUZUdwMVYxSTNTVnBJYlU5bE1FZHRhV2x6T0dwTVJISkpVREJ5YWpaemNGWXlVbVozWlZwVlpRMEtNVXA2DQpRbWhrYlVwMFNuZHhhRVZaTjJwMWEwWTRNSGN2UVU5b1Mza3ZVR3N6WkVkR2EydGllSFpYWmpCYU55dHJZekF6VXpVNFp6VmlUMFpXDQpEUW80UjFObGNrTXljMGMwT1VKbFVXWmlNbkpLUmxGbVFVVldOa3BxY0ZGTVRsUXJkbkpZV21kTGRsWjRha3M1WVVKdFQzZzRSSGQ2DQpSMHhoYzFjTkNqQjZSbTg1VlUxcFpIcGhVV05rU0ZsSlF6ZFlWbmRPYWpSelpVd3pSR1oxTVZaTmVIUk1jV3MxVTJkcU4yNTBTRzAxDQpjMDlaYWtseFoyVlZNZzBLV1ZkRFFtWlZVM0JEUVhKcE5tRkJXRGh5Y1hacVdGbGtaVWRYZDNWbFRVSlBlRFJJYjJGUVUxWjFhMDhyDQpWR3B2UlZsQk5FczFaelV2V1Zsd0RRcDNaRkk1VVVsMlpXZzFhblZwV1VWdE5qSjRhRmhaWjBSSlMwVnZVVFp5YmtSU01VVnZkakVyDQpRekpRY2xnd2EwSldTSGRyWTNCelJEUk1SRmtOQ21kdVpIRnZjMkZhYjJoelQwbzFWbVJMVVdWT0syOUdiamt3WkVkMFFWWm5VV3BPDQphVmhzVVhKUmNHcEZNVlpKYW5RMVUyaEpRVmQ2YzNsTE1BMEtOM0puWjJsbGNFNHhLMkZWYkcxVFFWVmFZVGxtZUdScldIVXZkSEZTDQpaV1YyY1VaR1UzSlNkMWc0WmprMmRVcDZUR1E0Y1doWWIzcGxPSEphRFFwMWVtSktZbkJVWjNsV2REQTRWRTV6T1N0b1psUmxkREkxDQplRXd2U2l0eWMyMVlTMjlvYVRsbGNWcE9VRWhCTVRKYU9FMXhNa2RJUmtaaVlVZ05Da1JDTUVKUVNsSnBRM2xKUW5CelpYQjJhRXBhDQpjakZGUlZsS1oyOXRTWGh1VlhCT01rMTVOWEZ0WWs1VmJtTnFNRk5TTDBWSVYzUkxhRmxLVUEwS1IwUmlUbmx6TjFGRU1ucEthRmwxDQpkRWN6TDA1WmNGVmtiRGxyZUVjdll5ODJUbkZQTjNST1RHNTJUV001YjA5UFpEUnFkMGg1ZFhkRFNIbFVEUW94TVhCc2FFcEtUbmx4DQpaamxOYW1kQlluRlFhMUZKYzI5eVdHVjZXRmhWUm14a1UzWjVUWGsxVlhjM1NIUmhPVVJqYVhBNVlrWjVSRXBDVXpjTkNrSXZTbmhzDQpkVmhGU21SWmJFSlhhbkZYZVV0NmRIVTVSVE12Y0d0ME1rNUxTWFJvV2tkeFZXRTNNR2tyTVhoVFYwNU9SMDlQWlV4dFdGTjZWUTBLDQplQ3RQTjFGTU1XaE1OelY0WTBkV2VuRkpTVlIzWkdsbmVVVXJlVFpzV0c4NWNUWkRiaXRJZFZFNE5HMTZWV1JpUkVNMFFsYzFUVXMxDQpTVVkxRFFweFJEWjBVR1puZW1JeFdtb3dLME0xWlVodk1sbFhMMjVLUjNoTldsSndTR3M1U0haMmFXbHpja3AzTkZwQlFWbExibXhrDQpRVE5TWjJWNFlVSU5Da2hxTVRaSk9FNXFNbVptU0dweVlubDJhV2RrYldack1UTkZZV2h4ZUZrM2MwWkVaMHBpTWxaSWRsSjFNbWx3DQpWbTlJZUUxWFFrTktkVWcxU1EwS2NUUjVkazA1VUdaUFNrczJXR016V1ZScVprTnhRbWR4YUZSV2EwOVhVM3B5TkRNeFRVRmhjek5uDQpZMjVJWkVRNFVFWnBWVkEyVm5sQ1RrSlREUXBZVEZsQlNqVXhjMlZxVG1zNVNsb3pSR0pLUVZSbVRrNHpiVVp2Y0RGV1ZHbEZWamxEDQpLMU5QWjNoclkyVXlOMVpKTVdVcmJXWlNSR04zYlVJTkNuVTBOWEJKWTB3ek1FUjBZMVZIYVdaT2FTOUpkR3h4UVVoRGRGcE5WSHAxDQpXSEJaU0hONU5EWmlSR2xrTUUxWVdFeE5iMFJyTkRNeFRFVkRUZzBLTW5sWWRrWjZkakpOUlV4bU1sUnlUVWN2WmxZMGNVMWlhVE5yDQpZM29yZUd3MmJsUXJWRlZYVkZGRVJtMWlNa3d6VFdOb1owdGliVkZoTVhGVURRcFRjblJ5TnpKUU5DdFRkVmR2V1dKamVrVjViblEwDQpVeTlhYVRsTVdHdDRSVW8wYmxObVNraFhSMWh5TmxKV1pGVndObmx3YjBsSVIyeDZSMmNOQ2xwRWEwdzFRMnBWWkdOSGJUSkRZVWszDQpTbFpzYTBFeFJHRTFabGh6UmpKdFV6WnBhV0p4TlhaT0wzb3ZURGxPTWpOdVQxSlVlbGxNZW0xdWFRMEthVmxYYnk5TlNVMU9iSFZaDQpPV1pPTVdOalV5dGlXa000UWl0T2RrRjRWM1JYY1c1RGFHZzVkWFV3UjJacGFsbE5ZM2xNUlhOUWEyaFpPRzAxRFFweFltOW5ka05ODQpaSEUzU0RkUE9UQnJWWEZKYVV0d1JrUnJWRmxvU1dKTVNrbzJabUp6TUZwdVNqbDZaMnBMZVdsQlVVRmlUVkZSZGtWWGVtWU5DbTQxDQpTSEZUVW5SaVpWaG1NVEZtTnl0blVHd3pPV2hGZFdjMFZtUlRaV1pWZURSSVVXWTBVVFE0WkhVNGJ5dGplVFpSTW1SVFVURkVUVzFHDQpaUTBLYm1OTVZpdEVNekZzUTNWUVUyY3paWE5STmtWVmVtNW5USFF5TjFkV1pXNUxXbVExUldwUVpFdG9aWFJzV0VnM2RWSmtUazlDDQpkV1JyZFRkUkRRcFpiMjB6UW5CaGRETXlhVXBCUkZWUU5HRTBUbk5HU201bEx6TnBOR0VyV0VKeVIzb3dOM0ZFV25oSVdsSnRaVXN3DQpabFp0SzIxR1dHWm5TWEFOQ2psTFRITkZVRXg0T1d0NVdIWlNWemxVTVZkM1RscEdXWEpSVEVJM1dFMTBjRWQ1YXpORlNFMVVVMFZJDQpkMjlsVGpseVRWcFdWR0pRWVdGRlpRMEtVVlYzZG1OdVdUVnFURzF1ZDB0ME1FOTVhV3B4ZERKRVRVNHZSM1ZDYldwYVFVeGlZVW96DQpZalYxT0dwNGRFNWlPVUZoWjFodlUzVlVLM0lyRFFwbVYwbFVhakJrV0doTlZITnFkR1ZFT0M5VWMwRkRhbkpXU0hWamMwaElXRUYzDQpXbU5zY1dSTVMxSlBRaXRrTWpOd2NYRjFiVXBGYldwMFRVVU5DbFZIUzIxc1VGZElaSFpDV2tvNWEwRjFSREUzYkRReFpETjJaemRGDQpkMU00UmpSWU5scE5iR1JxVTBwUlZEVlhUSGhEYjNrMGMyWkpWRlJITWcwS09YQmpkelZMVlUxaE1ETnZTVGRZWWtsbmNXcGFXblpqDQpSVEZZTDBNd00yRnJRVEF2VFZkWGNteE1UV28wVHpKWk1HZDBhVUZXZVZFdmRIWXpEUXBrU0ZOT1VWY3dRWFJKZVcxWFpuQjNiWEJDDQpjbGh6VjBJM09HNU5VSFJyVmtkNE16ZHJPWHBuVFU5UmVtdGFjRUpzZWtzNVVVWkJaMDAwVFUwTkNtWlplVmxpTlVwNUszcDJkMDlDDQpiMmR3ZDFCQ2JHOHJVRlpWTm5CUVVsSm5OMFJCUkhCd2JrdHlNR1Y2ZURkM1RVWkVhamhRUWxOTGVXVlNZZzBLWmxSeFRreGFTRmxSDQpORW92V0VSS2VsRmxjVTV5T0dKUE9XSXpOMmszYjNCWU1FMXBVMk5aYVROSmQxWlZiV1pEZUdoNVpVY3JVV1o1UWxNdkRRcFpiSEpNDQpaM2R3ZWxBNE5FVm9WRWhXVW5sMmMwTktjbWM1VVRGSFYzRnBNbVJYV21wMk1GQlJWRmhvZVM5WVdHbEtaazF4YjFkTWQweHZUR1VODQpDbE53U3pCMU1UQnpVMWh5YmxKbFJtaHZOVzF5V25sTVZFbHhSWFZNTm5ZM2JXbDBjbG8zVFc1dVkwOTZOSEZRWTJOck0wTkRkMVowDQpVakJHYlEwS1ZUYzNSR2xGYTA1RFVXcHZWa0puUTJ4YWExbFdWbk5hYmtzd1NrOW5Za3BLVUhCS1NXdFZWbE5CWjJSS2JUQkVZVnA2DQplR05ZUWxKdlNsaDBEUW95UkdKcE4ybE1aazl1YmxrMGFEbDFPR2d5UjFkb1duTmhSaTgyWjBkaWFHVTJaVFZSU1RkQ2RFUkRka1V3DQpSbkZHYjJVMVFWQXdiR28wYW1FTkNra3laREZIUlVGblpqaFdTRU52TVdKeU1VRnhlRlJtWlVaSGNrRXZTblpRWkZWMVpsZG9TR3BSDQpNa3QyUldNM2NFTjFUbFpXUTNsc2NYaERSUTBLVUd4a2EwWldXVVpxVVhGclYzTm9TbUZaUWl0b2VtOXpWalpLZURGTVVtOHpNSG8zDQpka3hqV25VNWIyVk9PSEZYYWtzNGNWUlJaMjB5UzBsT0RRcERTa28wT0hKNVRFMVBlbUo2U0VSVWNFbFBRbTlJUjA0dmNYWmFTR3hFDQpVRk5qWkROcFkyWXpUalZwTUd3NFlsQlBiR05aVDJ4cldFTnhVbXNOQ2pBck0yeHdkR3M1VFdWTWJ6ZHJXazQxTlhjNU1rMXhUMHRTDQplbkE0Vm5RNWVFSjJXbmxwYVhneWJqRm9NRTR3UzBoUU5tbFBRMGhxUmtGV1R3MEtPSEJ5ZUZOUFl6Sk5lWFZJZVhrclltRTVkMkpWDQpkMWx3Y0hsdE9HeHBObTVCYUdaSU4xWldVelkyWVhWMlZVbExaa1V2V1hNd2JHRnRMMjQwRFFwVlVIcDBXak5LVWtaaFN6Z3dORGxGDQpiakI2UkRRMVVHZEdNRWN3Y2tVeFpHdHpjVGh4YzNaa1RYbENkR2Q0U1ZGalJqZGtTVFY0ZEdkcFpua05DalpIWXpKd2JXUnlPWEEwDQpORzFvVlVSeGEwUnVaakUzUmxoUGNXSnpSM0ZWYmt4TmNHWklhM1ZGYW1KdFVuUklaR1V5VDNZd2RURllVWEk0YXcwS2NuTXhRWGhwDQpaVWhFY1RaNWVrZDBhREpQYTBWRVFVbEVhMFZoU1hOTFRrOXRUbXhwWmtaUVJDdDZPREJFTkVscGFrcEtka0pNYm1oRE5URndEUXB1DQpRbnByTUVKSGMzVXZRa0VyWTA5SVNFcFlUa1ZVVEZacGRFMHlNMkpTZUV0UVp6TjRVSHBRZGpVdlQxSm9WbVEwV25SS2JVZFdjR2RaDQpXWEVOQ21Sek1FOW1UbnAwUVhCNU1WWktaV0pDYjNvMFNGTk9ZVU00TVZCTmIwMWFUV0psZFV4SmVXRXJUR3RQWjJwTlVIaEtUa0pZDQpRbnBPTDBVck9BMEtTVmc0VjIxSWFHdHpVVXhrYmxCRWJscHNjR3BoTTB4YVRXVnJkemxIVkZOSmJYbE9Mek5uWldsTmQyVktibW9yDQphVU5ZWjA1VWNXYzVTVTlERFFwRVdteElRMDlWUWtSUVlrWjZTV2htTUdGWldscE9ZWE5uZVhBNFRVaG5TbkpYUWt0VWFpdFZhMjFwDQpOSFk0Y0haV2NHdERTakpMUW5CSlVXUU5DbWhYVURGSFpqUktOMlJ0VjAxWVJIaHZTME5IV2s1dmR6UkZUMjAzTHpOdlZsQk9hREpIDQphbGhTUlhoSlQwTnVTV2d3YzJRd2NGa3hZbHAzY1EwS05rNXhZVVZSVms1TGRFcFpkRzkzVDA1dGFEUm5OMUl4VUVscGVrUnVkMUJ2DQpPVm96WkZsd1JXbGFSRVZWYVROaFJIRTBNMmxXUjBFMGRUazVEUXBGVFdSVVRIcDZXbVZOYm5oRmFrUnJSakF3V2paUGRrVmlVR2xRDQpWbGRGWkVwR2NtZG1UamROTkVkWFJVaDVZV1pyVmxsSGRDOHpTV0psTTNZTkNrNUdia2M1VFcxTWFHMXVWRGRzV0dWemVGWXdXR2RuDQpiRVV2ZUdWVU9WZFlNRXhoTUZoTVluTXpjbkJyVlU5TmVWbEljMloxU1U1UWVtMXRjQTBLVHpZMFZFdHJZVWw1WWt4SWMzTlBXSHBFDQpOa0ZpYlhCbFJEQm9iRFF3Tm1GdVRVaDZNMHRyTDFWS09FWlBhR2d4WjFCRFUxZGlibTl5ZEZaVURRcFVaREF5TjNadFNuQjVhM1ZuDQpPVlZzYVVwMFVFMUVlbmc1VVN0VFQzTlRhVE5NVDA4NWJFZHVLMXA1U2pWaVkxSk5Ra1JRVWpScEwyazFTRWNOQ2tkc1RIQlJTMk13DQpZbXMwWlVoV2VpczRaR05WUzFwbllYRmtSbWhaTjFkcmJrMU9aMHBSY2psdVowcGFiSEV3UkU5NGJUZGtaSHA1UzB4VVVBMEtkMDFaDQpibEEzT1RKeldYVmxNemRKUVZaR1lXTlhNMjlRWTJ3NVJtNUJOMmd3WW14bU1FUjBNMmhuV0dndmNVczRUM2xOZGpOMlJVOVZkRTQzDQpEUXA2ZW1KVVNFVTVNMVJxYVRkMVYxUldSR3BMZEcxSWIxcGpXRTEzTjNsQ2JYWjROa1JKYkRSUmVHdHVjUzlLYURkNllWTnZSRlJ2DQpNemhaZEhBTkNtUnZWRXRCVVhkUGFUSkVNMGMwYWxCTFkxRlpkbXBaU1dkSlFraExkVmxGVFROTVdubDRZVk5DVFN0M1ZUQTRlRWxpDQpNRVZGVW5Gb2FsVk1aZzBLZVV4NWVFNW1NWGh3YVRCdlNsSm9OVzlQWW0xTUwxUnVkRXBrYWk5WmNWQlBUSGxYZUhSTmJURjRSRzFQDQpRMEpLVnpoakwwVm5kbEZTZVVkNERRcFVPVTlVVjJORVp6QXlMM0pSWXpGYVVsaEpVbXByU0hRNFMzSkdiMFZFVlRsdVp6QnNiekY2DQpiamxaWTNVMGJrczFkMVIyUmxwQlpsQjNSRmdOQ2xGc2JrcFljbXRKZDJoa1dIZ3lTaTlNTmpCMk5VdExhVkFyWkVWaFdHTmhlR05hDQpkWEl6WkZkNmMxZFBOR3AzTTFCMFkxQktTRVJJZWtSdFZRMEtUWFkzYW1KbE5YSnhVWEJMVVdaSlMwMVNNRkpIUlhKRU5uUlVWRk5PDQpjVTFzY2poSGVua3liVVJMTDNNclRFSjJaMjVrZFdWRWIydHBZV2hxRFFwWE5WTkdMM013YW5aT1pqQkVia05RV1ZodFNWTnVWbk5qDQpla3cwUnpSVGRFeG5hRXBNYjB3d2MwNWFiMmRYTTJwbVVqTm5TQzlJTm1WSFZGQU5Dbmd3ZFVWUFVtdEtkVFJOVFhrMlRWaENaVk5LDQphV2RJWlVOSVZGZzBTMGRHYmpsdlozbDBValJTY25jMVpFRndiMWxhTlZGSWMzUnVaVnBDVXcwS09FczJlVXR6Um5Wc09ERldUSFF5DQpNMEoyZVdjMFJFYzJXVEpxV0hFNVZUQldkMVU1UlcwMGNESlBjV1pyZHpFeGNFbFVORkpsY25ad1NFNHpEUW80YzJaWU1EazFkRk50DQpiRzFvUW1wWVMzVnZPRlY1SzBaMk9XbHNZVlZzTVN0dlRFNVJlbGg2U1Zoa2NYbDNOVVZKUzBGWmF6TmxRMlJoU0dvTkNuWkZka3h0DQpWa0ZqVUVKb2QwMHZUSE5oY21KNk5rczFZVlJHVGtoNVNHMDJRbVpvVlhkeFpYazNNMmhMVW5aNk4yRm9aRWRQVDNSYWVubFhhZzBLDQpSR05ZYnpCRVluQmtaV2QwYVhSdGQwVTFjWFY1T1hKaFNUZEthVFl5V0c1SFJTOVVNMFl2V1U1dlMwYzJXaTlKTXpWa1RTdHJLMnBEDQpaR1o0RFFwd1Uyc3hSVEIzYmxWemVqbGhTakkxUjBaRmF6Y3piMFpuU1VKWVlWbzBPVnBxTW1sQ1pqWnJjelpSUW5NMVNsaEdkMDh3DQphWEF4ZEdrM1IyRU5Da2hCVlhwMk0yNDFObU5JVFRGM2NrSmpNbXBuTmxreGIxUkVaRmxVVlUxd01EZ3lWMjlvZVcxbk1VOHZjelY2DQphbkl3ZUZWMFNISjJOa3RKUkEwS2VtOWhSVU5rWXpkcWVVbFNMekJZVEhkbVMzUnRhR281YzBNNVVGSjZTM05TZVhFNVkwazVMMnRIDQpOaTluYWtKaFZUZENkbkJEUm5aaE9UQk5EUXBtVW1wcWVXNVNjRzlrUW5GTmJYaFFZVkJFU210RWN6ZFJjMUF6TlZkMFkxRlNiVGRJDQpWaXR4Vm1kS01WVlBaMk4yUVVKeWJFdFNkVlkwU0hvTkNtVllUMEo0Y0VkemIzWkphMmRVWkU1MFdHZFhZVGgzYVZwSll6UkdhVWR2DQpVMDkxUVRnek9YY3dWazEwTDFvMFprcHdlRFYzWTJKUmNFNVpNZzBLWkRWUk5uTnZVekJ4T1RoM2QyaG9WM2xPWjFGRGJHWkJhV1pCDQplamxsVDB0clRFVlhUbWhqV0VKbmRIWTJNek5yYkhWcFYwbDNiVUptY0VWekRRb3pWM0IzWjB0amRYSXdXVFJCU1RGNU5FZzVRM0JYDQpTSHBvTlM5dlNqWkZUa0pHUnpCaWEwUmpWVVJRTW1oME1rVlhSalI0T0RGV1FtcHpjakVOQ2s5RGF6UnlNSEZ1YkhSa1RYTnNSbTF6DQpWekZWVmpKSlVHa3hXR2R0YnpsSGEwb3dkRGMyTlRCT1YyNW5jakJWU2xSM1NtcDRUbkZWTDFKQ1JBMEtVVTVZVkRGamNFWlRTSE0wDQpWamh2V25adVdHWldkVTh5VVU1cVVIUkpUM2hsWkdkTmVUVjJTRGh6ZVcxM1ltWkdjRTF5YjJOVFNUTjNUbEZERFFwbk1WbzVaMHBNDQpibkJ4T1RCdE5TOUNiM2xUYkRneUwxTnFTbVpUZEc5dE0xTXJkMU5FWVhsSlMwaDZRWFZrWVRkWmRFdFlkRGxQSzNwWVdXSU5Da2h5DQphMk4wYTNRM1NrNVFkVXhsUldsdVExTk5ZbFV2V1hOclJtOWpiRFJ1UW1FdldITnFVMGR1Y2s0MFNVeGtTRlpvWWxCU1VHcFVSa2hPDQphdzBLUTFaVlRVVnJUblJ4Tm1WelZXOHZVa0owZUc1VlJUQkVlVEpQUm14UWFUVlViVVJ2U2tWQmMzSjVjek5aVUd4QmRVbFJMekJODQpaRU13UW5KMkRRbzVSWEZxVEZnNGNVZDBibEJ5ZGk5a2FuY3lWR1ppYkhOalprTnpRa2h5Y1RGRVNYbGlhbE5oVGtWWlFXdGhlRkpJDQpZVGxuYUVOcmExWlBNamNOQ21adlpYVkNMMVU1Um1wU01sWTBURWx3V1hKbFJFb3ZZbmd2Y0VzeVNtWTVabVIyWjFaSVpVUjBORnB6DQpkSG9yV0RNd1ZXUk1iSE5TTW1oaVZnMEtOMlF5YTNCd1dVNUNWREZsWTFCalYxSkhPRmd2UlVac1RVVlVSR1JHUjNONlJUQXpTbUYyDQpWa3Q0ZDJGVVEwb3JOVkpWYjJOM2R5ODBaMjl3RFFwdFJVbFNRakprYVU4eFYxQkhOVWxxTW5nck5XWXdTRkJxYWpGSk1sWnhlRTl4DQpTalZUSzBaclZ5dDFMMUJTS3pod2RFbE9MMkpvTW01dVIxZ05DbVowU2trNFZuSm9aMFoxUkc1Q2FGUTJjamhFU1hKQmFHeDBUREF2DQphVFZ0Vmt4RFlteHlOMlZ4V0dwdlV6ZHJkMFZuU1ZJMFNHNXpTRUl6ZFEwS2RYTkdNbkE1Vm1GSFpXOUllVlZPYURkSE1EVmtVaTlyDQpVWGRCYUVsYVpWQnFXRVV5Um10MVJrVkxiekV6Y25wMWNVeEJlR3RsTXpCaGRXOU1EUXBYV2pKNlNuUnRlbHA2ZEhsbWMwUmxPRUZGDQpjbFJsY0U1TVpVeE5kWFZVYW5SQ1ZsZHJTMEZWWTAxcGVtWnhORVJFVlZGUFV6VlpZMUJYWmtVTkNsSklSM2R0YURsSmJHaEdWaTlLDQpkbWh5Y2tocmMyazFLMUZ1YmpoNGMzVmpTVnBRWjNGQ1J5c3dZMlpDSzNOS1FXOUNWVzU2U1dOSE9GRlBhUTBLU0ZCdlFrMTRLM0U0DQpVa1pTV0hCT1MyUnJRVlI1VW5WWE0za3piR0Z2YlhrNVkyd3pkakpTV0ZKQlJtTmpiVkZNTkVJelZYTllURGQ1YTFSSkRRcHFURFpQDQplVEZ4VDI5RWFrVkZjRUZWVm1GNFJUUlRkMlJQVEhFemNFRnZiWEJwU1c5RmNqUk1hRGRaT1Rkb1FYRTFVMUkwWWt4TVJXdFVPRmNODQpDbFZ0TDFKWWNGTnliSFZvVFc5aVJHZFlhMFpVVFhONk5VdDVaVkZJUTBWRFpVMXBhMWxITVRsRVFYQTFTMVZCTDAxdk5qTm9ZblE0DQpVMjFIZVEwS1ZDOVVMMk15VTIxbksyMU5iWGt6VTJGaFJtSnVaR2xLV1dKdllWWkplRFJVZFhvMWEwRTBNSFIwTm5seFZrTklibTVCDQphVlpTVWtVcmVqSm1EUXByYkVOaVZXZDNiR1U1VFRCeU5FZENha2xEYTBaS1IwZDRhRzFLTW1SSVNHSldLMUp4ZW1SVFVFOXdSR1k0DQpaMFF3V2tKd1lUZFVSSFZ3WWtFTkNrTktPRzVXU2t4UVlYTnlSMmdyWVdWR1JrcEhkblJLVDFkdU1TOVNRbkJYWlhOcUsyVTFVRmxLDQpRbGhTV2xGVk5qUm1URk5PWW1reU0wUXdTUTBLWmpFdlkzVmhXWEJYWTJoNFl6RXlNMHQzVlZjeVZVTklkREprT1VvMldIVkVTMXBtDQpLM1pTWWtGNlVuZExha051ZVVkb2JIWjRkakJDT0RZckRRcGxRV1ZEYkhoT2VGUk9NV0puYUVndlNGVjBPRkV5ZFVGbGVVNXJiVkZEDQpPWHByYVRGcVpXMHdReXN6WTBKRVIwdG1Ra2hhVEhCVk1XZFdkV0VOQ2xJdllsVkNSUzkxTmpWWlRuaFJVWEIzVDJkWE5sVkdUVTlRDQpTWGhRYWtJclJ6VkJSbTlsTDBaT09WaHZaR2xRY0dkNFpFeFRURFZ1YTFsdldRMEtVbXhoZDI1SWRXOTZVakJFTVdKVFExVlRRVnBpDQpRblpGVnpOV09XcHlkREJxTUhkeGVqWlhWRnByWjBaTGMwaFJRbXRQT1RSRlRIWkVMMU5NRFFwalltMXNkMXBCV1RGMVlXUklaVTlQDQpTSHB2WldzMWR6TXdRblJzYVRKYWQyZGpVelZGUVhCV1UwSmlORmgzZVRKSU5FcGxObWM1ZFhJeFlqWU5Da0pSTDIxa2EweG1SM2RqDQpUV2gxWjFaeUsyUkJNRlUzV0RSRVozRkxVVUU1VGtkcGNuSlBZbUY0UTJoTmNrMHJjRFJSYlV4c05rVm9SV0ZDU2cwS1p6QnNUV2RXDQpTR1oxYUdvM1VIcE5ZMWh6TUVwWmVsaGpVeTl1YUdVdmNYaHhNVEZyVDBoYVIzQlJZbE5LTXprelFrVlNTM05WWkdKcGFYb3ZEUXB6DQpSRW95VVZobVJsWXpPVE5WY0hvMGNWbDVPVXhHZFZCTlJXWmhNRWhYVmxkbFdqSTBOM1JZVm5GRk9GTmtVeTlxVEcxUGNXaHNSazB6DQpTazBOQ2xsYVVFVTNiRU5HZW5sUVFVd3dWWGwzU3pOcU5rNXVkekZVU1dwVk1UVnlUekEyVlhabkswdDBSWGRQWmxCUFkzbEJPWGRJDQpPV2syYmt4VWVRMEtlWFEySzJrd2NteFZNRXhEY1RNd1RXUlNWbVEySzNSVVNXMVhVbE5DWjJvM1JIQmxaMWhJWldWMmExQXdUbEIzDQplR0p2UWxKbldYZ3pjRE52RFFwRVlVczRhMkZhYVhNd0sxUlFZVU5hZWxVeVduRTRSVWRIUkVkckszUXZOVXBKYVhCSkszaHNXWEJzDQpWVFZPV2k5WmFFeHJRVGxFVVZCblRXSU5DblExY2xJMU4waFVVVWR3VWxOWE1VeFBRMXByZFVOSFlYazRlVXBKWkhwNE5YcHVlREl6DQpLMGx5WW5CUlZsQjBiR0YzUWxGWGJIQkJjV1JGUlEwS2JsTXlTRTQzYmsxNFFqaHVOVEIzTVZwdGFqUm9TVEJJVW0xcUswTlFlRFpQDQpVVVozUzJkd1pUbGFVbUZ0V0ZaVlVGVnNOa3g2WjJKcFpERllEUXBKVVdKNlIzRkpURTFNWTBJNVpraHFUR2ROWjNWa0x6bE9hRUY2DQpaR1JVYWpKbWRVcEVkamRwYWs1blRtSmFiamtyZDJkalRESXlWMjR2V0RBTkNrbHRiMEZGUmpOa09WRkVPREYwYVhwU1UwNUlhVk5uDQpka3c1UW1aa01XTllOak13Wml0NFdGcDNWMHhHV1ZSQ00zSTVVR1Y0WkRKS1NYRjVOZzBLTmpCb01UTk1ielozUkZJd1pUTkdORXhSDQpWRXB1ZHpSdlNFY3lkQ3N3WVhaUFZ6WmlPRzV1UXpaUVYxcHhiRnA2WTB4NFZHNWFUemxXU21GMURRcHBjVzlPWWpkTFJXdEdNbkpSDQpXRXhTZFdST2NDODBOWE5OVUdFd1dtNTBXVXR5VTI0eGJtdENOVUowU2xwdlVsZG9ZbkJpUjNvelozTmhNR01OQ2sxelJreEVWRFYxDQpNMU5HWW05clZIbzRUa1ZPUjNSelQxZGtOVU1yYlVScU5Xc3JiMjVQYWpaT1F6UkdkbUY1YlZkNWJWWTNiR05JTUhSNlZBMEtjekJ6DQpNWFUxYTNGR1ltVTNabEZJZHpkaFVWVXZUVzVPUldFeGMxWm9XbXBtYVRCQ1N6SXZWWFZ2VkhCemJsbzJaMlZ5ZWs5UFNXMU5lV1ZYDQpEUW8yYVVWMFdrVTVOV3BLZGxaUFJFRnJabGhCYmpkblJHUnFVWEU0YlRScFNFNU1UbEprU1U1U1dXcFlXWEZRYTNwdFkwTkRPU3RSDQpUV1Z6YTBJTkNsZG9VWGgxV0RSMVYwNUlRVXg2YkhoeGN6aFlWMjFQTkVweGJuZG1LMlpoUjBWWFYxUnVSMlpMTUhobFExTm1SRTlhDQpTa3RYUVVWUU5FaHJTUTBLZEdoeFJYUmlPRE53U0ZGckwycEZlV05pYVdwMlFtMDBkVzVzZDFacVIyTkNiRlZWU0hoSVNVVk1hbmRNDQpXVTE0WXl0blNYSjZhak5ZVGxKWkRRcEdlVXBKYUhoSmVsSXdXR1ZPYzJabU9FOTRMMVZvYnk5WFZ6QnRVMnhuUzBOTmFreEVlblp4DQpWbmRYUWs0elJqbElTWEE1VERaUVQyUjNiV1VOQ2pWU1JVeG5NMnd3ZW5wT01HTm9lak5oZWtwU01ITnJRWEZtVms0MmVFcGFiR2xoDQpVRE5hVUdKb1NVNUNRa0UzZHpjMFp6SlhkSEJEWnpocVRnMEtRVWxFY1dOU1NsTnlWVm92VVhFNWRIcG1aMnR2TnpGUlUyTkpiUzlvDQpRa2RLYW1NM2IxQllOV0pqWkVaME4yRlZZMmhYT1U1VFozZGhRWGRYRFFwaFJFOVJPRTVPUTNBMlNsWlJhVFJVVldVNGVYTm5iM1EyDQpURE5tVVV4TFQyWjJSa3BqZW1od2JGTk1NblE0YjNwa1RFeDJhelpvTVROelJrME5Da2xaZERocGVWSXpTSGhOYW5OYU1URnRWa3d4DQpPVmRJZUZGTE4zRXlaaTgxZUZkQ2IwOW1RMlU0U3pCTVNrRXlkbUo0VWtaamJtcHpTRVZoUVEwS1VXcDBTRW8zUjBoTlVFWjVRMGhGDQpXbEoyUWsxUlVrODVaV0l4SzFkTU5YRlpOMGxuWWpkQloxWXpRbVUyTURrMWVIZ3ZOR3BvWlRscFJEaFZEUXBuVUc0emFrSmhUVTVYDQpibXhDWTBGd2NqUlRaelJzYVhSRk4wdGxiVUozTkdaSWJIZHdWazloWlVvdk1rZDVlbmgzY0NzNVptUm5NSEozZEZFTkNtRnhaV1JyDQphRTFoV0dkcFYxSXhSbUVyYUdkTlVrOWtNME5MU0RORFppdDBVVXBaUVZsWFV6ZFRVRzlaWkRBM1pYaHpXVGRDTVVGVU5EbG9TQTBLDQpORWx2VDJFME9WZEJXVFZFUldoUFpVdEROVFp1VlhWUlZURmFPRUphVkcxUGJqY3lkbXRQVldnM1VHMXNkSGRqVDFZelNEbERkR2QyDQpMM053RFFwM1ltdzBNM2hUWTBkb1EyRTNWRVpLSzJOVUsxUTNXbmMzVVU5MVUwdDJXa3RrT1RsNVFtVlZhMWMxUjBWRmVuSkxSR2hFDQpZVkI2Um5jelNDOE5Da0UzTWpVMVZteFBUblZ1UVZGQ1ZUa3ZVM2M1ZVM5c2VFbFRUa05VZFhaNFNuRmpRVE5CTTBkeFpXOVpTa2hCDQpTbGRKV1haSlJVWjRaekV5VEEwS1RXTkRUekEyWW5kcmVXcHFMek5vVkVoQ2JVSlZVRE5SVDNkak0zSlhUbmx0Vm14VmRVODVUek5xDQpSV1poY1ZWTE9IQnpjMFZVWVRsclVqZFFEUXBDVjFJeFYwbFNRVU13U3pGQldtc3lTWFZYZFdvd2RuazFPRGRWZWxKV1YwbHFLekJqDQpPVVJ1V1hORU0yOXVja3AyTXl0d01tSndRVVp0WlhVTkNtUjZLMVZHUkhoNFVGcEJUV3hsU1VvdmFVbE5WRzE0VTNnd2RsTlFWRXhODQpUblF2ZFZobU0wczRSMDlrTjNReFNIUm1TbGRzYzBsVGFqTmlMdzBLZFRsNk0wTXhhRzF5WkRCT2MyWnBZbG80UzIxeUwwVlZhbmhtDQpNRGhNYUU5WlJrZ3dTRXRZWWpRd2NGZG9ibk5LVTBkcFpubHNRM2d2Tm1ScERRcFFSR05tVmxrMk9YRTRTVFJDY2pjeGFFaFhia2s0DQpVbHBCWkV4Tk1HVk5NVVV5WnpNNE5GaFpkM0JvYlN0a2QwTTRRMlZzV2tNd1YxUndRVFlOQ21oS1EwMVhUMlZ1WlVkWFJpdENSWEVyDQpiVVY1UWpNeVdUTkpjMFJQT0hsNlEwNXBWVlJEWWt0MlMyaFhRbEpzZEhGa2MwaElRelpVWnpKU01nMEtWek4zTW1WYVdsbHBSekpzDQpUblZXYVZsWmJsWjFNa1U0UVZodU1rSkxLMk55YnpkUU9IbHRhbFJMU2swMmQzbFdaVTlLUVdsb2FVRnZhWFZ5RFFwcVMwbDJTa0ZLDQpaR0ZNUmxKRlltVllaRmN4ZDFSWWQxWnBXVEpQU0haUFJGbHVPWEIyYmxsU2EyVnJlVE0wVWpOSFVqRmFOM05yVjI1MlpFTU5DazVtDQpTRTFXVVZWcFJ5OWhhaTlGTkdnNFdWZHJSamxLZG5wT1drNVlja3B4Y2tWRGFHeHJRVkoxYUVZeFFpOUpMMUF5WkRkQ2VGTkhNR0V6DQpadzBLVjNWcWRtRjJVMEpKVFN0TU16WmpiV2cwY0d0T1VYVk1lRlJJZFVOUVVVNUZiM1JaVmt0amNFcDBXak5WWWs1RVNGSXpjM1UzDQpVakZQUlhVMkRRcEdibE5DWkhCeFJETXlZMmRaU1dKTWNHbG5hVlpqVGxOU2IydEJZbkZrU1hNelN5ODFWbXROVVdSWWFFcGhibGd3DQpOVE5LTWt4eFlWQnNOR3dOQ2xoc1FYQlpaa1ZxTTFWV1JXNHlSVmcwTTBkWlpFWlphV2R1VG1wSllYcGxURkZQYTBGak1VOWFielp3DQpVR1pYVVc5bGFVOXhTSEZoWWpaMlVnMEtkek0wTlc1WUsxZ3ZSVVJ0VkhOMGVqQmpkRUpFYWpSb0swUlljbm92UkVKMWRtMTFjRTAxDQpiM05pVlVoSVFUTmljMWRVV1ZodGQzaDNZbXBYRFFwT2RucG5SV2xzWldNeFMzVm9WVVU0YmpRNFl6aHFlVWhXY2pGTFpEUndXbUZWDQpRVkoyVURCRlZuVjFaM2hCS3pSa1EzbDVObFp2YjBsQlN6Z05DamxWY0hBcmIxSTJjV3hqZWk5c2RtTmhNelpJWWxaR01rbFFiVXBxDQpTRkIyWjBOT2JrRXhTbE5WWjFCRmJ6aHlUM0JRYUhoSVNWaEhNMXBKYWcwS1ZXTTVWbFJYT0RZMmNXOVlTR2RVTmtjeFlqQnhjalUzDQpkR05JY1RBMU5qSXdVU3RsVmtWRmVEZDRVa1paWjBkRUswOUtUREpoTVhsS1p6Um5EUW80VDJOYVdUVnBabTFFTTNsclYyNVBWV0pSDQpNWGhOU0ZCWksxbFlSMWhRY0ZSalVVVkNhVWhNVGs1Qk5HWjRhbUZ4VldoUWRrZFRkRmRTTW1nTkNsRlZLMUU1TjA1Tk5VeHJNSFpSDQpZMkUwYjFCRGIwOURMMHRXVEVJNWFVOVVRWEpuUVRkdlFsVjZPWFk0YW1KMUwwRXhUamRVWkVkaVptNWpZdzBLVVhsM2RqVnBiMjAxDQplbVJoTUVkNFNubGxOR3N6VERKMkwxWlhaV2RzT1UxSmJIVjVZemwyYjFOR1VVOXdVRVV5SzNKRmRIYzRRWGhVUTAxWkRRcHdkM2cxDQpTbHBXVDBKUFREVkxZekU1Tms5bGRVeHlZa1kzVlZsaFpIcHZkM2hrY2l0dlRrTmhUMEY2U2s1dWNsUm5WV2RFY214R2VWRlRiR29ODQpDbTh6YmtKTmFHbzJPR0UwZDFrcmVsUmxOMkZ1VjNWSlZTODNiRWhpUzJwTGVISXhhVXQ2Wm5ONVIwcGpSVU0yV0VWeFQySTFObEZtDQpjVkZHU0EwS1QzTXZVR1EzUm1WNlpFdG5jMk52TXpKVkswbGlhR3BHT1RCTFdXUjZPVXhuZFZkMGMzQkVVbGgyYlhCNlRURlhUbmcwDQpZbWR6ZEVkd2JWaEdEUW92VEdKemNUWktSV05uWkhReWMzQXdMMW80YjJoT2FrZHJTWFp6S3pOU2NuZERjMnREUTNoRE5HbGFaVXRMDQpkVk1yYVhSNlJrdFBlbFJLZWs0TkNtMVZkMXBRYlV0RmNVUldObEZ2VUdwNGVEWXJORkZJWXpVNFNVNWFSV1JqVmtkR1NuWmxZbTVhDQpRa1V2TVN0S1ZXTmlUbWw0WTBRemRGcG5hdzBLVWxoMmJFa3JiWFk1YVNzeWNGQnlXa2RtSzFSMFVtSXJRVnBDWW1nMmIxY3pjbVkzDQpWbXNyZVVNMFFsQXlUa292VEZwUE9WRndSVGRRV2pKRERRcG1UMlZoTVV0SU5VUkJURkZNY1dOc00zZGlXR1IyYmxsbVJ5dFNZekZZDQpXRXN4WVZsb2IxcFZSSHB6TldOSU5tcDRiMWhFZURZeFNHNUhOemtOQ2psbFZqUkpSWEptVWtGNlozUlVUV1pIVkVKRFRWSmhhM0ZaDQpXbkpRTVVORU9XTlpTRk5zZDJsdVpYWTRZUzgzYVUxdlpVY3JVMHBTVTBWdmNnMEtjRFpZT1d4TlpTdEhSbXRYVWtVcmJtSmhPSFJrDQpPUzlETkRaaFdXOHhZazVZV0VKSVNuQmliWEk0VEVNd2FEVldTM3B0WkV4eGJUWXZia1Z3RFFwNVVWWkpka2RzU1RObk1scFZTRU5RDQpURU5WZGk5NVNtWldNMVpTTlhONVJFZEZRbkJzUjNSRldVUkVTVzE2YVVwa2IzQnhWV3QzYXpGalFWTU5DazVTYVU0NE1qRlhlbFJ4DQpZMkpYT0RCdE1EWjNWVWxRVUVoQk9FeGhMMjFUV25abloyNWthekJvY2tzMGVGUTRkMWRQVW1RMGJIaHdaWFUxY2cwS1VrYzVOR1ppDQpVMEY1TDJwd1pYazNXR2hXU2xvekwxZHJTa1pGT1d4M1F6WXdXVEpqZVV0Vk0wMVVkbEJZZG5KS1dHaHdObWhXYTA1TU1GbGtEUXBuDQpjVUZuTUM4M2NraEVLemd6ZFVOclRGQkxkbXM1WVZGTFoxRTRWV0YxT0V4d2VscFJUVEpsTjJrdmRYZ3hjbXRRU2l0TldrcDRWMUZ6DQpXblVOQ2xveFlubGhTMjlOVHpZMVkwMHpNVTlOTUdkWFJHcFFXbEVyU2xSa0x6VmljVWhKUTJaQmFqVlJRMFF4WlZWMVRIRkZhMU5DDQpaazAxTDBVM2VRMEtVbVJ2VDFGTk5WbE1SU3ROZDJSNmQyUlpWMHBhYjNCR1ZWcHJkRmRvV1hNM1VuQTVPU3N5T0VwemRUZHpRM0ZIDQphM2RZV1hKU00wUldSbmhJRFFwcFZsaEtibWRpVVRFcmEyeHVSVnAxYzI5bFptWm5VR2czWTBWVWRIUkZZWGhZSzFwR1NrWjNXSFJwDQpPR1J5T0d4alVuZFJkekZ0UXpaUlZWVU5DbmRYYmxGT2NGQndUMUJIYm1VMmRIUkJOMFl2UjJwcVlrRjFPV05WTkRSWmJFWm5VVkJtDQpSU3RQVURoeWF6QkpOeTlEVG5ObWNYZ3JNemhzVEEwS2QwcFZaVWxIV0dKbk9YcGFXamhrUldSVU5XaFRNRTlMZFdOdFV5dHJlWEYxDQpXV2x3VTJwWU16QkdjbTlLWVdWMWFXeDNXbkprV1VJd2FYVXdEUXBZVUZGaWJXbGFjMjFzTjJReVEzTTRRV2d3TDFCSmQzUjBRVzlzDQpPRFZQTlhOT2NIQjRhM0ZvTjBzd1ZITnNNRU5sSzBaUVREZHBUVnBzZG5jTkNsTmlZMDV5ZDIxNGNHNXFUR1V3YkV4VU1WVXhVRWRMDQpaV1J2Vm5Sa1lYcFJMekpIWkRab0szWXhVVmhqVkdvNGJtYzRjMHRDZEdzeGVFZGhjQTBLVDFGcmVXMDBaMEpYSzFKbmIyaEhkekoyDQpiblIxWm1saU1uUkllRkZ4YVZvM05HMVJUVVZ4V204clZVRmlXSGx5WlVkc09YWTBNVVozYUhnMkRRb3dhVkZWWkZkNWFtOW9iMGw2DQpNVXh5T1VVM05HZzJSa3hZWjBoUWVqZHZWemQzSzNWMU5EWTBXRzVYVm10SVlqVTFhbmMxUjBwMVVVazFXUzhOQ21OV1JqUmpjMHR5DQpia0VyTVVRME4wdFVNMnhFWlZvMWVreG5ka0Y0ZDFwYWFTOXZjMk5JSzNSd1NIZFdPVk56TlVOTlJWaDFPVmw1WjFobGVRMEtZa3hIDQpZa281ZW5Sdk9EaHhVbFJFZWxkU2VVZFdiR0V3TjNjMWJIRnNOWFpPVEc5dVpteGpNVWxuT0VZdmVuZEplamhTVTI1NmFqWkZVemxaDQpEUXBzTm5Sck4wRTFOMjVsUmtkaE1XRmtZVlEyVFVzeE5GcFlNRmsyTlhWRU5XWldWbkZKZDBabVNtaE1SalJvYldsdlVHeFhka1p3DQpUR0ZRUkVNTkNqRTRWMWxtZUhsU1VVUXpLek4ySzI5WFpDOXVUV3RGVEhkQmNEZDVhVVpyWVZkd2RVaGlNbHBQVXpKa2NVeHVVVlk1DQpPVmt6VVhwNFZGbE1UdzBLWldKMVJGSlROVE53Y201aFMxSlpNa0pUYkRoWVpqVkNNbmRZVUZOMVkwVXJOVkJ0UzBoamIybFBZakZoDQpOeXROUmtkRVRrZENjM1pyWTBGcERRbzBaVkoxZDFCNGJGTlljbEJ4TkU1MWNWQTVWamtyU3pCM0x6bHFaR2s1VVRsa05GbFBWMFpPDQpXVVZQV1dOMVVtWm9iM00yV2pCTmRuRnpWbllOQ21saVEyVTRhR2M1YVdOSlJIUlBiMjV1YTBacWNXeHFaVVZPUVZGbVUybzVlalJPDQpNSE40YlRocU9YbzRja2RMWWpVeGJuY3hZWGhyTDFOTVlRMEtRa1E0Y1dwT1pVRk5ha0ZxVkRrNE56WjVabVpEZDBKTk9XdzVjVUUwDQpaMlpNU1NzNGJrdzBSbWcyYmxsWmEwa3pkRzFxTUZjMmFHWnZjV1poRFFwNldraHZTak5vYkdVMlNFZHdkV2hUYVdneGFEQlBSMFZNDQpjVVF2Y0hCWlEyWklVRVpFYUN0d055OUdRek5wZFc4dk9Ha3hXbmRRUlRKdE5rd05DalF5ZWtkU2NHTjJXRzloV2s1Q05pdFhOa2R5DQpWVXBFYUdvdlIyZHZTMjFyTTBaR2Jua3dXVk5JV2k5VWJ6azJTbkpQTmxKMlZreHBUWGh3VlEwS1owRTJiMFZHYUVWWWVqTmtUbVp5DQphMnBHWlZRd1J5OVRPVmg1UlVGS05tOHJlbEZDTXpSNE5XZGlVMGx3VEdobVQybEtZVkJUT1V4dVJscDJEUXBWZFhOR01UTldNM2hMDQpRMUIyVTNCcVJIRjVPWEZuUXl0alJFUTVRMkpIVWxsQlYwZHRNSEUyTkdSTVlYa3JhR0prYzIxc1pXcFdOek5MYmtnTkNuZG5TV2N6DQpURlZrT1hOT1duVXdSMUpsTWxOdVZtRjRURWRYUm1oWk1HUmxaVGh4ZEd4Uk1XbDNiRUo2ZFd4dFkwTk5jR05NUTNoelIxSlllQTBLDQpTazFQT0VWWE5ISTFja05DTkdWUE0wZHFUMGM0VHpGelZFMUpTMDVsTDBWaVRHNTJOVEpqY1hJcllVZHpVMDExVHk5amVucFpNa1JMDQpOekJIRFFwR2VEVlZNMXBQTW1GWFEySmtRaXRzYkVZNGRraDFTR1Z0ZURsQ1VFRkJVRXg0UVhobVIzcHhkRUZJUkV0SE5XRXhRbU56DQphRXhyYVVac2RqWU5DbWx3TjI1Qk9TdFhWV2xGVlZKNFJFSmFOMHRrVWl0V01HeFBRWEl4Wm0xSE0zTnlOMWx2WW0xV1NuUjBjRVZJDQpVVEp2VjFwRGNpdDBNMGRoUncwS2Qwb3ZXVlJGTWpaUFJGVjViek5oT1dGdlVVdFllVWxrV1VGU2MyZFBNMHM0ZG5sSFozTlRNbVVyDQphakJvWWtkeE5YcFNWbWMxWTFGTE1ESnBEUXBqZUVwTk5rbGpURWhYUzJsMWJreG9ORTlKTWpsU2QyVkRNRWx4Y1dkVWEyNDBhRzVZDQpXVUZTV1RaWVVIRlpZbXhoZFU5eWVXVm1UVkozUVhBTkNsVk5WRVE0T0ZwVE5YcEtaMWg2U2tRMmFXVXZSMWgzVVVOUlIzWjRZbEpsDQpVM0EzUldFNGJuSlVhV3QyTnpFMVIzZHRjRGhhUlhkWWNHNHZOZzBLU1VWSmIwMUhWbk5uT0hveFptSkhkMGxyVGtzMlMzTnljM3BTDQpSRE5HTkUxaGVFOWlhbU5zZVZwVGRVaEVWVWRaTUZoNVFVVnJUaloyUWtFeERRcE5UMlpZVkdGTVUzWjJjR1JZV0doT2JXNU9WbmRtDQpZVU41Y2tSWU5tWmhWVkExVXpCemNESkZNRFEyZVhnMk5EWkNkMFZ3UVhwbloySlFabGdOQ2pocWFDOVJibXg2VEhwWmJVMUtOVFZGDQpUR2h5VERkT1dFZDZXVGg0UXpaMlVWWmlUemd2TDJwblNGUnJZWGRPZWxGQ2NUSldNRTV3YzNaWlV3MEtTRFVyTkdsTlJETXphVTk2DQpSWEIwUkVGaVdITTFabGRFZHl0cVIzcHRlVk5IUzNOT1pqVm1jVTA0ZFVFNVJISklVWFI2TWtOQ1ZHOUVTVFJLRFFwS1QzaDJkREkwDQpTbTlNTms1MFdqZ3hLMXBNV0VwdVZIVlRNMVZSYTNSWlFrTXZjRmhwY1V0M2RUbHNLMDV6WkV0WlJTdEdZMVUxVjNwelVFd05Da1ZsDQpiSEJ2VkVkSFNtOXFUMjkxY1VGSk9UZGpXblJaTldGeFRHTjBXR1ZFVkZwbVpGcHlNMnMyU1VKNWJqUkNlVTkyZVdZMGN6RnpXbVZFDQpVdzBLWVV4UVRrODVZVU01YWpaVmRHVlNNR0V4YXpoRFdrUnJjM0I1UkRKcGIzSlFObGxEY1VSVVlUZHBWRWRTZFU5UmR6TXZUR1ZzDQpTazFUZVdsNkRRcGlTMDF2VFZkd1VsVTRkaXRHVkhGS2NXbDFUVVJyVjBWclpHcE5TMVoxUjJVcmFFbFFiM1l5YzBFeVZUWkxPRzl4DQpaVW8wUW10aVlrVk9RbU1OQ2paSmNYazNiRVp3UTFwUVpGVXlaazEyZURCSWJWSk1SbXhsU0U1cGFpOXlkRzRyUlRCWFNGQklNVlU1DQphR1prYmxwbVdIZGFVR1ZPZGpSamR3MEtSbkpDY0VabFNEQjFWWGRoUVRKeGRuRktZVU5CUkdOMlRsbHZZa3hHUW1FM01pOVRSbTB5DQpkakkyV21WUWN6aDJVbGw0YTNFcmJWQnhUWE5HRFFwU1ZTdDNSSEIwVkV3MU9IUlFXSGR3YUU1cEwyaExOa1pNZDFBMFVEUkRWV2h3DQpUVmxSWkc1eVkydzBaVmswZFZkWlZWSlNZaTlQZFRSeGJtZ05DbnBzYjI1Q2FVeGFOVWhLZG5vNVVFWnhRbUZqTTB4M1JIbE1UR2RDDQpXalJxY1hjMFZGSTJjbWRPZDI1RlJVVjRkRTlQVDB4NlIwcFRaVloyUncwS01WTTJiVTVUVVhOdFkxSk1hV0YwUkRGb1VpOTNMMnR2DQpkMU5XWVUxMllVdFRlR1pIWkVOR2NHVnRhak42TlZsMVUxZEpNelJDT0dOYUwzbzREUXBNVEZsRE5uUldPVlpXWVVWNk1HTXpSVkZNDQpXa1E0WmpSd1VUUk5VVmhMYkRGVFVHdzJZVUZ2WVN0V1lUZFNNVkpaYkRGMlJVTTJUMnRCV0dJTkNsTjBaVE5MVEVaVU5XVXhSRkZqDQpkVFpRV0c5RmVGY3hWR2d5Um5GSmJYbEhaRTFOYlhObmNrdEZWeXN2ZUhWMVpEaE9RbGRhVmtOaVFXVk9NZzBLWmt4R2N5OTVjM0YxDQpXakYwYXpCWmRrMHZkRmhCT1VOMmNWSm1jRlIxUmtadFJHdFZkR1Y1YUc4M00yWnlibTFrSzA5aGQwWnFXWGhMWXpsWURRcEZiR05sDQpNbkJpYXpOblZuVnBiemw1UVdKQlNtdHBhRGRFTWtKUlNYWmhNa0ZUYkd0VVpuRTNjRTlYU1RsYVQydEhUakJsVUROVGR6bEtSazRODQpDa0ZJVWtGT00wRkllbmRFYTNWcU9XSnpRV0ppV2xkWVRHdExabkJKUkhGak1sUXdhMGt5UkRneVltSllUSGhVTkhselFtbHFXRzE2DQpURkl2TkEwS1ZUWTVOV1JPVGpObVRVWlZZVUZHWml0cmRGTkVORnB2YkcxT2NXVnFOVWhPUlRoSlNGVTFhVVJUWm5rNGVWTTBZMWRrDQpWRVZRYUZwT0wzWkJEUXBWTVhCclRrTXZPVGRCY0V0aWVrOTFOVVpWY25SMUwwcFlTMlp1V25GMlVsWjNXaTgwV2sxR2RHTkZTRGhuDQpjek5NUjFob1ltd3ZiRGxxTlZVTkNtUm9UVnBEYlZOV2ExUmpTa1J1YWxKQlFYWk9SV1ZZVkRKTldVcHFVbGxDVHlzMlVXRm1RM2RwDQpja3d6VVVkdFJVRnFjeXN4Y3pWdlQyMDBaQTBLTVRCTWNHOHJlRVZ5VkV3MlRFWnVlRmcwV0hGdWQxRnpRVEZ6YUhwRGRsWnBWVFpPDQpVR1p0SzFVMWFtWllaVzlRT1hKME5VZEVOV05PY1N0SERRcDBhMWh2V21veFQwYzRjeloxUVRaNldubFFWblJHT0dGcFlYZFZRa2xuDQpTa0ZRYzJWVGExZGpiR0pqWmsxRGVsRTVkMDFOZW5kMGJrbHBlV1VOQ25samQyVkNiR0pXUVc1bVNqTmtXRFU0V0dWTFMweFZUR0puDQpSVzVaVGxkbWIzbGljM2xVYTBSbFZpOTNZWEk1U1RKSmNrNDFTV0ZXUmk5aGFBMEtNVUV2TW5sNU4xaDZVRWgwVXpWUmNuUlNaREpJDQphbEZ6V1UxUWJ6RkZWVmxhVnpaNWVUQTJUMk5DZEUxMGEwVjVPR3RrTmpnMWNHWnlPVE5PRFFwQlpUTXdibElyTXpsMVIxUnlNVmxFDQpkV1JvZEV0aGExZzFZa05YTmxKVVdWWlhRMUIxVGxJd2J6SmtkV1pOUVVwaWRWQkRla012YjJKaFQyME5DbTlFVFVzeWFsRk1ObXRVDQpUV2hHYjNCRE9XZ3plSGRqTkhWcFVsVlhTMlJSWmtGbVEwTXlWMGQ0WWpWM2JGUXlUV2xsVEN0dVdqQnJkbEptWncwS1luSXZVVWRYDQpOMFJDVXpFdmJqWXpObmRuVW1SQ09HcDVXbVUwYVZSMk5FSjNiVWhFY1N0WmN6TkpkMVUwTW0xV2JrNVBZMU5SUVhkR2FFZ3lEUXBqDQpUVkFyUzFCblZrRmtXbGhXUjNneFUySnlZMUF5V2taWFdIZFBla3RqTmpaeVNEUTNNV2xtZEc5V055OTVlRkIwUjJoNk9FdHNMMVU0DQpkVU1OQ2s5S1RXb3pSMFF2TjFwa2RrTk9MMjVKU21Oc2RubFBhRTV5YnpoWlpVaGhZeTlzTlhkSmFGQTJWVzh4VW5sNlZ6Wm9OWFpEDQpXRWRXYVU1MmFBMEtOemx1Y21kbGIwVk9OSEpEU1ZBMVdHRlRTV1p0T0VoVEwwMTRNVUowVkhwVFZUVjBibmt6ZUhOaVJIWmpaRTVFDQpOMmxzV0V0blEyWktPSHB4RFFwUldEUlNkM0pRUVVKb2ExSlJhelpLZFhOWVZGUlJORGhOUkZSTFYwOUtlSFZXUmtKWGJHRndVVlZrDQpibTlVYVdoaVpGTkNkR0YzVG5kbGJra05DbEUwYnpGcVFrczFTVmgwZWk4clpYWTRXa0YzYUdwaVVuVldTWFIyY21ORk1HRnROM2haDQphMHRHYnl0REx6bHBPSEExTHl0MmRYY3JUMVp2VkEwS1IxbGhla2hEUTNwa2FscEpXRlJRSzFodFZtMUpRamRIZERseFVXZHBOVE5xDQpSVzFrYUhsd05IRnZUWFlyYms1VVZtWnFUMkpuVEhkWGVGWTJEUXA1V1VFMUwzZHdibGcyVUhkc1ZXdEtPV3cyTkdwS1ZtdERWV2N4DQpWVVpUY1d4eVJEWlJOV05NWW05SU4wVkZNa3BtUW5VdmRWSkdOV3B0T0VZTkNrNVVhV05OYWxKMk1YVlZZVTF5ZEhZelVGRnpaRWMyDQpZbmxuZGpOVk5sWmpielZtYVZSVWMxQkJhM2RxTlc1R1dtRnFlRTVpVTNVeldIcGhiQTBLUzJ4eU5VTjBOMWcyV205NlJsbFNkbVJODQpiSHBQVGl0dVMxVnZhWEVyUjNsQlJFaG9NWFZ2VVc0elF6VnRRa05UTmsxTGFVWjZUR1JMVjNCVkRRcDJRMmxTV1c5aWRtSlZiRTVEDQpabmMwU0RkUVZWRXZlRk52VWxkaWFrWnBhMDlMWTBvMVdVbE1NMlpPYWtadU1FNXhORTk2V2lzdlFYZEllUzhOQ2xOQ1pYcGpVMHc1DQpOM1Z6VWtOaGFteHlLM2hrV0c5VlZISkpSSE5OYlhkSVlrUm9WUzgxT0hGNVF5OWpTRkYyY3pGeFIxaHhZVzFZYzNaaWVRMEthbk5xDQpUbk50TDFKeE4yVllVMjVwYzFveE9IaGlXWEJwT0M5S1dtOHlVVUpPUkZWbU1YZERWbTFHT1ZjclJIVldkM0JPU2psWWQwcHNkbmhIDQpEUXAxTURCMVpWWkhkV0YwZW10ME5TdEdRbk5hUkdzeVNuTXpSbnBhZGtkcFNraHVTbU5qWVVkRVJuVndjR2w0ZDI1WFVtOW9MMFpqDQpNUzlETlc0TkNrdE1ia1JVVG5OalRrRkNMMjlhUkZOMmVqRkxRbTlsTDBob1kxWlRSMmRIZUZCeVpsSlhhR3h2YURaaVl6UnRSRkY0DQpLMU5UTVhwa1RuWklZUTBLV1RkeVZsbHNjMWxOWVhORmIwbFhRV2RZYlVFM1NqWkJOM2hRZUdoYVJtTmhkMGRQWkdscU5scHVhbEZODQpVblIxVGpkNmRtMUpTRUpGUW05akRRcHBaRlU0VlhwMWFsRXlla1ZYUVdwWFMwcHNXaTkxS3pKV1ZrcDFVblZTSzFwMFVHVXhWWHBFDQpObGhUVW10NFVVbDFXREJaU2tkWWVEUlBTVThOQ2s5cFNVWjBlbXN6TVdnelpXWnZjMDlGY21sQlMyZEZXV0ZYSzFsNVpISlVTemRJDQpWRWhrUWpONlZFTmlWVUZpYTBORVYzcFlaRGhZVG5JdlRRMEtaMWM1YTJaS1dsaEVMekpVUWxkVFltMDFValp4YlVScFNIbFFTSGR3DQpMMUY1Y1ZsaWJEbHFTblJUUjA5VU1rdHBPVmgyUWpsdVYwUkhhVmx5RFFvd1EwZGFOa2g1UkVrM1dXVm1NWFk0Vm1od1ltNTNSRk5ODQpha2hTTUV0WWNsbzJRbXhDYlhWQ05pOUthVUZCTm0xclNsTnJiV1JMZVc5clNpOE5Dbkp2V2xWbU0yTm1ZMWRxZHl0UVpGWlFjamRvDQpXRVZpTUVoWFYzaDJRalJVVTA5ellUSmhkWGRNVUN0dU9FTjZibWRJZGtReWIwYzBWR3hzYncwS0wwUk9UbUoxWm5abmMzWTRLM2RCDQpNa2x2TkUxeWIweENPRE4wYkhKMEx5OVFPVWhvTHpOVVVsQktlVVZyY21ZdlVYUkZiMVZ5VDI5cWIxaGxEUXBFYVZOTVlYWm5ORU5zDQpRM2N6YzFGYU1VNXZWRXhDVVVsVVp6WTJVVTloWlRKc1pHWkhaSEYyVTI5SmFpc3JkbkJ5ZDI1b2FXVjZjamhYUzFNTkNuZHFVMlpIDQpWbkk0VVcxTWFXaDZXRWszYUVOQmVFWk1SWE5qV2pWUVYwOWxVamg1WjIxcU16UmtiMm95YXpKV1dUTk1OVWxYZUdOVk1GUnJVZzBLDQphM1Z2V1hwM1UwRjBXbWhzYjBaMWRFZE5kRXBMUVZkcE5UQkNUMU00U0ZGb1ZrWlpiVmw1TlhoTGFYZDFWSEpxZUVaV1kwdFJTblJHDQpVRVJKRFFwaFNsVkhlazRyVDFVM0syMHlWRmxXYTJ0RmJYUlJkbWRLYjFocFEzbzFkMVp3TlZKV1p6RlFkbFpLTmtKR1p6QnhMMDFTDQpRekJPV0dOMVMwY05DbUZsWlc5UU5GRm5abGRXZDBSRU1FOXVVR0p4UkdVclp6VlVaVzVxY0ZwdVF6UTROM0ZhVW1WWGExTTBSa3h0DQpXREF3UWpOSWJVZzJhekZFZGcwS05WZFFlVXA1Y0d0VVJtcFVjalV4TjB0RVduZzJSR2ROTVZOeU5IVlJSbGxVV1VwUGRFcEhNWFF3DQpWWGxNYmtONlpURTNObU5ZZFUxdE0wRXZEUXB0VDNGTmRGSmFhV1ZOVG1jM1NIY3ZhVnBzWm10WWNVazROemRCV0dSS2FrRllXWFYyDQpiRVZCVm5abU9FZEhSazB4VVZCaWEwYzBUWGhzT0VrTkNtaFdRMkY0YUdWaU1VSjBlR3gwVTNsTFpFOTVPWEZsUjJSWFFXaDFLMk13DQpWV0pNY0hoU2IzcEdTMWRFYTBSemNGWjJTMU5HTVM5WVpDOVVadzBLUVc5UmFtNTJjWFk1VldGT1EzVm1PVTUwV0c1ek1GUlFSRE5KDQpaMlpRVml0bGJGRjJUQzl6TldFNVl6WlJibGRZY1RoaVoyMURVbE5xUzJ0bURRcFBWazFIZUVWWFFWWTVkemxNWVdGbmIycHdaVkZzDQpMMnhNTmxvdlRUbHNlV2RuZFZCNGVraHNjM3BpTjNWb1NUSm5OblE0VUdwR1FqUlhUVTROQ25wTk5pczRRV2MwYVdOMVExaG5TVlphDQpZelZYTVVOVGFtdEtMMFZDYlhkR1NHZEdTWGRKZFVwNE1XNXBOMEV3TW1sT0x6UlFTWFo0TkZZMmRnMEtSVGh4Vm0xdE5XVnhMMEYzDQpVME5YTkhadVNFSTJUSHBhWkVJNVVVUm9jV0Z1ZEZCR2VVbHdRVTB4WldwdFFXaGFTMEZTYkdFck1scERXa2hFRFFwMGFUVjRXRzV5DQpjek42THpOVVZFbHlhVEpwYUVkSk5sSTJibWhETWxoVGNDOVpZVmcwVm10MWFFTnhaR3R2UVVsUVIwaERRa3hpVWxWeGVGQU5DalpuDQpaazVLWW5kdFlreGxlbGhLTUVaaGMxVm9VMnQxZW5WdE1XZGhSWFZXTkV4SFV6TndhVmRQWkVWdmRtOWFWMWRHWlM4MGJIUlVSV3hKDQpiZzBLTWxGbmNuaHRTV1JwT0Zad1UwUmtOSEUxYm5aeFMzYzRhRGh5ZG1WdlluRklNVWs1ZVUwM1prcHlZV2hGV2sxTk1tRklNbmh6DQphR2xPZVVOV0RRcEtiRWhXTlV0d1YzWlVXa0o0ZWtOUmVDc3pRbHBHUW5kMFpuQXdUMnBvWTBodmVGWktWVTB6Ykc5d1J6QkJTRXRxDQpTams0ZFdSaWFXeFpNaXNOQ2s1NWVsTk5aREl2V2paTk9FSkNWREoyWWtSS1NGRkJhWGN4WWpCaVJuazVUWGRDYzNsYVUwOVpOVTF5DQpSa0pLSzB0TEwzTkhUVlJ5ZDNWUU5RMEtMMVZaUzNOdVMxaFlRM2hNTmsxNU4zTXpjMDlCU0RCYVZHRk5URGhqVUd4VFR6bDNZMUpwDQpRMUp3ZHpsNGFGaEhVVUZSWTFOa2VFbzNiRzk2RFFweFpWZzVRbEYzVkc1WUwyVlRRMjlqVUdOd2RYcG1jM296TWxwUllVSTVkSGh0DQpUV1ZOVFZnM1JtWjRVVTVOZEhCVFEwTm5Na2hCWTNWU2FrZ05Da1p1ZFRoUkwyRlpORkZJUldaRk1WbFFWbkJRT1ZsWFoxSlBTVzloDQpZM1ZKU0hkWE4zbG9OVE5PVW5rcmJrcHBSbEFyVUhSV05HbDRSM0JEVlEwS1JsRjBOazFqUldsWVFqWnhjekV3YUN0c1R6ZGlaVVZSDQplak4yYzBoRGMzbEdjMUEwYXpCUEwyNXNSalZMVWk5VVZVWTBjMHA2YkhSVVJFcEJEUXBtUTFCRlIzSm9UbEJYUXpSalFuRXdTMmQzDQpLMHR5ZERGNk1tTXpVV1ZVTDFSeE1UaHBkVGhwU1VsclMweFpRM05XVFV4aVUwMUlZVWx5YkZnTkNtWkNkMHRqYVNzMk1XZE9ZVFZrDQpZVEZ3YlZRMVVtUmtMMnROTVdObVZUVXlLM0JFYkcxaVFXcHBlSGhKUkc4ck4wNWxNMDVyUkVoSWVETkRSdzBLVERkRVVEbFFjMUJpDQpPR3cwU0hsSlkwVmthMGcwWjNOTFFtRXpPVmMzYjBSWlMweFlSM0l5YkN0T01qTlBWR2hVY0ZWdmMzcFhWMmw1ZFRoQkRRb3lNVTlyDQpiMXAwTjNkSmIyOXhZVkpwYldWbVJFcDBRbTR5UVdGeU16aEhMM2MyWkM4dlVuSnpabFp6ZG5WaFIwcDRTa0UzUVRWRE1YbDFibmdODQpDbWRsVGpkSFpsYzFkamhHSzJWR1UwaFhaM2hTTDNKTE0xRk9aVm93VjJSM01sZFlSMjlUWWtwd1VtWkliV1JWTldsd2QyWnFjaXRpDQpXR050VmcwS1NtRkZNMEpJVTBSYWVWWnVValZQY3paNVREUnZRbmhRT1ZZMk5uUk1RWGM0TDJWTWVFcDRiM0pUVFhsdVZETkRSRFpKDQpjMXBGUkVGbVduaGhEUXBTTW5oWmFua3lRVnBhWmxjdlpUVnJLMGx6ZHpsd1lVbHJiVVZ4VFRsSFZtNU9XRGh1V1d4YWRURlBiRTkzDQpVbTlFWlZWaVRHa3ZjMEV5TVdrTkNuQlNTbGxUV0cxNldXcHpRM2xwTDBSYVQydDJOV0Z6TmtwVE1UbFBNV1ZJU2pKRmJtd3ZNbWwxDQphVXBMWjFOR1kzRlNkSEpGUTIwMlV5dDVkdzBLVW5KQk0xVXhjMk4xVDFodVN6QnhNRFlyZVRKcFUyVmFiSFZMZEhaRVVEQnpRVWRJDQpkWGhLTUVoV0swbHpSVk5UZUZsbVEyMTBNaTh5VEZodURRbzVlalJhZEVaYWRHNVdLMGxOVVZwdFJXcG1SQzlGTWtkNVZHOWlRMGRFDQpTVUpsVkhBNVVYSmtZbUpxUm1WaFdHdGxWRUpRY1dZNGIySkZZWElOQ25OU05FRldOakZRVEZsUGJ6SkllbEZrT1hSME9FaGpkazl0DQpUV2hEYzJKeldFZHRiVUZFUW1seUswUnROMDEyUVdOMVRHUkxOMDlCT1RJMFJRMEtUMGRJZGtkS2NXcFRaWGtyUW1Ka2RUUkZPVEZDDQplaTlzZUhCeEswdHZWMFpHUW5aR1IySXhaSFV3V1RGNWFWQk1USFJ2TTJ4amJ6QXdVME5vRFFwSFIySjFlWFp6YlUxcU4yVkdaRXd5DQpZbUpIV1N0dWJuVnNiVlpGVlhGNVQyb3hNVFZ2VmxwQ2JsYzBabTlhVWpWekwyZzJOWGhRY1RZdlNsTU5DbkF4VjJab2FYSXZNbHBxDQpjVGs0Vm1RNWVFaFRVMEpRTjJoc1dIVkVNRGcyUzNaUFkzaGlUMUpqV1cxUmJpOUJTV2xhV0VZNWNERTJUMVJ4WXcwS01YVndOakpHDQpOV2xqYzJoTFVVRkJZMnBYYWpoSWJqbFhZMmxVVDJ0VGRtcFhVa3hQU3pZNWRHcFpNRWhWVVV3M09GZExXbFV5TldaaGFUZEtEUW8zDQpkMFY0TTJjdk5XTTRaVmwyV0U5RVNsVlhjWEZtVjFob0szRkxUbVZFY25SR2FFWnVPU3RGUTBjeFVHTnBNamt3YkVGSVNtZ3dXa0ZvDQplR01OQ2xOSFNERTFLMDFDWldnMmVtZFBWWE5xVGxoUWQwUkxWbWhqWTFvMWN6RnBhbVJ4T1hOU1QyNVhWVWhuUzFVeFFUUjBOazFDDQpaM2xoVjNOaWNRMEtNV3RZV0dKbVVFSkdTME5pVVc5QmEwTm1lR2RyZERkcU9WUXlNVk4yTVZFeEsyUklaazlCWTFWM1ZtWlNVRzl3DQpiVVZVWW5oSk5tTmlLMEZNRFFwSFlrWnlRMGNyWTNkb01FSm5XbGhrZFdwNk9IbzNMMmMxYm1aWU1sbEZkalZHZGtVd2EzRkxRelZTDQpVMVpEUVcxTVptZGhjV3RyTkVKNlRrUU5DbWNyWjJwU1puQTNRbVJrTjA1d1NEY3pOVWhITVdsVWVIa3dMMnB4VlRscVluUkhPVFZrDQpVbFZwYVZaNkswZ3piWFZPTTB4UlVYcHhhakpNTXcwS1VIVTJkbFJDTW0xTFpXUjZSRk5KTm5oSE15ODFWMkZaY1dKNU5VVTNlRUZxDQpPRXBsYlROVFVtSlNSbmh3T0RCYU5XdGhVa3AxYmtvd1Ewb3hEUXByY2tOMkt6TkZPVk53VTFGNWJIQXJSMng2WkZselduZ3JUa1ZIDQpXbTFWYTA1UlN6aHZObHBSVERCNVZuRklhV2cwYzBsdVR6RlpZa016YW1zTkNtb3JVbFE0VW5KNFUxcFhkbVJsTDJrMGVYZFVka014DQpSVWN2VlVsTFVpdHRRa2RqVDFVeVkyODVhMWg1Y2twUFkweGtNVVIyVlVwUk0wVlphUTBLZUVOWWNUWXdMMnd5T0RKNmNFVldiQzlQDQpXbWhNUW1aMWVXeFVkelIwYVhkUFlVOWhTbTVLYzBFd2J5dHpjV2d3VTI5M1ZHUjJXbk51VDFGVERRcEtTbk5GVTAxYVVHaHhjamRYDQpiMnN5Y0RVdmFqQTRjMnRGVmpsSlJrbE5UemhXVkZkQlRGTlBlWFZTVlhoa1VHWmtlazQyUlV4cVJVc3pSMFlOQ21veWJtdGxObEpwDQpXbU4yWVZkM1JXeHhXWFZsYWxSNGRrUnNhRU5sSzNWNmNsWm5kVmxVWVdwaGFVSjJZMW80WTNGeVFtVTVXR00yY0ZGcFJRMEtUSGhtDQpjRzh3YjJ0eVlWQjZLMVp3YzNkTWJGZ3ZaVVJzTlU1dmRUQnVTVXc1VWxGNVlUZzJVMjVpVml0UU9FSmtOWEF3VEZkbmJGVjRObEJvDQpEUXBSYUV4a09YbHhWMkYyZVhVemVsWlhjVXhWTUVaNFpXdENXa0prWlVWU1FYSnlORlJGYlhBemNuWnJLMnhRV2xsVVJuWXZhMmcyDQplalE0VDI4TkNtNTVNekpDYjBSVU9GZzJUVTlaTmtKVVJIRnBNRzB5Um1OemFYbFJZMGxLV1hwSVRXZ3daMmd4WjAxSU1HdExPV1pWDQpTbFpIVHpkVGVWQldZZzBLV2t4R2JVWlFSRUphYUhZdldIWmlRbWxIUlZRMlVqWk1jMEY0WjFsTWJHTXZPR2R5TVRoSVp5czNXRmRKDQpOVFZOUlhVdldXZEVOR2xaS3pVd0RRcHJUbVZYV21keWMxRkZTV0Z1WWtoM1JrbFpNMUpCZVdsUlZEQTNWakJCYVVGR1lXZ3ZNMGxsDQpOemRMZFZBd1FrNWFUak0yU2k4MlQyTk5kV2dOQ2k5SU4xRlVjSFJPZVZSMmVYUktkblZQT1VaT1puQjFOMms0VWpoWWFsWTRiM1JNDQpOR2hNTVhJMVozb3diSEJVWW5CV2FraHZkazFzU0UxSFV3MEtha1Z5UTFoVVozaGlOMjFGVXl0dk9HWjJUMEp6VDNaRVdtd3lha2xLDQplbE4xTWtRMFpXRXZVM2xuWkdsVmVGcFJUMmhQZFV0RlNGVlhNR0ZFRFFwRGIwWlRWa05DZEVkV2IzQnRZUzlWY3pkR1JuY3JiWFEyDQpLMlJHZUc4MFVqQlVMMDlQVjFwUFlXUnNXbkZ2YTBSdGFFTkRhVzVxUkhkM1psUU5DakpPVUZnclJXTjRZbmQxV21zeFF6Rk9NbVZ1DQpWVVUzZHpOdmRFZExXalUzZFRZMFVXeHlSVUZCTm5GT1J5OXFha0p3U0ZsWGRWZFJTRmx3T1EwS1VGaDBkWEJ0VjNOaGRWbHlja1ZKDQpibFZPYTBacWJrMVhVVGRWYUVZNWRVc3lWSG93V0RCamJXSjRiRVIzY0ZCTVYwRnFlaTh5ZUZwU09HSjBEUXBqTnpoQlIxcHJhVXBvDQpLMGM0TURScWNEa3haalJVZUVOd1VIUmxWMVF4Y0M5clMxZFVaemRPVkhaSk1VRlFUVmxaVEM5UVQwczVSMUpuYW5nTkNuVnNPVlJ4DQpaSE5YT0RkVloyVTVka05HTDJGQ2FVdExlbGh4Tm5Jek1XdEhhM2hEVm01VU5uTlhSbmc0T1RKRksyOVBOamh3VW1WYVVXNTZTUTBLDQpkVUpDYWpCM09FcFVSMU15U1dKdFVHVnVWbEoxWTNOa1pHOHpUako1VldKd1JrcHJRM0ZEWlVKamFEUjJkV1FyWTA5TmQxcFJVVGRHDQpjazlXRFFwT1JEVllSMWdyVFV4bGVtOVVNa2RIZDJ0VldWaFZUazB5U3prcksxUnphV2htUVhOMGJsQldPVFJaY0dsWVNGVnBXamM1DQpNbEpJVFM5d1dXME5DbXhMVG5GWGJHWkJMMGwxUmpCTGNpczRjMkpsVURkTGF6WXJjbE16VjFFeWFXbFVSbU5RV21sNFdTdFpWVUpIDQpiMVYwVldKQ2IzTnZaMU5FWmcwS1dqSk9TWGsyUzNaTVF5OWpORUpEVHpsNVR6VkdZekJVZVROTGVrSllObVJqYkhkcFVEZGtWWEJ3DQpObUpEZERaVmJFMUlielJDUzFBcmNWTlJEUXBvVFZKaWNYTkVTM2RrYjA5MlptWTFSbWhrUVVremFrZ3ZOMWxQYkdwU1ZXMTFPWFpODQphRXhITDBKa2NHUk1jVEZJZEd4amJubEpkMVJWVVZRTkNtVmxSM1ZQV0VaS2MzTkdhMDFPU1M5WlpFNVJNakI2WVdKS2VHbDBLMWs0DQpkRE5KUmtodk1rNU5aMHhuWlc4cllXNW5hbWRzUW0xcGNsUXJVUTBLWjJoWmIxcE9NVE5tVjNWVVpuUndUMDlLWVVOVmR6bGxhaXQ1DQpOWEJoUTNONUsyeFBNa3RqVVhSNVQwZzVObk5pZDBOb1EzUmtkRUZtV0dweERRcHdSR053U21aWGVIQnlPRGxHY0doYVN6UmpibEJzDQpRVkl5VG1NelJtNURVMWh0V0U5blJtdFhkMjFzZEM5dlFWWTVPVE5rVW04NFVqUnphaXNOQ25wU1dVUm5XRVIyZHk4d2JYSXhTR2hpDQpLMUExZEZsSFVYTmthV3RQZUhaMlFUTXJPVFp3T1ZJNFJqbFNObXhrVXpsRlN6UTBlVVpYTmpSdVNBMEtiVkptVlZFMGJVdFRVVWhwDQphMjkwT1VkQmMyRlpkMUpzZDNacFNTdGFZblpZTUhaV04yTlZLMXA2ZUd4VFJ6QmhhUzlNVWxOR1VXUldkbFJPRFFwd01GWm9UWFJXDQpVM2RYTlZCcFpUZG5ja3gyWVdaV1JHMVdaVXMwTmxKdVlVVmhRMFZpVUdoeWVXWm1VRTVDZEdaNlIyTnFkRE50UjBWRE5rWU5Dbk5QDQpSVVpMYkVkSGJIVTFjM1ZFYzFoTFFqZFJSRVZVWjNsdmRWVmhUbVJTS3pOa1NYUjJRelkwU2s1elZuZEpjVmR2WW1rclVUQnhkemxWDQpSdzBLWlRCcFUwZGpMM0pTU1RGaFdWTlZiVWRrTUV4alNsVTNVa0VyVlROeGFqUXZjMjVMZWpKMGJuVllUekpOZERGeE1GWkRSbGRWDQpTVnB4Y1hKMERRcE9ZbEpJTms5V1YzaEJWV3hwWW5aVlJrazBTalZ4TjNCbFFXOUpSek12UzNwM2VEbEVaVXBKVUdWblRtUnNPVFZRDQpiRzVpVkhOT2QzbG9hVUlOQ21ZMFJFbzJTbWRIU21vMGNuUnhZVTVPZVVFMFZFdFVkamhUVDFWWWJYSm1NV1Z5WlV0cFJHTkRkRmd5DQphR3Q1V2tKUVEwOTBSaTh2V2k4clRRMEtPVzFtUzBGMFltTjRTVGsxT1RJeGNIVjNZV3R0VHpkRlFVTjZVWFJNY0Zrd09FeDRZblppDQpWRmRGVUhOUU1YcFFVRXd6YURsRmJXbFViV015RFFwS2JGWklaMUJ4YlRGNFRUQXpNbk5LYTNCemRXNW1UakZLY1dwVlMzQjZUWFI1DQpaR3RqVjNaSlpFbENWbEpwV2t0alZsQXhlREYwU2xoVlYyWU5Da1I1YzB4RFkxUkRURGRwTlRSMFUwSjJOVWsxWXpGNlZXdFNXSFJTDQpkMXBQZUdOVVZUZFdOVVZVWlhsRFJITlJXRU5uYXpGQk5FZ3hPSEpuT1EwS1kxVXphVkEwWWtObVpVcGxSblp3UWpCME5XNXBOMU50DQpRbVpMVDFGbVJWVnpNVlJUTml0RU5rOWxNVmxCVFRoUVJXaDRTWFpKYURSNU5FVjZEUXByYnpKNVpVSnZhM1U1UjJGaWMxQkZSSHB0DQpTbmhKWW1WRFFqWmljM0pIWm5WdVdGZE9ZV1ZpT0RCSVRFVkdaa05ZT0V3d2NURmlhRWwwZFhJTkNuSkpVRTFuVDFscVRIRm1kSG95DQphemRhY0doSGNucHZTa2wxVDFwVWRUSnBkM2xMYnlzNVJGcEpNRVpqUldvMkwyNDNjazU2U0VsQ1lta3daZzBLT1RRcloxVmhaVlYzDQphVFpOYkRaSksxQmFLMk5LZGxCbGFISnFja0V2TVc1c1MwaFVMMFZPVkhkQlpteHBXaTgwZEZrM2VGSm5NWG8zTTFOMERRcDRORmxoDQpTV1JHU1hwTVFXSm5Ua3BpTkc5RU1HeFhWRWMwVEc1TVVFc3hZMU5aZEVJdk5WZzJNVW8wVjFaU2VXSTNaM1YzYm5BMlVFSnlSV3dODQpDbmhoVTFweGEySm9aRU5VYkhjeVJDOTZLMk5aWTFaeGQzbHVkVmRHVEZjNFpWUjJWWGRqVDIxREsyWjZlbXR5VWs5VkswcHJVV0V6DQpWbGw2ZWcwS1ozRnVhVTl1YzFKcGNtWnZOblpoTldoYUwzUlBhRGx4WVVwblVGZGthMFZSWkZveE5WQXhOM2hoZUcxdmJrOXdRMlpUDQpWR1pzWW1ZMVZtbDNEUXA0YXpJeGFtZHBOa296VFc5aWVXdHdWRGRQYnpkUU9HWlNhRmR2VERsU2RUbEtMMjQwVm14bWNuRkNkR3RMDQphMmR1WlhaVGMxRm9jWEJ4VWswTkNsQkJiRUZTT1RSUWJUVjJkblF5VkRSeWJuQXlNSFo0ZGxwYVkzUlZZbVpQUkRWbWVuaDBabk4zDQpjRWwxV1N0U1NtbDFabHBTVFZKNFFrOU5NUTBLTUhOeGIxUkRlVE4yZGpKT2NuZHlZWGRzYVVKU2EwNVZabkpzTVZCS1REUTJZMDVaDQpjVEEzUWxFMGJFNXJRelZwVmpacllqUTRia2wxYzFOUURRcHBUV2h0SzFSa2NtcFBNMnh3VmxJNVRDOUVLMGx3V2pOeVJEVkZSamhVDQpXVUV6VW1wNFdqSXpNVll5WkhScGFUbHVZMWc1T0ZONGMySXZlVVVOQ21GTlRHZGxNMGhuWTFBd1Z6bElaWE4yVlVWeVMyeFVVMmh4DQpTMG9yTkhJNWQyWTBlRkZ4VUZGWVJXaDBiVXRYYWl0ME9WQlZlVmsxT1RGcFdnMEtZelF6YlUxeVkwaG9kbEEyUzNaRU0xcElaalEzDQpRazFSVjBOblYzWXdTM2hYTW14a1pETXhaREF4WTNrMlYyMVpVbFZWT0ZOaVNEZFBSME15RFFwTmQzWmlUa1ZyY0Zwc1RsRjBPSFJMDQpRMEpFS3pWV1VuaEVOSEZFU1hBNVMxQk9heTh2YmpReGNIUk1ZMlZQWkhGVFNrVjNjemwwVURsT1F6a05Dalk0Vlc5dU5qZDRkelpGDQpNbEpNY25KdWFtUTRURTFoUVZaaVVsVkVRWFl6ZFZwRU4xRnVUWEEzUVhWb1dqVkZjR293UkdSTlpFUldMMlJoWWcwS05XUktVMGMzDQpTbFpKYUhOT01YTk9kR1ZhV0RZNGFFSnpaVUY2ZUVkUlRETldVelJEUzNwNWJUazNlVEZYY1ZOT1ZIaG1jVGxuZERsWVpHWnNEUW8yDQpOM2h5WWxBeE5WRkJVbTQyYlZjeVNtNXBNMUpPUmtkSE9IVnpTVlpOTTFGNU5GcG5RVEZZYVhFd2FEZHBlVGREUlROUGVFMUhaVlIyDQphSE1OQ2pBelduSk9TMHBITUZGVmNVRjJkR1ZMYlhweFpHTlFSQ3R5VFRSWmFFWXZiMlpLVjNoV1lWaENVVFEyV1dFNVptaHpVa1JVDQpTVmt3WVRJdlNnMEtXWEJNTXpJeWFVZHpjM3BPTTFFd1pteHljV1ZVUjBOalVDOXpNR3g2YlM4eGIwYzRSelU0Ukd0Rk5XeFFjMmhqDQpURUl6TkdSUGVXeFZWWFJ3RFFwRWRtMUJUeTlqVm1aRGFXaDBiVXBpTUdJdlYydElVRVUwUWxCM01WQXZNVm8yU0VVck4wWklRa3hQDQpkeXRVZFhaamFHOTJXVkJLZUdaSmVXRU5DbUZJUmxkV1NXNW9NRTFGYzBRek1VeDVjQ3RUTTNaR05qbFNjWEpFUVdkamVDdElVVE5NDQpkVk5ZZG1wQk1XTldVRGd4VVRGbE9YRlNkRkpFTlEwS1RqTkdjV1V5T1VablFrSjNRV014YlZacUszVkNiek5TVWk5RmRrcDRTV0ZwDQpVVUZCWlU1VVp6ZFRWWE5GY0dWTFNTdGxRbGhoU3pkd0wzSlVEUXBMWkhad1VtaHNNblJsYlVaRFpGWkhkWE0xUVhsR01UbFhNaXR1DQpVVWx0Y3pkdFdYZFRkelo2ZFdSU1VrWmFhbWRDZWtwb01YWndUVk5JWjNvTkNuTnRaRmhhTWlzeU5tMXdUV001WWpaWVdra3ZhMVpEDQpOWFpYSzBaSWNFbHROakJMVGpKTlVtb3hUa3hxYmsxSFRYRlZVMjkzTkd0U1FtSkxTUTBLVEdjMFZFTnBMelpwU1RKNU5rVnNVMU0zDQplVVJDYURrMmExaDJRMVJSVVdOc2Qza3ZjazRyU1dsT2F6TkhTRWhZVEZwdWRuazBkSFJSYUdzMkRRcHplVUZoYlVnek5IVmhTVzFhDQpPVEZ5WVc1b01tTTBLMHN4YUZaYVYwUnBjekF2U0dwMWJpdFlUVW9yZWpKRVNuTkxPRGg2UW05eVVWZFNXVlVOQ21oYWR6SllTekpPDQpLMVpPZVU4eFdVVmllak0yYkVWTllVVkZNVmRvYjJsVWQxRjNlRU41Ym5kSFprTk9ibVJ4UTIxQk4xRjVlSEpMTjJKbVV3MEtlVzB3DQpZazVvVEVGc1ZsUllUVGc0Y25kSUswOVVWekpzT1VFNVl6SkpNVFl4ZVRkc2NteG5ia2RLU2xGYWNteHNPRTFuYlZGeVVIbGFkVVZzDQpEUXBvVUhJck9XMDJOVVZ2ZWxsVWFYaDZla0UxZUdwTU9VbzNkQzlyTld3eVYxcHVWRWxsY0V0NlNWRlFWSEV5WXpoQ2VWcHVlR0ZtDQpVbTlzTmt3TkNuSnBPR3QxVXpsbloxQjBNV05OWnl0ek9DOHlRWGhtV1RWSVQyaDZiVmswVjBvM1JUSlVlVUV4VFhoaWRqWmFOMVlyDQpTVFZpTDFGS1NuTnJZUTBLYlhnMGFuWmxUbWM1UWpSM2RteHlVblJQZDI1UFdHdFZSREpWUTJOS01ERlVTM0pKT0RkV09YaDJUR3BODQpNMUJNYVU4M05FbEZaVTFaSzBWWkRRcFZWek50ZEdaM1dHMUlPR2RKZFZrMkwydHBkR1JoVXk5WFpsaHRUVVZVUWxSSGJYVm9ZV3h3DQpUaTk2TTB4cUswOURWQzlCVW1WblRqbG5PRkFOQ25sMlVYRXlSMnAzZFcwNFVHWnNhMEp4T0VGdFJHNVJjRlpKVm5OMFNFOHJObE5KDQpRMkpwV0haSmFETjRkU3RYUmpSaGFGZzFMekExTW5wTk9RMEtZM0J1VWxsUGNERlhXSFJJY2xOTFVqZGxZWEk0S3pScWRtMUpRMkpQDQphbFIxVkRCQk1YSnpla28zUm0xc2NXeGFiMDE1UzFSMWFYbzRVSEJJRFFwWWNYWjFVa0kzZFc5bU9GSTRWRlp3VkdvNE56Wm9aMEozDQpNVzFLWlVkNE1XZEVUamxKUkV4MFpUVjZibk15UTBONFpIcEtSM0YwTVdGQ1JFa05DbUpCTTBvemFqaG1hSGswYnpsdE5qZG5PR2hQDQpRbFJTUkVaaVpUVjVhall6TlhOM1NFZFZVbFF2VFRScE9HTldhR1J1YjBSNVZISXhjM1ZIYVEwS2QwaGFPVWhFVW1SS0szWkRWMVkzDQpkRmxxTkZwUE9IbFhTeXRPUlcweVJFVlpUM1F6Wm0xS1ZGTm1SMmRaZVN0NVpFaHVlR3RSVDNkMFZFUmFEUXB0Y1dVMU1GbGtTRU5EDQpSV00zZFVSS1QxbGFWa1Y0YUhwSmVYY3diMFpOYmsxblpuWTNRM1pNSzJsSlpFbGhkV3R5ZEVGbFZWcHhNbU5hT1VnTkNrbFlRV1ZWDQpRMEpFVEdoUWR6VmlhRXBCUVRFMFpqVnpiRzE1TXpORE5tbEpjak4wVDJoellpOVNOSFVyZGpkRU9EbHNkazVFWVRrNFQybHpadzBLDQpRM2hWYzBsMmFWSlBhRmhYVG1ONGIzUXdVVkl5VXpocVNEVlBlV3RYT0c0MlVsSlVZbkZVTm5ObFdUWk5WVlZXY1ZSa2VWbzRWRUZtDQpSMFJ1RFFvd04xZG5ZMHhNVFdKMFNWUlJVVWh2U0ZaYU9ISTRVMHN6VnpGWWNFUjVWMEV5Y2tKUFlVMXFWMjlRY0haQlpsaGxkVXRMDQpjbFYyUVV4VVUwd05Da0l2UkhwaVRXRldhRmRDTTNZdlZtUXZVREJyWWxoU1prNTNjSFY1U0VkdE1GVXlZbU5wVVdZNWFUWkdla3RUDQpUVUpMTjFwcFRrVjJabGh1YWcwS1ZWWm1VRXRTTUdZdlJrWm9ObGgzVkdadlJITlRRVkF4UTNGd2RrSmhLMHgzVmprekwwNUhNbXB0DQpjRkJNVW01ck4ybFhlV0o1V21oSFFVcExEUXBEZG1GeFYwbFVSV05WY0hkdGVFVjZSbFp5ZUhFelNFdE9heXR6TXpOaE4yNUNSV0UxDQpjbVE0ZERWSlNscDVLeXQyYUVacFVEVTBVbUkwUW1RTkNsbEhSek42VURrNU1WZEhZamhCVGpWSmVVMUNlbGxJTmxGTmN5dFFOV3RzDQpjMWhqYlZScGVHeG5WaTlwUkZkNFRqQXljVVZzTlZGMFIxWmtOdzBLZW1OUFJWSkVhVFZ3VlVWU2JERmxiVGg2VjBsc1ZrcEJUa1pwDQpOVlI1TW5od2R6TlBXVU42Y1hwMlVVeGFaMVJLWkVsSWR5OUtOMkpxZEdOeURRcFpVbkVyVXpGWFZGUTFjRE14TUdsNVNEaFFSbXBVDQpUMmcwUm5WM2RVSlpjRzVMU2xCMWRHMUhUM1ZWVW1NdmN6RnlRVWRFWm1wRllsWlBkbmtOQ2pCTmVqVXpZbFJYZWxSaGRGVnBWVFJ2DQpVaXQ0WkhGdlRHNVVaM3A1VVdaUlp6ZHZjblUyZEVNNVNIbEpNMHBUYkVsaWMxVnZSWEZwU1N0NGVnMEtWR0pVV2s5elRXeFpZWEYzDQpOREYxU2pkTGJHMW5kQzlsTDIxS1kxZEZhR2xPYTA5RVUyUjJZMWxtZFd4NmJFOXdXV3RJVDJoTmMxSmtkVEJvRFFwWWVuSTVaMEUzDQpkbkV6UlM5NVNtVnpkekJ4ZUU0MGVHRXhRVlExVTFaSE0zVlZjbWhGVUZKa1JWZHBaa05oTHpGdmFGcGxjaXR6Y25Wb2MwVU5DbWwxDQpPV0pHTlRoS1dsRjNaVk0xT0RBeU0xZzVWbWgwYjBSRFdUZE5iREpIYmpnM1ZUa3lhVTl1U2pCVWRXSnBia2Q0UjI5RFUxTnVSMWhDDQpaQTBLYjNGeU9UZE1ielpHWmk5RFJWRkdlRVZUU201cFZuWlRaWGxwY25kdFNrWnNjMU4wU1ZsWFZTOVVNSEFyVTFwcmIzUmhiSEZ0DQpVazlEWjBkdERRcDFNWEoxYm5WUVEwazJPSEF5VWpVMGIyRnlRMmRXVFdKeGEyNUxibVY1Y1RWWFUyODNZVFo0ZVM4Mk9VMU5lWFJ1DQphekJTZFRnMmNEY3phemtOQ2xsalVXOW1SRzEzWldZM1pHUkZRemRKYVV4VFdtazFXa1F6VmxnclYxcFFSVVY1UzFwcmJXUkxWVXN5DQpNVEJtUWtRNVZUWlBORE5UT0ROa2RBMEthVVZIVUdwMlMzVjVTekkwY1ZKdU1FRkdXazh6WkhvMVIwaE1iV0pRT1daYVZUQnBTRVJHDQpha1pSTkROS09FcDNjM05NT1U1VE9VUlNVRVUxRFFwU1J6WnNVRGdyVERocmFtTnlNMjlxV0VSYVozTmpjM0pFYzBkS2Rtd3ZVMUowDQpZVFo0ZDJoRVNrWXZiSFowWmpkWU5ERlJjVGh0U1V0aVdqa05DakpsTmxkVGVIcHBXbmd3Y21wUWNGZDVTbFoyVTBsWWNtVkpNM055DQpRMU0zWTBSSWJsVlJNV3hLVnpoSVdVRXllakpqWlZkcFUzUjBjelJLYmcwS1JsWmlSaXRuZFV0dWNERk1iazQ0VEZsYVdVdExSbmh3DQpOa0p0Ykd4b2VVcE5VbHBuU1RKaFQwVkJVRUZ0WVM5UlJVTlFOa3hSWXk5aVNtOWhEUXBxTDA1WlIxRnhhV2w0WjBGMlNtaHVaWHBSDQpUeTkzVlhrMUsxRmtZbmxVWjFGaldGRjVNa0Y2TjNRMWIybHpTMGd5TkRkb1FYUkNXbTFCV0U4TkNuRTVPVzFCUW5CaGJtNVlVVXBEDQpSMjQyUWl0RlRYUnFRbllyVUhaNWR6RlNNRU5hVW05NWJYQXljVXAwVTFBelRuRTFZV05pVVM5RldqaHdaUTBLTTFjdk1YRndlRVpEDQphMlZLVFRKVVoxVkRTSGR3TlRGdldIcEdaMll3TTFaa1Z6aFlVbXN5YUdnM2MxVTVjbmxXYW5JeEwyZFNjMlJ2SzI1WURRcHVWbGxMDQpTSFkzTWs5RFFreHljbHBsZUhCVlpVUnNPV0YxYTFoU0szWXJaVzh2VGxJNVFpc3JZbEo2ZW1adFpUSTBMMGhsUlhscFdHcExTbkVODQpDaTlRZUhKek1rdFJNRU5vUWpCSGFsSkdVVGsxU0VSVVNHTXhLMDkxVEcxcWRWY3hkMnAxWVVGTGFYRjNXVzV6YTBWcU5rVkxlVXRGDQpibFV4UlEwS1ZUWkdaRWhGU1RoNmNHUldTa0ZGT0ZoMmRreGxhbVVyVEc5dlozRkxkRkpETURkRWJ6aHVWak5UUTBOdFNHWlViVXdyDQpkMVI1TWtGVVpuTXhEUXBOUmxOcllUZExVbVpuTDAxb1kySkZjMHBhTDFGVGVEUlhkREpxVlZGcVJHMUZNVU5GZFU1S04wUTFjR0ZsDQpXQzgwZVVGNlpqTmpORGxSUnpJTkNtaE9jQzkwWWt4WmFsZ3dkVU5WYTFFcmVqWjROSEp0VUVkaWRURnVabGsxSzBSWk16WTJRVTVNDQpkbmRhUnpKbEsxSnpVelpITUZGUFQyUlpaUTBLUTBkeFRteHZRVEpDZG1zeVFrSlFRa1E1VUhFelVrRnFjR0UyWldOaVNuUkZWMUJODQpRbEY0VmpZMU9FOU9TV3BVZVZKTmJuSmxia2RpTDFRMURRcDZMMFV5UzBWTU5GcGlSazVNWm1OM1MxbDVVVVJ3VTBOV2NuTTJRMGhoDQpNR2xHVmpZM09EZDZTME5XVFVFNWJtNUJaRzlWY25WeWVsbHZjM0FOQ210YWJXZDZZWE5VWVhoU1QxVTBZbFV3WWxGVVdubFlSak5VDQpkbnBrYjJSeVIxSTFXRWxKZGpBd1VqbEdkblV5YldsMlNVZ3phRTVZWjNCcU9RMEtkSEJNVWsxTGVXTXZUMjVYVEVoTVlVaEhMMVkyDQpRazF5TXpBeVZTczJjRVppUzBka2JWRklTMmh0YkVwRVQxQlpWRmhQYUZKeWNGcEdRVzF0RFFwT04wdG1XRlJzY0VobEwxRTNXVU5KDQpORzB6UjFsTWNFOXZabkl5V0ZOQ1FVSndaV0phWW1WVFIzWTBkbk4zT1hRM1UwUkxSRmRpTjNKVU9Ua05Da2w0TWtoTU5uZE5iREl5DQplaXRtZGt0MVVWRnRkSE5WWlZoemRFeFZWVlZQZHpRMFdtcERSMWxuYlhJMGNFNHlWMWh3U2tkdWEyWjZVMDgyZWcwS1VXMVRPRE5UDQpTbVJSTVdWMmRtZFFVREo0U1doM01FeFJUMHR4YjNKUFFXVnZlRzVWUjJwMWEzWldiVkp4YTBGMlRVWmtRVzk0ZUhGYVVIQnJEUXBHDQpURWxVWVd4VWVEWmxNWGRUV1hKS2FHVkpRWFp5VnlzdlFtVnRSelpWYnl0d0sxbFNXamgzT0ZseGVrdEdXVVE0WjJSR04zcGFUSEJSDQpVbXdOQ25GTVJVOXJSSGxHWjJkVGFVbzBSV05tYW5oVWFFMUlNeTlOTjNOTmFEaFpiVE40TjNwTU4wWkNNSGw0ZEc5aWRtWnlVVUZKDQpVSGRzTWtjcll3MEtWbGhXWjJ0aldHRTVaVEZoYURGdE0xRnlabkV4VEVzeVRqZHpUbkpSVVZwb2NGcDFWRVk1VGs1eVNFWjJReTlDDQpXbFZ5ZFcxU1ZVTlBkbFE0RFFwMVpHOU9ORUpRVlUxMVltTmxZbWhJTDJOUWVrMTJWVFJGWWpaNlpHRjBORkIxY1haS2NtRmpSMmxWDQplUzg1ZFZKMWVFcGhTVWxaZUc5VldEZ05Da3QzVVZsWVVFVnFWazV3UVVwalRIbFBiMU5VVldVNFRFWXZOV3RLYTBSUlozQkxOMmhLDQpXWFU0VVRGQ1FXbGxRWFJxY1U1TGVFZE9NR1JSYncwS1RIbzNVMmszZUhJeFMxSkZRbFI2U0V4cGVXUkxWVUk0UXpWcVkzRkdVRXRUDQpkRGhTVjJoQlJraFRiRFJSUm5WRmQxbElOeXRFU1hGeFNuRlBEUW94VnpkTVRHbDVWMUpLUTNBNWVrZDZXbWMxVTBrd1lWRkNOREJpDQpVU3N5Y25OclkwdHZhWFI2Ym1oUFdHWlplbVpTVjJ4WlpGTTNZa05aYWtRTkNrZDNTMEpHUjA5V1ZHY3hlazh4Y0RWM1EyNVFVekpJDQpha2Q1VDFrd1lXVjVkVXhzZDBORmNuRTJiMVpWWjNaU2RGQTViVlZYVURSQk5IcGxVUTBLY0hVNGVXY3piMGN4UjJSck5FSkNUbGcwDQpaVzV1Ym5jNU5rcGhaR28zY0VwUVdXcEVjV2RwVURWU1V6Qk1hWE5pYXpCUE1tbHhlVVZrUlhOMURRcElkMUJIUld0bGEwOUZiMDh6DQpWVEJvYWs5MFYxZ3lWSEIzZG1JcmRXUjFTazlYV0VwVGFtNDVlRWxZYmxablVsaEtObkZDYkhWSWRHeHBaa3NOQ2xkek5XaFFTemhuDQpNMmhtY3pkT1JXTXlWVXBpZFU1UmQybFZia1EwTkdOamNHd3ZWRkJoUjFacVJtTXJaa2xRY0V4RFVrcEJWV2RMTm1FNGRRMEtXVXAzDQpLM3BEV1VSVmVXOTVaMVpLYUV0T1dWbHJhM0ZYY1c5NE5tbGpRVk5zYmpoMVNYbDJWbFIyY2tacVQyRTJTbEZrUW1aRksxRXphVUV3DQpEUXAwVlVObGMzQk9OVkpVVjFoR2VqUlFOV3hpTldsQk1GbDFUV0ZMVFhwMVQwaDBaSGRxWlhscGJIUlVZMUo0YzFOTFZUTlRRVzVGDQpiVFJWZEhrTkNtVklTV2RxVWxKRGVuWXpSMnhqVkRaWmNubGFhamRuU2xjNFJFRTRZbkJUYkU5bFYwNUNjaTh3TW1GblpqRm9LMGhJDQplVVZUTmsxamMyRXljQTBLYTFCTFVVSlRZVUZNTVdoV0wyNUdkRTVtVmxSQ1luVXdOakp5Y1dzd1RFWlRjWEJDWlZGWU4xSjRkRlpLDQpPVkI0WkdGUVZYQnlWMlpyU0RCUURRcE9TalZPVGpaREwwMXRlbE5MZWxvNWMyWmpaa3BOY0dka0wxWk9SVE14YW5wa2VEaFlRVUpyDQpjMGxtU0daT1ZWaEJSRU56V0RSSVQyMUhXRUlOQ21NeGVUVkJkSEY0UWpONlkxUjVNVUpTTDNrclptRTBTazR2ZWtVM1EwazBaV2RWDQpjR05XWmxaUFpIaHdPRTByU0UxUVRYUkVWVUZzY0ZwaU9RMEtjSGRVYTNwc2VFNU5SbEZ5WkVoeFdFWndOM2RHV1VZMlUwaERkVXBqDQpOa2RRVFRkaFR6TTRVRkFyWTAxdloxRXdZVkF4ZG14MVV6ZGtXV2RERFFvMk1YVkZLekkyWnl0SWFFZG9jR1pIUmxCcVlXNXlTelZODQpZelpwTms1WUwzUlhWR2h4ZGpoTk9FSjJUWGxVYlhnMmRIZFhXazlaTWxWU09VRU5DbFpFWkVSUGNpOHJXV3RYVFd0dU1rcFBOVk16DQpkVXMzTlZVNFZHdHdlSGxrZG1wU2NFdzNUQ3N4TkVOV1FtOUhVbEZoY1dOWVNWaFpUMkowVVEwS2FXc3hXVlp3Y1ZKRmIxZGxUMEpzDQpUemx1UjFKM1pGcEZhMVZVUTNWMVkzcE1hSGg0UmxWRlFVaE9SVVJtWWxZM1kzUjNSVTh4V1VabVRUVldEUW8wTkVGb2FEaEhTakpEDQpjMlZOWW1OQmF6VnpWVXhrZFZFeEwxRmxTbUpZUlhoVE5uTnlWa055YlZkMFkwTmpjWEoyUjNacU5qUmtOVTVKTjBRTkNrMWFaRUowDQpRbXRHVlc5aGFqRlBSRFZVYlhocVozRnNVSG8xZFVKQlptVklSa05CU1VKTmNFZ3ZiMFEwVm5JdlFVaGhWM2x3T0VadFkxQnZlQTBLDQphVmRVVDBaeGNWSjZhVUl4TjFjdlIwOUtOR2xHVjNaamFETTBhbHBCTkhGR2NXaG5URXR3TDBGSE5HZExiVlpyWmtsT1ZtZE1hek5DDQpjbVJGRFFwS1NrUkNLMGRPYms1NmNEbFdTRkl6WW1vMlZqWnNlRTFHWmxkTk1qWTJVV2h4YVdkWlpsaDRWblE0TUhkSlVETXdlakk1DQpNamgyTUVWTE1FTU5DbXRaYml0RGNqWjVkekV6Ums5MVkwTmlhVFZoWWpObGNqWk5WMnh5YkVJMU5YSnNNSGhqY2t4dldVTkxRME5rDQpaWEk0VVhkVFNXVkthVmx3TXcwS1kzcElSazFrTjNZeFZYRlRVakFyYlZSNE4zazJaMkpwVmxOWGJXMUVTMXBOZEhKSVVIRTJaRkF5DQpiak5EYkROM2NrY3lZMWxpVlZSd1RpdEhEUXBETkRCRGFVZHlXbmRDUzJVclVWRXlWV1pGYkdaUk5tOU1jMHhUZFRGbWVHTTNlazVsDQpZVUZVV2pWSmJsaFRjM0ZDY2s1UWJGWnRWbXBtYlc4TkNqQnBXbkU0WVVSS2MwWlJhM0JVV1ZKUEwzUktUWHB1UTFrM2RHSjNjWFozDQpXbEZTZW5OQmFtRnZhbHBDUm14RVlVSk5aR1l3WTNKWVZqRlNUZzBLVEZwbWJrZFNURE0yTWtGME5qQlBOeXRwV0RZdlNHeFVSVUkwDQpTR2x5YVZoa01ESjZTWFF4Vm1Sc2FGRmljSGRyVFd4VU1WaFFNVUZITW1vM0RRcFNSRGxIWWxsM2MyVkhSamRaZDFZelJXVTJSemh5DQpTMHRyTUZrdmJDOXRVWFp1UmpkR1JGWkVVMmxTWlVsd2VVNUhZVVZIU0ZKRWFXWldNWGdOQ2xOcGVFNWljVkpqWm1ORlVGY3ljSE5wDQplakozVUdwV1IwNXlObk0wTVc0NVZGZERPVVpWY1hoQ2FYVlFXSGRrYmxRMVJucFJUVzlpUkVocFV3MEtNbVpTY1U1YWRuRkdha293DQpibXh6ZVZGVWJqQlViVlJvTldGNWRYRjFTa2hUV1VsUVRXRk1XWGRaUVdadlJWRkJla3hFTjJ3ME5ESmlkRUlyRFFwcmJrWXZZUzh4DQpiVWQxTW5WMlEyVTFUemwwYzBWelNtTlVNVkp6ZUhCM1lteFdlVTV2V0RSRGQzSk9UalptUlRRNWVVRjRZV2d3WkdvdlFXVU5Dbk5YDQpNMjlyY1hKMVNXZHVkVzlqUjJRMldXODNZbGRQYlM5aVoxUkliRnBLV21GaVZWRllhV2RuVVVOV1ZGVjZibWN6YTNkbk9GRjNUMGxTDQpOUTBLUlRCM1VEQTNRbWxHUlZwdlExcGpaVkZ6VmtwTU1tVklkMU5MVFRoRU9IVlZiaTlIWXpNM2FXRlpNV1poTlcxd1VWZFpNbVppDQpOR0Z2VEVwQ0RRcHdiekF4U2xkSVFWcGlTRzlzYm1OdlJqRjFlRkppZEVNdlFrdFlhSGxSUzBoRFQzVkRjVU5yVkd3MWRUTjFWR2RJDQplVzFyWXpkUlJFeEhRVWtOQ2tnd1RuSjNaMDEzSzFBMk5rUXlRakkxWkVzNVpXOVBZbHBQU0U5SFRWTTNSbVIxVmxBdlpXNUNTVEJ6DQpaRFpqV1RrMlZFSnpLMU5ZYmpsbWRRMEtjVkJ3U2pkRFpuTkRkMnh1U0ZWbmVVbE9LMWNyWVZrelkwaEhVemhvTTBSbk5HOXJXRFZpDQpNVTU2Y0ZGdlkycGFaVXBOWkc5QmFIbDRhRFZzRFFwbFEwSTVLMk5EWW5kalF6TnRSbmhTYzNORmJXMVVOa05XVW5GMk5FVnFPV2xODQphRzV1SzNnelZESXZhREExT0U5c2NYUm5WRUZNTldKeGJrZ05DbmhPTnpGc1ZWVldPQ3RYZFZkTE1rRnFhVU5ZWlZkaVRTc3ZaRzl6DQphMFp1UTFFMGRGUmtlWFEwUzBObGIxaExkMmxtSzJoM01rWTBNV2hJY2cwS1lXcGpXRFZOVFRaMFpYZ3JLMEZ2T0RWSVNVbzBaREIwDQpOVGQwZDFWRFVrazJVVTh4VTFjNFNIVXJiakJzT1hONlUybDJaaXQyZDBsNmVVVjBEUXB2UTI1elVXMUlSbHAyWkZjME4wSlljRmxyDQplbHB6VTNSU2JuWlNSM05pUVZoRFRYUnNjR2R5TlVOaFIyOTNPREZPVW1kelowcEVXVVZTWm5BTkNuUm5hWGhCVTJSUE5XZGhhV3B3DQpZbmhvVEVOQmVGQkhSblpFZFZKR1NtVTRVVVo2V1dSclIxcEZOMXAxYjJNM1ZsQnBSbEpRWmxGVk5WRllNdzBLWldobk9GUmphV1pGDQpURmRJVVZBMGR6Tm1TWEpTV1hkS2JGUkNNM2Q2ZW5oTVFYSXpUWEZxZVVoa1ZVeFZkelI2VkdJd1VWcE9iMWRMSzBOUERRcFBNVkJGDQpWVFIzTTFoQk9YQXpSMEpFYVZSdFEyZzVjM052ZHpOcmExbEJZekZqYjNaRVNIcFNUR2xOWnpWb0t6bDFLM1VyUjIxdE5sZzNPR01ODQpDa3Q0YW5veGNXNWhhRU5qY1dSbWNHaHhSRlJEVm5WV1dsWkxjMVY2VGxWd056Tmpla0psT0dGNWJreHdOUzlLU0hGcVJtVmxlbGRJDQpabGhMTmcwS1NVbDZUME5KV2psMlYxWkVUbWRPUVdGR1dERXlXbXh2WlhCTWNFSjBTMVpNUzJsMk5YQnlSWFZETlRSelVsUmtTbnBJDQpXREIyVWt0NE16SlJEUXBIV0hKeU1HaFlRMUJFVmxKM1NHMHdUbmd4UTBkT2JGcFdWVU15WjJ4bFptcHZiR3BpZDJGYVVtbDRNME4xDQpZVWh1TW5oaFdWVlNSMnRUTUZJTkNuUTNha3BTY0hGdFlVZDBSMGQxY25rdlQzaG9aMDFUVlhWRU1GWXZMMkpXY2l0b2FtSTFMMG92DQpjVmhOTjBwSlMxVXhjSGg2YkZacmREZ3pVdzBLTVRSQ1VubHliWEo2U0doSWVIbGFXVEYxUldKNlJ5OVlaMmRNYjNabWRtUm1TblphDQpOek5KVEZSaGNtOXRabUpsYWpWNGJYbHNWVUpsUkhwdkRRcFpVaTlWWm1waVdqaFBhVVFyS3pocU1tZGtlRFZ4VjNKSk5uVlRORzVVDQpWMkZrV1doQmJuVmlPWE5QZWprek9WcEhSbUpzVm1sd2RGWTNRMUVOQ2pGdmQweE1XWEpDUmpVMFR6VjZWWGMyY0ZOV1dFczVXa2R0DQphMGhoYTJzeU1qbE1PVGhrTTJOWU4zWTNjV2hrZDNoQmFXdEpSMU5UZVc1Q2N3MEtWekpETm1GMWJEQjBjV2xJTjBWcE0zaHFkWGgwDQplRGhaU2pCdWEwTjZLekZ1YVhwVWMyOXhObHB2Ym1aamJGbHhOVWhOZFhoRWRtTnRSVFpxRFFvMFZGRkJjemswV1UxS2RHaHdNakZDDQpOMnR3WW5kSmRDOUdSR3RPUjNFeWJGcFRNbEppUkV0b01VSldNWHAyWldoYWNIUnZWR1JoTWtwTE1FVU5Da3BMV1RRdmRDc3paSHB2DQpNMkpqTVM4d1RIbGpVbUZtWTBwb2RVTjZaa1pxYVdsWWNEaG5UbEE0TXpOamJYQldhbEk0UldsTk9HUklVRXMyWXcwS2J6UkZkRlZyDQpNU3RLUzAxUmRIaE9NVmRHYTFCRVRGQTRPRmR2VjBoM2J6YzRjRkV2ZGs1T09XVmhkV3BQVjNoMWVtMU5jMGsxVVhkSU1WVXlEUW8xDQpZV0ZyVjFVeFRsZGxiRTlqV2t0S1NWWjNhSEJsY0hwSWNURkVRVlJaZDFjMGNHcFBabkZxV21ocVNXcFZjRUZWTjNGSWFpczRPR1pUDQpUMGtOQ200cmVIcDBhV051YjBoNmRHTlNjWFJWVVhvMVNGWTJXWE5oZG5nM1VrcElUMUpEVG1aR1pHSlBWSFJhTlhoUlRXdDRkM2x1DQpTSFF2VG1kTlVBMEtiVFJWV1M5MVdteHBUMVExWW1GSmVHUm1ka0ZqUlZaM01pODRWSEl3WlZSU05ISlFaRXBCVmxsRUwyNTNVR2xFDQpOREk0TlRFMFExaFhXRlJpRFFwUlZHRmFZbEZCTDJoMWRXSnFaemszZEdVMFVHVkVRalk0TXl0SVlscDRNM05MYUZWNGNGWndUQ3RuDQpNMHRQWTNKc2VEQnhkMk14WWpnMFpsb05DbEY1WWxWSk1TOUhSMHN5UlVSSWVWaGFhVTVIVmpVMVVWZFpTREJTWmxCc1QwRkJNVWMwDQpRV1pDT0d0Q0wxSTRVVVZOUzBWeFFsSkZObVpxWmcwS05IaG1iR1pHU0hGeVIxTXdNbGcyZW1acFlWRm1ZbWxCTkVKdFZXOWlURTV5DQpVemt4U2xFdmMyNU5jazUxY1ZVcmNtUkJUMmhNVFNzNGJFb3dEUXB2WmxoRlduWldiVzlSWlZONFpsRk1kMnhaTnpCUVZWRkphR0l2DQpPVTV6VFVSdlRYTkplazE2ZW5WalUxWm9SVGwwWVVkQ1lXNW5PSGwzVjFBTkNuQTVibU5ZUlV0Q2FHcEhaMVV6U3pKbFdqVndlRzVhDQpSUzl0VDI1TmExaE5hbEZyTW1OQldWaHpjSEJEUW0wdldrZFlhbGxpWTBaR2EwMXNlUTBLUzNRd2MxTkpjSFZ4YUdOME1XVXJOR293DQphVTlIZDFOWkwxZFNRV2huZDJNMmQyeEthU3QwYUZsc1MwTjNWazVpTVd4T1dFZFZXbVprWTJGT0RRcHRkRWxIWlhNMWNrTXhVa3A0DQpSMnhHWTAxaFIySmljV05ZTUZWV05XUnlSVkJ4ZWxaTlIySkpSWEJaYlVkclNFbGxTa2NyT0VnemMxcDVURm9OQ2tGclprUk5kRTlxDQpiVXR4UjFFM1l5OW1SWFJtVTJOcWNHbHBkV2h5YVVaQ1pEQlNiRGRHTjFsWWVrSXJjbkJGYUhKMVUyTkliMnczYkhac1JnMEtiMlJ1DQpNVUZTY205dFoyMTZhbFJzVUV0elZWZGhZbFk1U0dWVFdVZFBhRWRqTlVsR2EyNHJORXBXYWtwd1NFRnhhMWxqY1ZZMkwxUjVaakpEDQpEUXBLTlZCaU56YzFXREpPVEZoVmNVcENlakZaV1c1YVdYbHFNMU5pVkdSbWNEQllVMUpWV2xJcmJXWnpSVmxNUWs0M1J6QTRNbEJWDQpMekpyYzJnTkNrSTJLM2xQSzBkaGRVRk1iMjFVTkVGNVlVRm1OSFEyVkRGV09ETm5VVEJSUzFCbmJIRlJiSGRpV2tGV0sybGhPRFpUDQpRMlpZVGpSVlQyTnVSZzBLTkhGRFpFdGxWVXRwY1ZndmRETkxUMVpqYVRreldFRXJVVUpKVFdRMGVYbHRWbXBwWVVSblNtUlBUVXBLDQphazlTYzFKVk0xaDVhblZrV0VjM0RRcFRVMU4wTTFjd0t6QXdUMjVKWkdrMmVHUTVUVEpIY0U0clUyeG9OMHRGYkZwWE0yazRZblJRDQpTVTVQVTBGVVJuVXhTSGhSV1hCaFJUaFBlRVVOQ2pabmNITjVRVTlrUkhweWVIUkNaalpwUlhKV0szVjBlamszZDNnclVrdE9LekpQDQpOVWxEZFVsNGMydDNUWGhCV1VOTk5UQnhhM2g2VlRSbVRnMEtlRTVUVVRkamJEUm5TWHBVVVVOVGRIaE5OMjlZVGpKT2VEazNSMkUyDQpka2hCY21wRU5sTTJiRkJUTVU1TlRYa3ZVMW95ZVZrNU9HTXZPRU5NRFFvdldIZFVTaXRTYWpWcUwweGhaa1pUTjFrMWIzZzBVMkphDQpTMjlDVTNaWGVVRkxjVllyTDNsQlUyY3JjalV5Wmt3d2R6RTRZbk5tZURacFNFWU5Da0pWVWpSYVZFRlFOWE5tYTBZd1MxRkVjSE4yDQpTak14V2tsS1kxcG9Ta2x5Ykd0bFkxSlBaRFZWU1VRNGVuaEJRVFUyVjFrNE1XRlJWak0yT1EwS1drbFBVREJKZVROSWFHWkpZM0JNDQpjbGR2UVZwNFIwcEdURzQwVlZOelEwNXpla3RaUzFkS1lrSlFVVEpOYjNBd2FqYzFaRmQ2TjBSeFlUUTBEUW80VkVjeVVHdE9ZWEpPDQpSRGR3TVc5eFlWSmpVMHQyZUN0M1pucEJlR3RJTkUxSUx5OUNUVE5uZERCb1RtdHJVU3RvU2t0QlRYTjJiek4xYTJ3TkNqVXdURGRzDQplbVp1U0ZwdFIycEJZWG80T1hWd1VsTm5RWEozTDA5WFpEQnViamxGWlUxVVVVaDJUakJZYm1oaFZWWXhjeXRGWmtsSVozRllkUTBLDQpWalZUUW5wVFRuQkJiMHhNVjJjckx6aG1kVXQ2ZUhCcWRtTjRRa0pMWVc0NE4zSmFUa2c1YVc5NlNFMDJhWGN6WkZadldHbG5RMHRpDQpSekZZRFFvMlpIWnpVakJsTTBKMmFXcEVOVnB6Vmtoa2RVSmxVVXM1Tm1KaVduZFplVmwzZUdRelozcFFZMWRZVlhRM1ZFOTFieXRCDQplRzF6V1V0c2RHd05DbGh1YldSRFozbHNOWGxxY213M1VtVjJSMlJ5T0ZOVk1XczBWemN2WTFGVFp6SjVORlJqVjJWME9Ea3dka1ZIDQpXVWRQTkZWemFUUnFPVlo1VkEwS1pVbFhlV2xhVGxseVRsQlpUWFJDV0RSU2JtcFlUR05yU0dkYUwycGtiVXB1WjNjNFRrZFFWR0pYDQpjMU5VVUdKVE5WQnZaM1IzVDNwVWNWQjVEUXBxZEhOR1JIaExXRUV4YUdKbk1FaFRVelZUTVdwWE1YaEhUa3RhUTNWU09FaE9SMVJXDQplVUpyWTB0WWREUnhaVGhJWVhoVGFIbHVWM05zVkZnTkNrMXBaMFJEY21vNGExRnBkMFZHTmtsb1ExcERabWRKVURoWVQwTnJiSEJEDQpkV1ZRUkZjMldYaDZjSGhLY1M5NVVVRk5VbUZxV2tSRU1sSm1ZUTBLUldKck0wZGxNbm9yY0RKRFlWZEhORTVMV2xkeFF6UXZSRUU1DQpVVkJtZURFemJsaE1NbWRzTld0RE1VeDRXV3AzSzNZeFJtNU9hV3hyUmpCSURRcHhPVGx5V0VkM1VuaHpUamcyUVVoSVZYVTBNbmd2DQpNMHRDYjJrMVJreEtNblZhVlRRMVNqWnlZWFpoVEZSUFdraHpjMnQwTDNWWGRFUnVWMkVOQ25KWmEwMVFWbVJoVm5kck0xQlljVXh6DQpVREpWVFZOMVpqbHhLeXRhWkVwa1JWZFJZa04zV1VKM1J6SkVUVmhvV1VaUEwzaFFka3REZW5wS05RMEtlR1ZoVjBZNFVtdFdURTV5DQpSM1IzY1ZobFkweGFXVzF1WmpkdGJGbElhbVJHUmk4d2FHSlhZa2hDV0U5aVRuVmlSRVpwTm1aa05XOUthek4yRFFvd1IyZG1hVUl4DQpNVmQ2V0RoRGJFcDRhMjFNUm1ObFVHOXZRMWRhUW1sT1ExRnJUVWR5VG5OcGNsb3pVR2RTWkdWVU5EWkZXVkpXZUdOR2IzUU5Dbk0wDQpUM2c1Tm5aaU1YcFRRbU5zZW5GNFQxZHNlR2x6VWtNcmFUbFBZWFl4TUcxVFVtNWlOVzVGU25FMWMwNVNNWFE0UlVka2MwRlRSM2hCDQpPUTBLYTJKbVdGQmhNREJpYUdwelZsQlFRVkJsYTNWQ2FFaFpkVUZaTldSb00yNUJlR2N5VmtkYWIzTmFRa0ZzTkhGTlNuQnBTblozDQpNMGw2T1VseURRcHBSVTlUYnpORFJHTlpPRXQ0YVZoVGRuWk1ZakYwUTBSNVpVOUtZM2N6VW5GQ1pGTm1jV3hWWXpRMVJqQm5RMkZ5DQpORkU0TlVKUk1UZFBPVmtOQ25vMU9HbHdPRTVzVGtZd05rUlNWVlJrVkhoQ2FrVmlXRXRVTkZKYWVtVnFOa2hCV0dOd05FdEZXVEJTDQpXRWg1U21WNFltVjJkek16VVd0UGR3MEtkR0ZITTJkM05GZHNheXN5VWxOUWVXRjZUVTFIZGxCNldEZDZUVlkyVFVGcVptMVdaM1JODQpOMFYxTUdNeVUycEllWGRTT0dWdVNXMHlSbmRGRFFwTE1sWm1kVk5zWnpaelRra3ZhM2Q0Y1RSelZqRllRbmRZVURJeGNtaDRZbHA1DQpVVzg1WW5GaFFXMVZhVnBoYWtnMEwyVnFjemxIT1RGNlJFc05DbmQwV2tsNllqQXZSMmt3Y0U0NGExSTViRXRrYkc5MVVtdDRNVGc1DQpUbVpZTjI1eGJDdDFhMFZOV21FM1MwNVRlVk5wVFVSQmFuaEdhRzF1THcwS09VVkdlaTl1Y201eU5qaE9PVVZoYWxKalVEUTRjR1pTDQpNRkZtYjI1T01ESkRiRnBaV25od1FXZEhiQzl0YUhwc1F6ZHBMMUZ3S3pKWlJGSm1EUXBWWmxKMWRTOUVaME4xVERsRGVVSlJSVGh6DQpTMDh2WjFGemFXSjVhamc1ZFZNMlVYZ3ZURUZuVWpKeGJUWlBXRk5hTUhKS1YxY3phWEUwTm5NTkNqbDNlbGQyYjNCUVVEVmljVEF6DQpOa1pLUjNSMmQyOUtRVUprTkM5cFVVUktTSGd6VFhac1EwSlRWbXRTVlZGdVdHazRkRGRVTUVOcmNYTk5XUTBLY1RFM1FscFlVbkZIDQpVbUphVWxaTmFWVlFRVk5QWlV4a01EaHVSM2QzTkhSRVlTdENRa1p4UlhaM055OWpRbUZMY0RoU1FUSnNNVXBHU3pocERRbzVVSGMzDQpOMnRJUVZwR2RHNDBhVGhaYlcxbFZHdHVjSFU1ZGxnemNYcE9kMllyU0doTGExWXlZWEIxVEZsblZUZHpXV3hxUlc4NU4zSjRaR0lODQpDamRVY3pnM0szVXZhREJpVnpCNVZGTlNObUkzYjNnMk5HNUZaM2hsU1RKSlZGbEhPRFpVTmpVdmFUWXhiR1ZzWmpsME5GQTNNMFpLDQphVVJSUkEwS2FtSjRRMFIyVVhWdlRuVkxWbTFPWmtaWVZXNUtVbU5uVW5sWk5GZGtVbmRKTTBWT1UzcGljazU2YVRGclZIZFpOVkpaDQpiVll2YW5ac01FOW5EUW93TDA4emVrUjJiVXhGUlRGWGNrcEZaMWhUTVRRMlowTlJXVUo2WVV4WFRtMURkVzl6U1dOMFNsRkRNRVJqDQplbEIwVGtoWk1IaGFUblF2Y0hRTkNrVmFXbWw2YkU0MllrbzRUR3cwV1c5d2VIRm9Oa0p2ZUZvekx5OVBPVEl6TUZKVGJVWlliRTlLDQpjM1JZU0dFeFNsUk1OSEVyYm5GcllYaERTQTBLTlVKa0swZGxTRmxLV1N0RWJYcGhaR014ZG05Uk9HazRXRGRaVldrNFZGUkhkREYxDQpSRTVOVVhSUlkxVTVlalZXZFRoVFlWcDRZV3RVY0ZBMERRcDZRME5aSzJOUE9XMHhPRmhSVEdnNVEzSjNNWFpzY20xTE0xbFhTRVpPDQplVk5wV0ZsV1ZFZzVObTByVEdoWE0yeEpLemt5UTNkV2VIa3ZaR3dOQ25KWlJqaFhaelZQVFdRM2MyNTNWRllyTkhsNVRDdHBTR012DQpka2swT1ZBNFdWZEJVRkpGTW5OdmNVVklMMVp3U0hVMmFVeFVja3N4Y1ZwU2NRMEtiVWhKTDBaME9Xa3pjRTl4YW1kaWEyWkxiMVpEDQpNRFZvZWxsU1dESnFhMHRZVVhscmNYQjJhVTU0UkV4cWR6UjFSSFp0V0VsbWVuRnphMWhURFFwMmFURTBSRmhGVjJsWFExQnhheTlhDQpMM2szYmxwTFIzTklaSFJCU0ZVNVJXNDJRV1prWkVScE0zUmhWMUEyYjJsNWJtRlJhMDFGVlhoRVJrY05DbFF3ZVZScGVGQmpRV2t5DQpOa3RZY2t3NVpVVmxSMUJaVGpGclVYQnpNelpVUmxWT2FrOUZZVE4yUzBSMlEzSkpPVUZ0WVhwV00yUjJjRTFvTmcwS2FXRlpVWEpIDQpNVXhySzBGVVR6Qm9NVVp3WjB4VlRrdDZXVXQ1VXl0NUwwOXZWMHg2TTBaTEswZE1iV1ZxYlhOSVdEWkRNMWg2V2xoVWFrZGFEUXBIDQpNVFJaZDFReU1qSllUbWh3U2tzclJWRllZVFYyZVVOdlMwOVlVbEZsZVVkWVp6Vk9iblpGWVd0V1pqQXhXak16Y1dGMWExcHZNVGRTDQpkemdOQ2s1VFF6VnJURE5GY3k5T2VqaHFXVE5EV2xsQk56ZEJSMjAyYVRWd1owTkZabUZLTUVGek9IRkxkMUpEY1RSQllYVmpaSFEwDQpTRFpPY1drME9BMEtObmQzZW5OTmN6UlVLMEkxTnpaSWVHSlJaVWwzY3pGeGJGTnJTMjVKVWt4dGEyMXBkV2czTDNOTGFDOUZlbk4wDQpTbFJJWnpOV2JtcHpiQzluRFFwRFltUlJOM00wTlU4eU1VeFVNREJyYWpOVVExWklURVJsWlU1T1ZuRkNObFJYUkdwUk5ERlJkMWRWDQplbmQwYVV4aGIxQm1jelZrZUVONU1tOE5DbWh4U0N0VGF6SXphSE5aUW1veFNqUlZLekZFTXpFNGJGaFlhVkZDTUdGYVlXNWlRbWhIDQphMlJGTUhGb2FUVkVVeTgyYzJoUVEwaE1jVWRLTmcwS1RYQjNkV2RTT1ZkUFN6ZHBjV1ZtT0dsSWFrY3JSVXRQUkhsTlNWUnFWVmszDQpXVzVNZWtObk56QTFPREJwY1VNM1RsWkxUMDlET0d4Mk5ubHJEUXBPWjFKWU5GVk5NMVJvVFRSYVVUWlFkSEpsVm1oRFZXVm1hblpGDQpXVTVxTjFCUlFVeEdhMW81TUZKS2NscGtUVmhPUW1WdlduQndlRmxyVjJZTkNuRXlWbmhFUXpSNVkwRTVObGRGWTNwaU1FMTVTbU5IDQphR2RaYXpGek55OUxSakJrUjFkQlVrNDBiM0p3TDFwSVVsTjRUa0UwT0cxMWFHUXlRdzBLWlRCUFJtNUZXVkFyZURRdk0yeDFjMXB2DQpXRTA0Um10WGVpdElRelZUZEROWU5tOUtOa3RKV1hwSGNsVlBPSGhOUldSWlFuSnRkR1poVjJwcURRcG1TM3B4VFZOYU5YaFRPVTh4DQplQzlGWTJWU2FHVjJlalJ0YzFCblNUaHhWSGg1WkZremVXTXZOVkUzTlZOU1JrUllZM0pVVDNaMU9VUXlNR1FOQ2xkWlRHaGxVVEExDQplbEJKVDA1cVZ6UlFUaTlKZDJ4cGEyZ3ljazFKVGtoQlFXMWlaRWxGYjBseFdXbHlVbkkxTWxobFlpdGxaMlowYTNwNk53MEtVekIyDQpjak5XYWxkR1Uwd3ZPSFF6TlZBMFdqTjFVRFJHZVRsMGFuVjBlVlpUT1VZd2Qyb3dhbEZpSzBvMmIxUnBMMEZ0VEdjMmNscFFXV2RYDQpEUXBNVW5CNlJHeG9jRlEwTDBkTGIzUTFOSEpIY1RBNE4zaGtaRnBOUkd0eVlXZzNRekJ1V0RaYU1IUmlTSFpaZW1GUldUUmxia3hCDQpZWGswUjBFTkNtNW5kVVpVTlN0bUwxaFhWR3hMVlhJeGRtWTBiVGRGVFZOc1dqUmthRFJKYjBwMVJDOHJUalZ3WkdwdFJIbHRkbUZ4DQpaM1phWkU4MVVHMDRWQTBLV0dseVNrNTZTRGhUT0dnM1NUZEhWbkJQUVRKbFUzRmtUbkJXU1cxTWVUZGhXWGhyTW5wek9EaEpWMnAxDQpWWGhWV1cwNUsySlZlV3BUYmtVNERRbzJaRFI1VGt0VE5VeGpaakJ2UVd4bWFucElNbFZEWjFWaVJtNXZjSHBPVW1kR1VVTXdPRnBJDQpiek5SVFZvMmVUTXJPV3BUWW1WRFdEZGFLemdOQ21oYWEwdHJVVkpITjNsUlEzQlhZMWhqWkdOa2NXRjJlV1ZXUW5CTVduRXpPWFZ2DQpTamxGYUVKalpsTXlMMFJHUkZkcFpucG1VRTVKVTAxSVNnMEtRMlYyYlRGa2NYVlBVbTlqYldzeE5pOU9aRVF2UVVNMGJrRXZXSGczDQphRkJvYzFoSWVXeFdOR3BLWVRjMFRtaEpkM2czYjFaNWRqQlhWSGxMRFFwaE1VaFpRMDlEWjFaMlZ6Vm9UMkkzZWxablJrOVNVekJHDQpSekl5TmxKbk5GcDFOVEZZV1VRNU4yMWpiMFl2VjJvdlUwa3libXRaTVdkR2RrNE5DakJ6UVZCaE1ERldlazA0YkZweVRrNXRjMmsxDQpWMVJTYTFKU1dHSlBXRTAwZDJGSE1VUnVOWEZPY0VKU1pWWlNkbVphWjNjNWRrSTVkMmxVU0EwS1dqTjZlR2hTWXpWSE0xbERNV0phDQpjRFJ3YjA1bFUxWmxNMFpYYTJ4U05GcDNWazVJZGxoMFV5OXVla0pLY0VSYWMyNVpXREo2U25SRFl6bG5EUXBXZURGQ1VuTlFUbk5xDQpkMDlKUlVkaVIwVllVWFJ4WW1WUlNsTm1MMXBSTjJWNlpqWkZlazFFWm1JNFpuRnVaelZ1VFUxM2JrWldkbTF1VDBzTkNtczRZMVZ0DQpURzlZVkhkQ1JHNTRNRW80WlVGNmEyUk1XbVpNV0ZOR1prZENhSGRHU0VSUU4zRmhaVVJOUWtWamVsWXZUa1YzY2xSR01XbFpkdzBLDQpNREZPUXk5Sk5HTTBZMGQyZEhveU1tOWhTekZyT1VwdldFOTJiWHBFT0Rjck9GQTFjRzFXTlVSVGVGVllORXhoUWxJMk1qZHJOR0ZJDQpRWE5IRFFvd01IWlViRzh5TUU1YU5ITkhTbTk0Tm5CWVRYQlVhbTh3VEdabFZ6bERaeTlzWm5Fck1rWjJSMnh5TkRCdlZXSTRUbXhzDQpVRXB0WTB0MlRTOE5Da1ZqUmtaeGNrRkNXRFJpWkVkRVRUQXJORGQzYW5kaGMweHRUVmRzSzJsWmRXRmxibTlMU0VKNmMxaDNSRk52DQpWMHBoZFVSTFdXcDJZVzlQU0EwS1FsQnhiUzkxYldkcmFubEpLelppVUdod0x6UTFOVGxxZEhKb1VEZzVZak5tVlRWeVpVWk5jbkUzDQpPVkl6VFVadVkzZzRWV2RpYVZoaFdGcE1EUXBsVDA0M09UWXhPRFZvZFVWQk1XUnhiMlZyYkd4dWF6Um5kbXh2VXpWNVEyaE5aRGc1DQpVR2xuVEN0SVRtdDJWSHBuUlRCaGJURkdRMjFDV0UwTkNuaENZbGQ2T0ZOQlVFVklTbWsyU2pKeVVWZHdXa2wyTTNKMFVXRm9kMjF2DQpkSEl2VUhKbE1qbGpWVlY2YURnM1dYRkNVeXRJTkhKQmMyUnRPUTBLZUc5RVZFOUJNVkIxUmpsTlQweHVhemxvZFhOM2FXMW9lVVpUDQpaVEE1ZFRaTVpHVkxkME53ZDBrMlMwOVNjRTgyWjBGbmEzQnlSV1ZVTTFWc0RRcFdSVUo0VWxOSldVbENhMkowVkdSQ1NXaGtaREZyDQpObWRhYVU4emFWVTBSbkpRY21KdGJucFZZMUpxYVhFMmVTOW1ORlF5YTNKTmVWWjJjMFVOQ2pKYWVWbDNNMVZyUW1kWGVXdFBlV2hDDQpUMFEzZGpGNWNrWmpjV3hDZWxKTFdFNXJXRzFZWkdoSVpWaHVORmtyTkdzck0yWXhUVkV4YWs5S0t3MEtRMjF6SzNWYWNWaEJkRXhQDQpTRGx2UTJ4WksyNVpWVFJEVTBJMldrNWljbHB5YTNGQk1HaExMM0Y1VG1od1MxZDRiQzg0YlRKSFF6aGpha0UxRFFwNWNWZFBOVWRMDQplRkZSTUVjeFVFVmpUR2R3UkZOMFltMDNWbGRFTVd4bWQyOVhZMVJSVlRJd1QxUldkako0UlZGVGNrVlZZa3RuUTBORVZpOE5DbmxUDQpZbXN5ZFdkSmFIbERRbmt4WVZBMk1XSlNRVXNyZFN0RGFsUjRjVXgzT0dabWRXdHFRblkzYW5GdlVIWndPSGxoYldob2EyOXJWbFp4DQpWUTBLTWtocVNGbHhXWEJETVhWelRtNDJlbEIzZERCNVNUYzBaVGd2VkhsU01ucExOa05HV0ZkaU15OVVkRmwzVlhGTmVIaGxRVGxJDQpjMmhETkVSekRRcHZSbWgxZVVoU2MwVkhjMkk0Ym1aU1NrdDJUMFpwVlZCaE1USnBTREJNVm5WNFNsaDFNa3hPZWpGWVRrWnlka2RKDQpXRVpNVW5sSFdIbHNNbE1OQ25aeU9EUTBaMHh2YzNrMk9IWklUMlJ5TkZOdFZHeDRZa3BUZGsxWlkwdHpRbEYyYkc5T0x6UnpibFJ6DQpMemRqZFZoSk5URjNiWEZVYzFFMlZBMEtXVEZYVW0xeWVXVXplSFZVWnpSdE9GVnRTM1pXYjNOWWNFTlVaelpXUlM5bVEzQXlaR1ZQDQpkMlpJTlhWNFNqZE1WbTB2TkZoYVJIaDJkREZaRFFwTlpsbHlhbll2YlZkYVdXMVdRV05UYTJoTVJWRTBaMFkzUkdadWJVeFhMM1JEDQpUR2RvZFdGUVVtMDNheTh2UW1aUVVWaHhkblp6VDJkbmIxUU5DbEJMYms1Q09XVkVTbm95V2sxVldUTXlablZPUjB4RmNFNW1kV3BUDQpSM1pEVTFSMWVVb3JNM2cxVTBWdmFWSjJiM2xTUzJjMEwyZHBkWE13TlEwS1ZGRm5NalJRVjJWcVMwZGhOVkY0WTNwVFZGY3Zaa1IzDQpUMmRDY25Kd1VIWkhWVGgzU21abmRHWktSQzh6WWxwdFVVTjZkMVpzUkc0MlpIUkREUXB3VTNkamRGQjFOamR0UTJwMlZHaGpkbUZxDQpXVkZZZG5ZcmFqYzRRVFpHWkdRd1FrUmlXSFZzZFhGT2NEaHJOV1F5TkZCcmEyODJabkJ3Um1RTkNsWjZaVlpMYWpCUldERm9hRE5qDQpSV1JHYVhCUmJtUXJOVE4xT1VVd1MwVXlTMGhTYmpjM1JTdG5hSEZUVkVaT2EwNUxTa1JMY0ZkeGNtcG1XQTBLVTNjNVR6VmhZVlowDQpNM2Q0WVRSNVUyMXFTMUpXZEhsT05UQjVRMUUzYTAxRVoyaHljMnBMZG5GS2JqUmFkVmxXZVRoYVZXbGFPRFppYzNkTkRRcDBVbU5IDQpkVVJ2V0VGYVNuTnNUVE51ZEZoUlRVbzNiaXR1Y3pKNlFVb3lNbGh1WjJsVFVGTlhTR1ZtUldkdmNXNVVkRkI1Wm5sV2NUaGljVWNODQpDbU5LVm1aaFl6VjFkek5aVFdRclNuRktjVlJyV1VOaGNEVjBkVTkzY3pONldDdHhRVWhSV1N0SWRrTXJaV2hvTldKc2FIQjRjRkZKDQphWEIzTWcwS2F6bE5WVmQzVDFkWE9XdHBRMVIwWmtObFpHUlpNREpMUWpsbFRFTnlkMkZrVTFSd2VrdDVOVEJ6V0V0bmRtb3ZVVlprDQpkMnBtVm5wM1F6aEtEUW93VFdSeVlrRjRXRUlyT0Zvd2RtVkVWR3BLVTNoRFdEZERhMlZRVG1Kd1VEaFBZemc0V21aUWVqbEZRbHBzDQpkVXA2TUZreGVVOU1XR2MxWW5RTkNrTnZXSFkzVjJsWVZ6QmpjMnRsT1V0dGJtcHlTSFpzY3pOV1MycGFUWEpxTjBKdWJ6Z3JjM0ExDQpSalptVG5reFR5dE5UbXhxUW05cU1FUXJXQTBLUkVSMWVUZzBWV0Z5ZDFoWGQzTTRXREZ5TDFSUGJXODRhQ3N2VDFJMkswWkNiWE5VDQpPR2hIWlVwTlpsbFVVekV6VlZCWU56bGhOMFZUUlRsaERRcHFNblZQTmtzNVVXc3JVamx3VmtoTVpVOVlSWHBEYVhwTmJrRjBOemg0DQpSQzltY0VKbWRuUklibW81TVdkU2FIZEtWVUpHTlhkaFNEVlNlbU1OQ210dEwweHhNbXBMVFVGT1RXUlNSM1J2Y0ZWa1VXeDJUbVJzDQpVbGxIY1ZOUWRVOUlVVFJQZGxCMllrMXZjUzgyTlZsTmRGZzJhbFJIVmpsTmFRMEtTRTV1UldoMFJGSkdla2hOTVROdkwzRXZiREpzDQpTbTlLWWtGak9IRnJaMnBzV2xsV2NVWlVka1JIWmpOcE0xb3daSGxIWkRadWRXWlNaWHA2RFFwaFFrWkZTV2xhV0d0dk9FVmllbTlVDQplbHBRWlc5VVdVMXJiRXRUZVRnd2EydE1TM3BVYVZwQ1EyNXpSR2xFVEhoYWFIWnlia3R1U1dGNWRrWU5DalExZWxkR1NVaFJiVXhCDQpXVWhVUVRoT1psbHJRVnBQV1VSelZ6bE1WVWdyZDJKNk9ESlVRemhVTkZneVUxTjJTR05LWkZvMlZrTXJiRWd5TUEwS1NqSTFWbXBTDQpZMXBJVW1sd1pXOXVkazVyVnpCcldVdFZRazV6THpaSVUxUjJRVmc0V1dKWVZIbGlTVmRsUTFWS2IzZFhkemw1YldSRGFqVlBEUXBuDQplSFU0U0hkaU9FTkJWMGxUT1dad1lrbFlkR2g0VjFRMFNtMHhSV0Z2V2toU2VUYzFVVWxZV0hjeE1XaHFlU3RzTW1oa1VIbHdlV051DQpRVk1OQ2tSQ1N5dHNLMkZJVDJwU1NHdzRTVWMyYkd0UmR6Z3ZPV2hXTHl0RE4wVlFWalZxZDFacVUzcEZUa2hTTm5Zell6VkhkSEV5DQpUMU0zYkVseVJBMEtRbXBpZG05RlEzTmhhalJSZGtkTGRVSnRWSGhXUVVVelRVcHlibmxhTlRCNlJFWXljMEZXY0dVM1p6ZFBXbFYzDQpPWGRaV0Rrd2MyMXNLM0ZtRFFwT2EyNVRjRmxrTkd4dk9ETlpiSGN3TVdWMVlVNUpXbk13UW1WUU9UbGhPVzFzVEVGRldUaEdiME40DQpSMkpXVG05dVV5OHZSVUpUYm0xRFNtb05DbU5FY1hVeU0weHJVMWhUTlVoUWEyOHhlRFF4TkRaUVFXSnpia1p0Um1nd01HcDNTMjl4DQpVU3RzVFhOc2IwdHlkMmhvVW5CRFJsQkJNMjlqUVEwS2FuRnFhSHBqZWpCSU1HMWpTME5RUlVKcllXY3dOVUpxWkU5VVJ6ZEhhMmgwDQpXRWNyU2xGVlExaFlXV3B2YnpGdldIVnNVMGhXVm5Kd0wzRnpEUXByYmtrd1ZucHJMM1ZhUWxwTE9XTTRWSGwzUVc5TmIwMDRNak12DQpWbWhTYzB4cFUyeGFjbEIxV1VaWFVVY3hPVEYyYURKUU1XSk9RbmRGWm5nTkNsTk9ZalJ4ZGpVelUyMXlibUptYm5JdmMwVmpjVmhGDQpVa2hFVVd4alFUTkdRV1V3YWpKc1JqTnFaa1kzWmpnelJUbElkRUZvYzBwT2J6ZEhWZzBLYzBaa0t6ZEhVMHB3UlZCQ1RVVXhUVVF5DQpPV1JWTHpkcmVrUnhjamtyWm1VNWNHOUhWR1I0TDI1V01HdDVjV2RJVm5CSVlVb3ZWMHByVVdOU0RRcE5kbkpLUVRoRmFqZG9ZMDFoDQpPSEZhTXpFMWN6TkpZV0paYUZSa05YRlJVa0ZzYmpsdlJXTlJkazk2V1V3MGVXUTJiMVV6YjNJclRtMXdSbkFOQ21SemFtZ3dTalZDDQpkVWxGUzBGTVlYbGhNMFZyZUROaFEwMTFUakZMYWtoNGVqUjBUWEI0T1Zob1R6WlJZM05HUjFGeFNqTTJVVk5oVGtVdmVRMEtObEkwDQpTRE01ZG01dGVuTTFhQ3RKVWtwdFRUTjRlVXROUzBwTVVEWnlhWGxzV1ZSaFV6bDJjRVZvZVhZeFpIazBLeXRWY1hwSVYyaHhURXh3DQpEUXBJZW0xVVVuZHdkVGQzVURSMVZrY3daMjVDTVVOSmMzSnZXVmxaZWtkYWRqSXlLM1JIUzNaeFdrZzFNRzV6TWtGYWFUVm5TMXBaDQpUazFaV0VVTkNtdHdWM04zVjJOeU0zSkhaekZFY1RZM1JHOWhRMUEwTlRsTlRsRm5TRFlyZDJwMlNXdHhSRnBPWkVkVFoxSjBRMjE0DQpiamxYY0VWMVMyTlpkQTBLUldKakszVjZWbEphTjNacWNsZDNZVEo0YVdKT2FqbHVZakJCT1hBelMySmtjM2hCZDBScVdrZ3JVWE5TDQphbVJoWWlzck1UQTBUSE5FWjBWRkRRcDVSbVpVWm1oT1FtZDFXSFZuUkRrMkt6bEpWSFJhUzFWWWRtYzJTRlV4V0U4MlVYRjBOWFV6DQpUbGg1VWpWT1kzZEphVEp2Vm5ac1UyWk1iWG9OQ2xaTmMwRmFWMjlUUWpkeE1WRkNNVmwxY2tGNVNXaFRaMmhxY0daNFl6SXdUR1pRDQpVV1k0TW5kaFVteFpSRGw0WmxaUVRYcEplazFxT1ZwU1N3MEtUVVJ1VEZCNmVsUTVMMlJ5VERSU1NXOUpOMHRGUWpWQ2IwdGpZazFzDQpTbmRWTmsxQ2RVRnlWbVI2YTBOV0wwcDJRMWRZY2l0d2N6bGljRVVyRFFwRmRpOTFXbFZ0UWxBd2VrUktiRFJQWW5WeGEzYzFUeXRVDQpRWEZUZGtsVU5sVjJRUzgyT0RWaFExZDNiWEoxT0ZjMFpWbFBhMGxpZFhwamFWRU5DbTFqVDNoQ01FWjZTMkp2ZFdacVRXMXpNbVVyDQpWbEpVWW13eVIyYzFXQ3QxVDBoUFRuZDZNVUYySzBOT1EzTnpUMDlYU1dwMVVucGplRXgwZEEwS2JWcEhUR3BtZWtKVVFrbHRibUZFDQpkMU5hT1hSSlVFWnJObGh6YUN0NGIwNDRkbXA0Wm5oamVYQTNkbmRZZWpneGIzUlRXRmhCZW1SaVdsbDFEUXBFUkZGbVdtbFdlV3hODQpXREZEUzJzcmQwTlBXSE16WmtsblVpOTZWVEp5UTI0MlVtTjNPVVphTVUxTU1rUnpMMWg0YlZoRlJFRlVSakZwT0dRTkNuWlZUVk5QDQpUMGRPU25Ga2QySllOeXRLYmsxS1ZXSjRaR2RXYjBGbWNYZGpMME5UWnpCMWRpc3JOMDkxVlVSMWFEQmtUa0pLV2t4dWVVUm1XUTBLDQpWbHAxUjFORE1FbEhXa2cxWW04M2JFSm1Nalp1ZGtkTmVYbGhObHBRTUd0bU5FeFpXa0ZEVEdad0sxbHVUelZaY0RGNmJFOXhXbGxLDQpRVzUzRFFwR1lXNDRUVzkzV0dSRGJXeExPRGR5U21kT2EwZGtXVlJEUm5FNE5EVXpaRE13UW5CSVRVRldiMlF2UzBKVU5HeE9hV3h6DQpVVkp3WWxsdE9Dc05DazAzVkdaMmVYSnNZbkpFTkdkSGRYTlBSMU41WVhkd05XRjRiVmt6UkdWMmJXcHpWRUpKT1dWbVRsUjJWREoxDQpTM2xXZERscmQwMTVjbTQyTWcwS09FTnVOVzEwTlVWWVZrNXBlakkyTDJsU2EzVTNlblV4YlU1U1VtUnJUbXBIV1cxdmJrOTRSSEZuDQpjVU01V1VaUVdrWmFXbHBtVVVKSVZrZFREUXB1TjJ4WGVqVnZkRU5EYkhveVdVTjFkRUZ3WWtkWU1XeEpkMDVqTlRFd1JHOUNRVkJ4DQpWakpJYWt0aVpXOXFia2xhUlVSS1VsVjRlSGRKY1VJTkNsTXhjRUpVU0ZJd2JFbHFhR3RNV2twNFlpOU9iVEZLU1hSTFYyVk5OSFJPDQpSSGxIZUV0cmVIZFZaVXR5VVZoTVRqQnVaVzVtVlhWTWJFRnZTQTBLVDFaSVoyVkdNell2UWpkM2VGbHdVRTlOWVZVd2JDdFdkM2xRDQpVa3RJY1U1b1RtRXJOVkJwWW5kbVlrTXJhVXBxTm10V2JEbFdUMmRxTlVWWkRRbzBRbmRqYlRaRVJVTkthbGxDZWxsYWRFdHNaR1oyDQpWRkZCZEVwdWIzYzJTRzk2U0haNlJrSlZVVFZ0VEhKeFFtSXliMmwzWTJGeGN6SnhUMVFOQ2tWbk1WUmFiV2x1YUhkaGExUlBORWRPDQplbmgxUjFoVlRWZzNUMEppTUdsalRTODRkRzFuVkhsbWJUQk9RV0ZOTkZKVWFra3lLMGRaT0ZkR1ZRMEtSMkZ5TkVWbVEwMTBhMDVODQpUMk5WYkhZMlJrVXZRa1UwT0c5bWNsTldNemRWZFNzMVVFY3hjVXMxVVhaMlNGZ3JWblZXWlRKcVpIQmFNR3BHRFFwa04wTklRVFEzDQpaMUJIYVhJMU1WbGthMnc1V21KMFRrcEhUWGRrY0U5a00wTjBiakp2TDJjMU1XUnBPVzg0TURobWFrTlpVVmh0THk4eGVYUU5DalZSDQpObVJtVjFGQ1pYcEJUbk42YmpCUFJsSllOVmhITVhoTUsxaHFXamg1UlRaRU1tdE1RVXh0Ym5kNWJGcDZhRXRVWm5ab1VVUjZaeXR4DQpLdzBLTkU0ME5teHhRVE5QTVhZM1NscGtRbXhKTWxwck4zSXdjbWhtV1Zsa1RVNUhNMGN2TkVSQmJtZEtTRzV6UXpGcWNIa3JkbGhwDQpZMHhhYmxOWURRcGthRlJzV1RkeVJuTlRabGROWkhoc2VXTldhVXg0YVRCbU16QlhPSFJxTVRadGVUZHZMM3BKWmxKMGRuUllNblpDDQpjVU5zUVRSS01YaGhMMWNOQ25oVU5GRjRjMlpGT0VkamNIaFBWbmxaSzBJd05rSjZlbk50TmxJMlZUVXJNaTlwTkVWUGNtSnFWMGxQDQpkRmxwY0U1SmRWWk5SSFIxUkZaNlZRMEtNRFZvZEZSRGMxTlBlVVl6ZVVwd1JVVjVVRkprUkhVMVRGZHdVVlkwVWpsa0t6Z3hlREJuDQpZMnQxVmk4MU55OXVXVkJrZUVreVVGWnFaM2hxRFFwT1NHZHhXVk5RZFZka09YQjFNVXBDZVhSV09TdFZaVWxuY2s1SFUwMDBkMVUzDQpTa1pwYVVKUkwxTlpMMDFJWnpOMmQxRTNTVzAyTlRCU1NEVU5Da1ZKUlVwTk4yNUxhVEo2VVdZeVdWUkRSRkJIVFc1WU5VZzFXR0l4DQpaRWx6VEdzNVYwaGFlblI1ZFhoMVRGZE9UMjVIZFZCcWRraGhhMUZVTkEwS1l6Vk1OVWgwUzJSNVRFdENhMmRqVkdOb1JXOVJaekJVDQpkMEprVVdSV2NVUTJabkZxZGtWcVNERlJZMmxyYXpKdE9UZE5jVU5KVGlzNVNHTjZEUXBEUkd0VlpVdHBkVXhHY0RNdk9UVk9PV0ZCDQpOMUJZTkd0YVlVdEVPRWRtYWxGVFMyeFVhQ3RGUTA1a1ZpOHhSSEpZUzIwNVYwd3hNaTlzTmxZTkNub3hXa3ROZG1GeGNraE1SSEpQDQpNMnRuVWxZcmN6VnVhV2hKYWtsR1dXbHFjV2hoTUdwc2NUSmxVRmh5YUhCVWF6WlJlRzFqU3pkbVJXaFZPUTBLVVVGRmIwSktNMU51DQpTelJtYkZsQlYyOW5ibXR0WkUxU1psQmxWVU5LUkU5VmVVWXhLMXBVU0dsVWJqWXZUM1prVEd3dmRGSXdiMlpVTVhSRkRRcEllRTQyDQpTamw2WjFrNFFrbFlWRXBPVjBOVU9FZzBSR28zYkZCVk0yTTBVMlZRTlhSVFNETnJTamMxYjIwMlZGbFBOR3RUVDI1QmVEQkdjeklODQpDakpLWTNscFZrWkxORkpWZGtKM1kzZGlTMFJ2VVhOamFWTnRRa2RZYlRVMVZVVkpVMFpGUlRaeGNFZEJWSFpIV210cGFHNHlUVU54DQpMeTlIZEEwS1dGZENOM0kzY0dWeWFGbHFMM3BqYjFsdlkySTRRbEZRTVU5ak5EbFFRazB6WjBkME0zRlhSVXRPZDJ0dFZVcFVaVGRXDQpUM0p4VlN0aVVrbzJEUXBOYkVKUVVWSjZPRGhMVUVSUlNrNXJabTkxWTNNMFRVdFFVR1JrZFhCVVZsRlVPWE53SzBOTWRERXlSR2hNDQplRnA0YWpNdloweG5UMlJQY1UwTkNucHBOM0ppZVRCdmVreDZiMlpvWm1GeFVFUk1kRWQxWkhGcE1DOXRUVVU1VGxvemRXVTBMelJUDQpSR2RWVDFSSVpIVnZPRFZwUW1aemMxazBNdzBLWjA0d1l5dEdTMFV2YUVOM1MwRkNhVkIwV25OUGJUaE5PVmgyYkROR1FuUnJkVVZXDQpiRGQ1Wm5BMWJtTlJOa3RHWlU5c1NXZHhPVWwyWjFwSURRcENMMW95TW5KQ2NYWkNVV2xIT1VoRWJHNTZWbkF3SzNGcUwwOHlRV0oyDQpWRzEzZEhBMFRUUlVUV1Y1TDI5QmVEaHNlRlZDVlhseFVWUnRZbElOQ2todFRYVTFVa1JWVUdjd1IwOW9jMFI1T0U1SlZqaE5kbEJXDQphamcxTjBSeFJHSnZZVlJFZDBkSWRucHlUMFJ1TDBjeWVqWkxPR3g0VGxGS013MEtXVTlMVDNGNlFrVkxUM1IyVjJGVk5uZ3lZMEY1DQpjVE12TDNCbVowSlFNRzFyU1RWUFNIUXdlV0U1UTFOSWRrUmhiVVZOU1dWUldFOUNWV2hKRFFwNldXVjVORlpaUldOTmVqWjNNekJ0DQpXamxJUTBwM2QwTnRSMXBSTldOMk0yNWxiMGRCWWtkMWJXTkpUU3N5YUROVVYycElOVEJJZDBkSU1Fb05DbmhWYzJad1Rsb3hZMVZEDQphRmhtYTJjd1pIZFNWMWxDTlU5WVNDOWxOVFYzYmxsQlNUUlFaRFVyVkd3NE5uTjNkbkZhVGxZMmMwTkxXVXBsZGcwS1NWWTBWbWx2DQpjMjB4ZG5JeVdrSTBRV3hLYlM5dE5UUjRTVlY2VmsxUGIxVkZMMVZ6WkdwQmVsTlBhMkpLTHpKdmFHSlhObXQ2VjFkNlkzbHdEUXBPDQpSMkpXT1ZWNUwyZGtkWHByV1dwU2JVNTNNMngxY1ROemFVbzJSa3RqWm05SmRHdE1TV2hrYjFOMmVYTm5jbXRIWkZCSGNtbHpUR0ZoDQpOSG9OQ2pWNmRrNTFhRzlqWkhsM1RXOXZhM1JxV0hjeFYxVlhXRmhLSzI4MFZrSktjQzlFYTNvdmJtTXJSaTlCTW5GMFJVZE5la3RuDQpZVWhqVW1admNRMEtZVk5DSzJvNWRHUjBNekptY0UxQlNubEZOVFpDYkZWb1JEUk9kV0ZvV0ZkSFdsZENaVGxPUmxWU2IyZzRNRkkzDQpWbVpMU0ZWaU5XMVFRWHAzRFFwRFduRlBOVTVaYnpSU00ybzJlbUZJYTFweWRuVnhXVzF5YmxGTlYzUlFPVlZXTjBoTVUwNVRWbFlyDQpiRTlZVVRGek1VaDVSMUV3VTBSU05uRU5DbnBtYTJJd2FrVlRialpqT1ZaMVNrWnRWRVU1U0RBMGIxUmxOakJtUzJGd2NuWkZTV2MwDQpaMmhwTXpGcVMxZHhZV2RFVjBGS09TOXJaR3hTY3cwS2NuRnpOREZrUlZWaVlWbGxPRXhrTW1abmNDdG5jMFpwYzBsT1NqUldNVTR3DQpiWE5TUXpSSFRreHNiM2hRZFc5WmVHaGFlVzlHUjFsTVZVVmlEUXBaU21kWFlWbEdibVpLTkhwVWJWRnpiMWt6SzA5clIySmFMM0prDQpTbHBSTlVWVGF6RllORVV3YUZSVGIyVk1WR2RMWjFoalQzRXhWblJ0VjNZTkNuZzJiWEJFWjJWVVZrbHFVMHBJU0RSSVQzZGtRVmxXDQpNMnAzT1N0WVQzcHZTVkJJSzBSdU1HZHVhRWhOU21saFQyaFVkVnBMTkU1aWVFRTVZUTBLUVVwMFFXcHhNRFJ3WjNWSVNrZFVWamswDQplVWRNWkc1RU9Xa3djR1F2Y0hwR05VSnpUbWxOYnpjeVpsWmtXa3AwVVZCUFF6ZEZOalZaYlhFekRRcHJTbUo0ZWxkUVJFaFpRVTB3DQpiRGxCTjI0ME1HdFFNRmxRYzB4M2VVaG1UVGxzVFhaVlRUTm5iRGxSVUVsQlVXRjFkRUkxVVRONmJFdDFTVk1OQ25VNVlXSjNiR3RrDQpPRmhXVGtsS1QzQXJlREphY3k4cllWa3ZibWQyYlZOSlFscElNV1JaUldKTFYybEZhU3RrVjBoclZsWjFibEpzV2xWdk5BMEtXbWQ2DQpaMkpvUm5aeFoxVmpiU3QzZVV0cWNWRlhNVU5UVGxsR05tRmtMekl6UzBRNFZGZDRMekpGYlV0SWVHTm1iVk5hTUVGNmRDdE1iRlZNDQpEUXBJTW5OSmJtMHlObEpQSzNaVmJFaFFSVEZHWW5kalVrRk9PV2xuTmxwSVMwNDNaRVpZV0VFMFIwcFlaV1puUldVMWNIQllNV3hpDQpSSEpLYWpFTkNqZEtSSE5aZEdneWFYRm9VV3hwUmxWeVlqSkxVa0ZCYUVkSldXdzFWMHMzUWxaTldXMWFjbkJZYjJacVltcHlTekl4DQpaSHA0WTJaQmVrTmpWZzBLUlhoTVJGRkpPVU5XZFV0VE16RjNSM0IyU0RseGMzaFlVV1I2TW5KVVIwaEllR0pMTVhKSGEwUXZWVmRXDQpNekowSzNCTGFIQXZZMDlPYld4SkRRcHllWGRyY2tGNk5HdHFZM0UyVTFWMGRFaGhPR2hUTjNKbFprdHdka2syU2pKR2NEVlhiakZWDQpNVTlaVkdsT2JTdG9hV1ZDWlZOb2FHdHBjMndOQ2xKaWNYWTFTVEZqVnpSbVRtbGlUMjlyTDNkTlVtaHdjRXRRTlhobWIzRnFNRkZrDQpiazVKVVcxcFUweE9hR2xuVnpKWE0wUkZNRGRJYlRSUVZnMEtSVlp5WWxsTVF6ZGpSMU16VlVwbmNFSlRUMmxZV1drMWVIQXJUMFJLDQpjems0UTNaWmNFMVhXWEp0TjIwMVkybHVhWGhwYldJeWNFNDFXQzg0RFFwc1YyaGpORXRPVW5jNGFXTkhXRmQ2ZFhoT1EybzRja1Z1DQpOMlpYSzNwWFIzaFdVbUpHYkZaVlVGaFVVMWd3VEhBMVltWXpOVEpwUzAwdlRXUU5DbGhrYUdkTFpEbHhMM05LZEVrME1UUkpMM1ppDQpOaTlMZGtzNGJtZERhWEoyWmt0Nk0zTnJkM1oxTURSWFNXeEJSa05xU0ZGMmFtOUpWamtyTHcwS1JIVllRVE0wWTJrdk5IVnlRemxyDQpTVWhHUTJOVWFtRXlZbEJPVFM5V2IyMUNSMDVFYURZclIyTmFaalppWTNsaVZGVnVUREo2TDJST1ZXNDFEUW95YjBoWWRXZEdRVEppDQpZbHBpYlc5dVZEWnFVemhxTWtVMWJuWm9OWFZTVFU5Q1JEZGFSQzlYTlZNNFkyRjBWRkJ0U3pKUFR6ZHNPSHAzY1ZjTkNqZE1SM0JyDQpTMGx0ZG5GbGRXMWhZMjFVUWpoSFJtTklOa0p0UlRRNEwxbFdPSEJKU21KQ1ducENSbU5uSzBGME1XRllabTVMYlU5QlVUTkVhdzBLDQpRazV5ZWpKWEwwaFdTV3hGZUV4WGN5dFhVekUwUlRadmVVWmtRMk13UmpkVFNDc3lNMmN5ZG1rdlZtcDFhbVpOZEZWV1ZFdGhOUzlODQpkV2RoRFFwQlUwbGlTV2xCTWpGd1dXSlhkSGhtWjNOTUwxQllSakV5WnpKd1NGWTJlRlJEZWxoVVpXMW1VbTFSYldNM2FqZGpSbEZpDQplRTEwUlhGUWNETU5DbHBYUkhOUFlXYzFOMUJqYjNST2REaE1hMWN6V2s1Mk5tWjZhRE5JUjJ0dUsySklUbFUwZDNoWmN6WXhZMmhhDQpWa0ZDZW5sNVMyd3pPRzFYV2cwS09XNXNZMHRNZWtsS1VIWnhjVVV3VXpZcllrVjBZMGRDTlhWWWIzRXdSblJ0VW0weWJXTXJiMkZ6DQpaRTFSVkRSeFRrUmxlV0UxVEVRdk9HVXJEUW93ZFVzd2QwSm5aMEZsV0hCRWN6STBRbWRrVlZFM1dVcGlUbXMzY2pOcmRuRnVVRlJvDQpOelZ5UlVoak5tcEVWMEo0Ukd4cFNHbEZOMk5KTDFFTkNsVXhSM295V210ME1IbGllalZUSzNFMGRVcFlNbVUwTkhoR01HRjVVRTAyDQpNVWRZU3pOdWVrTkZPRmh4SzBoRlRrUk5VbmR1WkRad1dsTkhhZzBLTTBGcU9WRnZOVUl2WTBReWFYUmpibXAzSzJGSksxcHFkRmhqDQphRzR6Ukc0NVQxbDJSM0Z4TkRCWksxWk9TR3B5U2tKUGVFZzNXVFp1ZVUxd0RRcDVOVTFRY3pFclF6aHBRamxCZHpoTWVXOXpRa1pUDQpNSFZ0ZG1Wd1FsSnhTeXRuU0ZOdlRIZGhLekJPWlhSUVpGQkROa1pvWlVSaU5YSmtZVllOQ25SR0t6WkNNRmQyZFc5TU9HUnBaVFJPDQpSa2gyYVd0bVVWUnpXVUZVY0hkMFluaDBlRXBtY0RGRmRtNTNZbWN2T1dkS01tbGhjMnhqY1U1dGVBMEtNV3RGY1d4RGNXUXdiV3BCDQpaV3ROUVRoM01rRXJVSG92TkZab1dtVldkRUpUWjA4NVpGSktaMjV6YTJobWJFSTNLMlp4TnpWMWN5OVdUVlJLRFFwNFRGWnljbXBEDQpkbEUxY2xaaFNIVmpTbTlHVWtvNFdsbzRaUzhyY0c5b01WVkZPREJzZFRsS1ExTmpUV2Q0TUZOQ1lqY3ZabUpETTJJek9FY05DbFY1DQpUMDVpUm5adFpXdGlUa3RQVmt4d2IzWlBXVmxSZFZGNmVHZHJhWFF5V0dFeVZVeGpWM1ZyYm5NclExTnFlSEpuVDFoUVkybFhXa3RXDQpTUTBLZEV0UVVrUm1SMlEyVTB4T1YxQTBVQ3RQVDNKQ1NHRXZMMVZUVEhwTFptVXhkamhZV1hsellYQjRNRUpxVTJOcGNIa3pUVkJGDQpTWHAzTmk5WURRcHRTWEZyVjFsaFFWbFNReXRwUjNWS2EwRkhWRkp5YjJSQ1NtWnlORkZEUlU5RmJubEZUMDUwU1Vzck9VUXZhbXhSDQpZMnhTUlRaS00zcENXak1OQ2tkelNISnBTRFZRZW5OaVNsRkJkV3d6YjBwS1YwcGtOM2RJVmt4elVTdExVMEp5V2tKTFMycHJVa2xqDQpWMDVJTlZaQ2VXWmlVM2RvYzJGcFVnMEtWUzl4WW1RNVRYZDRUemhPWmxKR00wTktjMUZ1U200d2FXVkxkSEpaZUM5QmVXdGplRUpTDQpWV2t2ZDJZeksyTXphbWQzV2xacmJHTlFhMVZoRFFwbU1VWXJUa3R2YTNKdVFWQnpSRkV2TVc1YVVtTjRVek4xTlRoWU5qaGhRVzF0DQpkazB2UkhOUmF6RnpWbTFDV2pKTFlpOTFZeTl2TUV3clVUSU5DamxUVFhCQ1MwOXJPVU4wTHpWS1JVSkVaVTVGUVZNd1Z6TTNNRTQ1DQpiVmw1Vm14TlQybDVXRTVWVERsUk5EaFdORkE1Tm1ObWMyRjViVTQ0ZFEwS1NUYzFXa2t6ZWpCS1VqWkhjREI2UzJwdGIxZHhiWEEzDQpOak5PTVdKS2NscEROMjVhYUc5dlJUZERaakEyVFdSRVoydEhlalpvTUhsNVpHUTNEUXBCYWtGRVYyTm1aVE5rTVRGV2RIbERVVkZGDQpTemxQYUhJek1GTTRZWGh6UkhkaFRGTm1aV05xV0VwbU0wVlVZbkZCVHpSTlRtc3lka1E0YVhvTkNuUlJlRVJCUW1RNWVHNDVVRVEzDQpiVnBuT1RZM01WQXpWMUJLY0VGdmRWUkhOV0o0YmtkUloyZHlkMU5QYVdKbGF6Wk9iRlZ3VTNsSmRHWXhRZzBLWWpkcFJFaDFSbm93DQpXR0ZUTlhoYVZYUk1VbTlUY3pOT1ZDOVBiVUZCU0ZRNFIweFlObTUwWjBFMFJqWlBVRTUwY21Gb1JGVm1abnBYTWpCb0RRcHdUM0JuDQpjVEpyYWxCNlJXVk1NRFJFVkZWRFpWY3ZZVXhFY1dvclFTdERibEI1WjNBNFJYQmFjMHhpUm0xRUsxRXhUbGRsU1dock9IVTJhRFlODQpDbGsxV1hBd2RETnVXVUpQTHpkWVJHaHpaSGhaUjBsamEwMDBkbVpRWjFWWFUycG9SWFJNTDI5Uk9DOVhaalkyUldoR01XeG9iaTkwDQpkbTlxTlEwS2NVWk5iblpyTm5KaEwweG1UMDgyV0ZaSFdVdEJkRmR2UWtwd05YTk1kMlJCZDJ3elNWRk9SMnhsYWtkeEt6SlNhV3B6DQpOblpJUkZKTFRVaE9EUXBUTXpoRWJVeHNkMk5ZZEdkalFsTXlWVlZQYzJ3eGQzaEVhWEJYWVN0NmRrZFhlazU1U1ZOYWJHRjRUalJhDQpTbkJaTmxwdVFWRmphV1I2WkcwTkNtOWxZazAwUlc1c09FTkVWVVZ1YVRneE5ERnpTM2RaT1hCclRuTkZRM0ZsZDJzeFJsUlFWRkJuDQpaSEVyUTFWbFExbEtXbWRqYnk5V1luZDRZZzBLZUVGVFVGWkxaSE0zYUhwc2JURlpWM3BLZFU1UFUxcEVaMEZqVW5oUlkycFZOR2xKDQpaMU5oT1N0ckwxbFNibWR6ZFdOUGQxVkJabmd2VERnckRRb3hUM04xWVZweVJWbHpVa0ZtVEVGUVdsVk1aWGg1YVU1b1FVUlRXbTFsDQpWV1Z5UWtOWk1FVkRLMEUwUldveWNIQTBLMDlvTlhZelFVUjJWV0lOQ2xwVE0xbFJMM2w0WlRoNGRHbzFSVkZEU3pWdGRUWmpOU3M0DQpUMlJ4ZWxGUGRUWTRhRVJDVFZsdU9GcHJTazB5UWpSaGJqWjNaM1JQUTI1MVdRMEtaRlZXTW1oWWVXaHVTMFJ1VkRjck9WbDZjM2hoDQpWak5sTXpGblJXOVZaMlp0ZEhwdE1FSlVPV1puVjAxTVVIVnBRaXRXTW01Vk1XeHllVlJuRFFwUmFtZENOWHBRVjFsdFdGQk1hR05IDQpRMWRuV2tWWE9UaEljbWxpVFhsVmIzVlRlbGREVG5SbGNsbEtaVWxSU0dneWEySlpWWEl5YjJoYVNHRU5DbTFKUmtSdldqUm5Sek5qDQpUa2RGUTBWeVJYUnJNRkJaYld0YWRVTnBXRFJRVFhaNmNUaEdiemxWWlhkNU9FWnNOakUyWnpOVmJtVXhZMUZFUkEwS2NVcHplbFJODQpRemM1YkhodWVHNXJSRmh2TjJFNVRUZHNkSFUzVlN0UGRFWlNaVkZtZDBSb2VXaEljRU5VYlhScU9XSkhXblpaUjNSMWNsbDJEUXA0DQpiRTFqTUVadE5rRk9abHBJV2k5UlZHaHpRbnBDVGpCUE1taFFUV2xIVGxGMldrOUpTMDh3VUhNM1MydFVLM0JHYUZGamVrbFpURmhUDQpjamdOQ2xaWFNXdExOMU51Y2tocU5uRjFZa0ZHUlU1aGJXNTBla3RrTTJ3ek5uZHdaR2hCTUhOV2VteHhTV2h0YlRGS056TjZaRkV3DQpTbVJDYmt4SU53MEtZMlZJVTFOTllrSkpTWEp1ZG5kSGNsUmhjRTUwY0VreVpFOVpWbFZZYWxGamVUUnBRVzU0Y0RWQ1lXWXpaRmR2DQplazlhUlRKc0wxRlhTbVpZRFFvMU0xTk5RVGRqWjAxTk9WcHZiSFZ1Y214d0swUnJjbTlpYkdkRVVVNTFTeTlRUmxkbGFHZEZURlZaDQpOa3hUVEhFNGN6aE5hV3BJVTIxaWNuQU5DbU53TVZWNFpYVnlVblJpWW5Sd2QwaFdTRTAyU1VrclJIaFlSMHN2TWpkaWR6ZFVRM0JpDQpXblZsYkRnd2QxaHRLM1l3ZVVnNVpHUkZVMGRHY0EwS1pDOXFRa2w2Y21OaFpIQjFjMGxZYW1NeGVtczJTbkE0Y1VscFFqZDNOMVJIDQpRVk5UUVhJNWRVUmFlU3M0U0VsbVMzbElkV1JrWlZOd01XWTJEUXBJZG0xT00yNTNjRlZxWTJjNGQwWTNWblIwWm05dk4zWkhibFZIDQpjMmsyVFZKWFR6Qm5XbGxzU25GVU1YQnFVVTloVW5BcmVVNXhXbVJZV0hFTkNtZFBla2hQTmxWNFJFa3dlRGhGZVdoTFRqUjRUWG8zDQpkVXBuWmxoMldXNUNSa3h4YkdFdk1WUnZVbEZUYWlzMFFXSnJabHBsV1VKclpuRldVZzBLY1dkRVZreE1VQ3R3VlhGSlNVdG1lRlp6DQpXSFF4TVhkeU1DdG5SbGxVTkc4emMzWkphRlZOVERaMmRtcFhOVk5EV21NcmFWbEhUekp6Wm5KSURRcHNTM2w1ZEc1R1RWcEliWFJFDQpkV1ZMSzNWbFRtVkpSVWhWT1RKeFQwMTZkRXhpUTFWb05UZDVkblI1WlUxeFZqZE5iMjVYVTJObmNreEtiRTBOQ2xGTFQwWndVbmxqDQpka1JrUm5nMmExaDJXV2hJV1hNcllqTXZSRWxNZDJReldIWktPSHBKVG5SUE1reDZNRUpTTjNCMVltdzBaazlyTTFkTmFnMEtTMWRQDQpkMnczY1dRelZ6aFRSa1JaVG0xVmJESldSVEpoUVRWTVN5OU1WelZVT0RGNFZYTlVlSEZTUzFKYU1Dc3dlVmxCVWpnd1RGcGFUVUprDQpEUW8yV0d4dE1UaHNNM1ZhTURSck9XOVZiRVJwYjFWd1UycDJMeXRyTjFoeVkwcEtlVkJxUVZGSk1USnJkRVpWTkhGbGMzVk9XaTh6DQpaakF2WW5VTkNtSjFkRFpETm5SRVZFZGFVSEpEYUNzelJVOWpZbHA2Y0hCelYweHJTR0pIWVhaYU1XRk5RblJFVEZJdmQyNWljM0ZaDQpUbXgzZUdGWFFtdEphdzBLU1hOMGVWWmlNMVZtWXpGNFVtMWpSMmgyYzNaVFFtUmpTbEZRVkhKcFNISXlWRzVVZERONE1tTTFTMmh2DQpaM2xTTkhWMGRsQjZkVFYzTlZReURRcFZUVnB6YTFGSlJHaGllblZ3ZFVwcVZXUjVjM001UTI5a2NqUjVVVkVyWVZJNFpqTkdWMnRIDQpibTlNWkdFd09UazVkSFp0T0RaMFJ6RXlZMUlOQ2pOa1FsaHZPV2RGTlcxSlVHMVpWVXhDZVZkTFFrUmtLMUozY1VscFEweHhkRkEwDQpkV05IVVRoS1owOVZkVmxhYkROcmVsSnhUVWxxV0hSSFlRMEtSbWRKUVdZelVrOWlkbXBtYTNSSFRFZ3pLelZpYUU1M1VEZHNTMEZGDQpZak5KYzJFM2IyMWFkM0pIUkZWRVRuUkphblpzTTBRelJYRk5jVXMwRFFwNVFYSm5XSHBtZERoTlNuUnBlR2d4TWpSUlkxbDRSRU5SDQpNVmRrWVVOUU0wMDRSSFpCUVVjd1RrVTRNMGxqTm5kQmJHZzJhMGhuYzBnNU4yNE5DazV0YkdwQmRuTndhR05SU25vdlJHaFpVM2h1DQpUbTl1TVRWVFNVWXdiMkY1VjNkT04waEpiVTkzUjNacE5FYzRlbkpMVWxsM1ZVb3hSbHBFYmcwS1VURmtTRTl4VEdsclNqaE5SVFpaDQpka3RrWVhZNFZGSTFjMHRSUlM5SFFpdDNRVlp0U1hsRVZFWnJXRUZKYjFBeFIxZ3ZSSGhtTkhjeWFUQXpEUXBTV0UxV1UzbE1NWGQyDQpkM1pFWVRodFVFMWhiUzg1V2xaTE5rMHhSeTl6VldOT1VEbFdVR1pvTm1GYVYydHpNeXQwVFVKalZVUlpSM1pRWW5rTkNtUlZhVkZRDQpRamg2WTJkTmVXNHlaSEJMU0RabVJ6ZHRUWFYxVWtOQ1p6WTVZMDFLZG5GMmQzSTRlbEZtVW1SUU1sUk1kVXBXZUVkMmVGRlpiUTBLDQpRVGhpUjBOT1dHdFdjWFJuT1doeVIzZGlSRkpDTUhwcVltUjFSRmxrT0ZKT01rWlRTMDFrTldFeU5YYzRaa2xtTldaclZsaENibkZvDQplVkJNRFFwbVZHWXlVa2RtVm5oUU1rbFJPR3B1VVZsaWNEaHFZVWwxY1c1d1FXSmpjeTlGV25KTVdVdGtaMDgyYmpsUFNWaHlTRlJhDQphVXROYzFabGNYVU5DbEJKVjBwa1lrVnRiWEpKUlZGaU1rVlFOVE5QV0VGbE9YQjFOa3RyZW1sbVJHTmhUekU1U1dwWVJYbGpZWGRLDQpSbW8xYkd4RmVUaElOVGhZY0EwS1VrVXlSRTFGU2xwNmJuQmxNbGRaUWpCVVQzaHJZMnByTlVzclNVaFFXa2x4WWpSSloydG1TVmxLDQpkM1YyYkV3ck5rcFVZbmwwVFhCYWJWaHdEUXBQUVdoRk5USm5hVGhSV1djMWVTdHhVRXhSYm5GYVdraHliMDE0VEUxMk5FZDZabkF5DQpkbWhJYTJwVlRqRnBRM2R6Wlc0eVlXSlNhRzVDZG1rTkNrSm5URXRYWVRKc1kyaG1aU3QwTWtGdmFFVlFiVkJqVFdGYU5XZGhWbGRLDQpRVk5QSzNOQ2JuZEpSRzEzV2tOU2JrZEtaMFpUYzBobloxSk5ZUTBLY2tWblRqTmtObVJxZDNFMU9URmpOelpOU25JcmFXTXljVmhhDQpOVlZYYW5KNVNrZEphbEE1T1RkVmRFeFRWazlOTUdGbVVqWnlSMnN6UjFkc0RRcHZVRVV2Um1kbmJ6VnNZalY2T1VwUlpTdHpWMUprDQpjRkl4Tml0eU4zSm1TWEZLZUVGd2FFVlNUMnhDT0ZWNmNTOWpLMVJ1YUdSNVRqUTJhMU1OQ25ORVRIY3diRE5JT1VoQ1ltRndUV2c1DQpjR2hDWVd0V1NFWkVMMWcxTm5wdVprUXhVR3BETUc1QmJsaEJXU3RXT1hOU1J6VlJWaXR4UzFCQk5BMEtlVkk0ZWxSWmRtVkpVek5hDQpNa3BtVnpCcWRsb3ZWRWRsTUVsTE4yaHhZa0ptVEhaeE5UWmxUMUpGWmpoeVVVRTVXWFJoYjNScVNGSmFjWG81RFFwT1QwTkxaRVowDQpNSE5EWkU1YWJteDJaMVpZTVc1WFNGRjVSRzFoYkhsT1pVNVNPVzQ0UVZwVGNWWlFiM1ZFVVZkck1tZHRWVkJVWm5sdGMxZ05DbFZODQpTa1l4UlhRd09XWXhkMmRFY2t3M05rZFZjWGxGUkVOc1RVaEpjVnByVlZseWRqQnJNemhaZVVGUWFFTTBNa1JITUZCUGJGaFpWRTU1DQpNUTBLUkdaRVZGWjZTREl5VEhaRFNrbGlUMlpuTDFOcWNXSk9XRkpSU0RKM0syTmlObE0xSzNrdlpGQm5iR0ZWYTJFd2RYUk5MekV3DQpiWEJUZWpGekRRcEplWEp0TldwMFNWWnFPVlIyUlM4NWFFSnZhbUZ5Tm1oVGNXVTFUamR5VW5GSFIwUTBielU1ZEVKSVlWWmtNMDl4DQpWbEpDY2tReFdFYzJUM1FOQ2pocU1HZGlhWGhyYTFOMVQxZEpPRXRuVUVacVpHbDZXVWhuZEdKMGJVYzFWWGh1Y2xscGRISm1RbmRpDQpjbUZHWVdsMU5qbEhTREJqWmtoeFdRMEtXVTlTVFhwdWFXdHlNbWc1Vkc4d05tbDJZbWRTTjI4NGVIVkplbVJOWm1KUGNEbG5iblZuDQpSMlF2V1VGbldtbFBPVVF5Vml0UVQxSjZhMEZWRFFwcFVVTjVkME5PYUc4eGRYWlFPWFo2Ym5OR1kzRm5VWGQ1UlZKMVoweFVlRmRaDQpPV0UwY1dSVlNYcDJaRVIyZW5KSFNHZE9hSEIwZUVsSFNuTU5Dak5LWjBSeVRFYzBlRVpyYlRGbFl6SnZVRW96TlZVNWJtOHpiRU5SDQpOWFU0VUdGUk4yWjJjMjEzU21aclNUaENWR1Y1TlRWalRXZGhhMjFwZUEwS1RtY3JUbnB4TmxGbE9UaDBWbEU0TURRekwzZzVjVGcyDQplREF3U3pScldYVjRjSEp0WTBsMmRtVkNhM2R5VW1wVFRWZGhXRWxFV2xWMFozTk9EUXBpTWpWRlRqUmtiRGxPWldsaE5tTnBZaTh3DQpOR3Q0U2paVU1saFdUMmxuTUU5a2FsTjVUV0lyWVU0eWFWVkdlamd6ZVVGS05XeGpUMWRJZG5VTkNrZHlVRTl2SzA1UGNuTnFNazFsDQpWR0pCY1ZoNE9Xc3lObWgxZVRSWGJuUkRiMk15VmtzclVtMUJSWEl5VWpCcGIybFdZWE1yTkM5U1dVcEdOdzBLV0hKaVoxbEZRV05DDQpOVlZTT0c5TU9HMTBaRFpPTkVWWFNWaDNZbUY2WVhCcVRsSmlkMWxHVVVGeGRFMXJiMFJDZW5wc1JYbzJTSGROVVM5Q0RRcHZRME51DQpkSEV2Y1dZMVExWXJOamR1Y1hscFdEaFRTMUZRWjBwb00xbHlUU3R1VDBZdlZtVTJWalp3WVM5bmJFVXljRGd5YTJ4SVJGWmhaVUlODQpDa0ZVY1dKaVUzUkZiSGxOWTI5M1dra3hhMUJ2UmtvdmNFSkxaMHR0ZWxZNFYxTnFZbU54TnpkQlJGTjBXRGdyV0hjMllVMW9abXRHDQpWVzFGUWcwS1Iya3hhbTF5ZVV0NFVFaFNUbEIyYW5CWmVrNU1MMnQ0UTI5UVpXdExTRzB4VEhKa0sxZzFUa0pIVlM5UWIzUlpWRmQwDQpZWGRDUW5ka0sxaEtEUXBoWW1vMGRFUjRhbTV0ZVdGV1owZExlR3BTZG5GWWIzVmpjMVpxYURKeEwzcEZUV1IwV1dWQ1dFSjRlVWRhDQpTMUUwYmxsaU16UnlhR1JaYnpBTkNsTkxXRkUyVGxWS2VqTldjaTh5UXpsVE1tNXVRblJIUjNKSlduVnZVRzlWUlRsSVdUaEVTRWx2DQpSbVpHVVdVNGJVeGhVMGhYUW1Kc2FERlNNQTBLWWs1MWJVRkJWVEI2WTJKeVNTOU1UelJ4WlRZNVNYbG1jbU51VWxVeloyTjJkSFl4DQpaRzlVVVhSUmNHa3JlbVp2UjFGMGMxTkpTbGd6V0dOekRRcFZXblZ6VW1aTWRsUkZaMWhVUkRGeWJsRndUSGd3UkhCalJYaFpZMlZaDQpkMEZZZW5Ga2VtRnlOMkZ6TkZCblQwaHZNbE13Y1djM1IwMXVjeXNOQ25Fd05YVndURUpuZW5sck0xRjRXbloyVG01UE16Z3ZlbGdyDQpObTFpUWpOUVEyUmplV2hOUTJJM1JIQlRPRXhJV0ZSMGFHaHFUaklyYUVWVE9RMEthVlJ2VVhsSVFVTXhTMmhTYm1sdlp6ZEJjalV4DQpibG8xZWxKNFYwWnRTakkzVldOR1ZXOVFVbkJsTURoRFdUaGhaSFY1WVVoc1UxbFZka2xPRFFvdlpTdDJkVk5GTkRSbmNVWTNlazFNDQpkMGhDUkUxaWFpOUJORFZqYkhaQ1RHd3haRUptTW1jM2NtYzRhbGRDTUU1dmRGaHFUMjFTWWxsbVNWZ05DbGhFYm1waGFuRlJjV1pODQpVa1ZKV1ZsNVIzVjJNblJsVG05cGRsZzFhRTlXU25RelptZHFURkZTWVdjM01tdHVlbVJ5YTJ4TFZGcHNaMjl1UmcwS015c3haR1pMDQpZWFF2ZUZkR00zZFpRbTFHVkd4TGVGTjNabGhOWlZoTmEzVndVMDlSYmxFMWEyMUxUalpJZVd0MFlsRjFkRFJsZUdsRmJXNXpEUXBoDQpVMDFJTnpCcWJsVnRhRzVMUzFWMWEwUjRVMU01WVdndlFuTjFWMlYyY1VsUGNVOHphVzE1ZUdkc1IzcFRUa1ZMTXpWSVFVSkJMek42DQpZM0FOQ2paV1RXTXZNSEpTVTJoTmFYRkdjVmwxWTJsVlRqVlhTVEp1U1N0VmRUQnFkM2R1TVZSTGJVOWFWemxUWmtaTmFITlRVemhzDQphMGh5U25OUWNRMEtNelZZWTNSMlRtTkNlRlJOWm01NVJVOUdiMUpNUVRCa1dFTkxiVXRaTUZkck1HdFNOMEpqYTJWWU1FVXdhWGRvDQpTM1l4UW1Oc2JtdDRWRGQ2RFFwMFluTXpTMjFqWVZkdk5qTkZTa3AzV2tKc2VtaDJWMDRyYlZSUmF6YzJTazByVDFCc2VFaDNkVlEzDQpkMWhYUVV4c1REWktkV1JHU0RKRFMyZ05DbkpyYVRkUmVqUnhkM2w1T0dSWVozbFRaRnAwTkdwYU0yMDViazlrWVVzNU0wVnpaM0Z2DQpSemMwT0dOWlRVdDJUbUkzYmxRelZWQTNXVTFRVmcwS1ZsZ3pjRFpCUjI5a2FGSXlSVmRWYkVwV2MxaHVWM1ZyUkdKV1ZESXlVU3RVDQpObmQyZWtseGVXVTJZelZEYUhoTmJXMUhVSFJKZERJMlNVcFVEUXBuUjFOTlUzQktVMjFUU3preFdtWnplVkI1YzFSSGJHbEthVEJ4DQpjV1JCVERaM2RXY3dZVlZHZVRSUWMxaFZNM2N6ZUdoc09VUmhhMXBJUm1vTkNrVnhSbGhWT0d0MlozRkRZWFpOVTJzMGJYTjVjRkl3DQpiM05pTWxCRVdVTkhWbFZIYkcxWGNsUXJZMFpvY2xSV1FXbGxaV1JVYVdGNU0wcEtOQTBLVmxWWlIwbHJRVU5vYXpSeUwyZGxWVlZwDQpOV2RJTjFsMlkxZHVOamRhS3poa2NGTlhSakVyVDJWUFlsUk9PV3BEZURjeWFreDRVMUJvY1ZGVURRcHdUMDEwYVVoMVZrYzRUbnB5DQpWSGxPVlhOMk1uWmFPR1pLWTFaR1ZFMDVNVWczVWxSVlkzbEZOREI0V0VRNWNrUk9aVzk1T1c1SVVIWllaM2NOQ2pnM2NHMVJkMjlKDQpVRlV5YUVWUVFqQjRUWFJuVGt3dlNFZDZaV3hKWW5vdlExbFhVREpQTW5KM1FURnFRbnB0VVM5M1JqVTVlVGRHZGxvMFNRMEtNbFZ6DQpOVGgxVTJodmVYVjZSbFpNWW5kbWNsSTBWVVUwY2taRFFXbzVaa0UxT0ZscVNGSTVkSGROVDNOa2ExQjNLMjQ1UldVNWFGUTBlVVkyDQpEUW96T1dOblJuUjZORmxoT0UxNVEzVnRaVXBOVVRaWlVqQkhVSGhVUVRONWVqZDZNMFJvY25WcWNYQkpNazA1ZVVSMVRFVnRWekZ1DQphRXR3TWxZTkNrWkxheTlpVWtKNFNEWXJjRWx1WjNoVFV5dHhOblJXTkVSS1drdENVR3d6UVU5U2NEQkVaekJ3TmxSTVprTm5jekkyDQpWMU5UWjFjMmFtZE1lUTBLVldGNGVYbHVWMEl3UTFrMFREUlJjVkpsTUZvM2NpOHdialpQU2xkdGQwWk1SV3R6ZFM5a2VURXJXVE15DQpiVVk0YjJkYWNYUk5UVmh0YmpOWURRcEtOR3BOYjJFeFMwVlRiMmRLVG1aUWVtaFpVMVJHUzNkMlUwaEZhV04xYkRGRlExb3dkbEIwDQpTRGhJVlVJMmNHSlZUbEkzUVZkNVVHOUNUbGNOQ2t4U1UydERlbTV0VTB0eVoyMDBiekZEZEd0MVRqSkJRMmxOYm5kbGQwVnFURFkwDQpkM2cwWnpCSVpIRjBMMnhQU0dkeFZrUlhZazlJWlc5cGFnMEthRUZDWkROQ1psSnBZa0ZQTlVkdlJXSmpNa1ExTWpsSGN6bG1aSEpwDQpVbUZuZG5sT1VFMXFOMHhYSzJKNlRqWkpVWE41VVhSSVQycFZkMHBHRFFwNGVqSXhSbmxsVTI4M1ZIRnRiVEJVVUc1RldGWldkbWhYDQplSFZZS3pWM05HWkRNelJTU1hOU1dVOVpVMk50WTJKbll6VkdNWGxTSzI4NE9WUU5DbFJ4Ym10bU1uUkxXVkU1UkdoQldHeEhielY1DQpUbko0WTB0eFZraE1lbHAzYjJ4NFFraGhhVzFEVTFSVVRtOXJXR0UyYVhKSmNDdHJVR3h4T0EwS1owSmpSM1pVWjNsQlVsSm5lRUZPDQpZVE5MYWxremVtdzVZazE0ZUdOWU4xTnFVVTB3UzNoWk9IcDBZMGhvTlRRNWJGQTRjRzFEVW1NNUwydElEUXBaUVhKSk1WaHhZaTlQDQpLMmsyYWs1R1IzWm1abFJYWlRaaVVFMW5XVXRtVjNkSGJVMXNNV2xoVlRrNEsxZDFkVTFLYTFrMk1YcEtTMkpXYUZNTkNuaFpiVlVyDQpkWEZ4U3pWamFWTnFXbGRQYW5sbFVEQlpSRGxuU2twUGJ6WnBkelo0U0d0eVdGaGpORU5xWWpGc1kwVklPRWhPUlRaNFJqRjNOZzBLDQpXblJzTkM4clEyWXpXVXB2TWxoRWVFUTNSbTh5V1c5cFpVOXNRa1JQTmpkdWRVTjVOSE56TW5KR1ZEWkhhM055TXpSQk5GTlJaM0FyDQpWVUpzRFFwa1lUVkZiUzl3Um5wc1ZVSnJRM2RKU0ZwSFlUWlBZV05KVVVkMlZXNHpkVEpsVWtaeGRrVm1kakppUkRoM1puVklUbFkwDQpjbFZsTmtwdWVEQU5DazVETHpWMmVtOWhlVXd6WVZCT05UQjVSVmR2V1RjeGFrczRVbTVuU2tWVGVsbG1kakZLV1VRM1RVTnBlV3hLDQpTazVNTXpCclEySXpSMVZzVmcwS1lrOW1ZbkF3VEVrNWRIcHVUWEEzVkVkalNuTlhaMEp6VG1kbGRtczNNbmhRWVdWTlZVbDNSRUpXDQpVVEo1ZUZCVk9EZ3lObGRQY1RVdldFazJEUXB3ZUdSVlNEWnRNV2hWV1RsMldsUTFZMmROVjJSdFMzTTBReklyTjB4R1NIRXZNMGxaDQpjMWh1YWpoNE0zUnhNM1l5VVVoc1ZrOHdWV1EwYlhnTkNsbEdaVE5TSzBreGJqWjBabTgyVGxaWU1VaEVNSEpWVEV0RFZUUnBWMnA0DQpRa3BHTDNwTmExQkVabFZTUjFOS1JVMDRNblpEUjFjMWNqTmpjQTBLWkRoTmFWcFRWV3B5ZDBVMVlpdExTbTQxVWpkc1UyZEJVMUl2DQpVR1kyYVdwdVNYUTRRV1p5U3paeVVtWmlRa0YyTlhkc2FHOXRNVVY0TXpCcERRcE5hbkpXZGxscGJVVkZPRTUyV0hCQmNFTjNTbVV4DQpVR2swY1ZaYU1FTlhNM0JzWTFaWWIydGtaVVpWV0hjemVWTnBRMVZYYTNaeEswbERjbFFOQ2poRU5tSXZTRzFTYzFNM01ISktabkZ0DQpUbXRtTTBOQmNFRXlPRkpRUkZFcmNYaExaalZGVGtFMFFXeEJiR2hrZURFNUwyUmtRVVpVYjFkb09RMEtWbGQ0Um1kSlpXMDVWa1I2DQpZakpZYW5GTFJTOVVObmRDT0ZKMGRVbEtaR05GZHpSdGEzRnVkU3R0ZUhBM1RYQm9ialV2VlU1bFlWTk5jRnBrRFFwRmJ6YzRjWGhqDQpRMUZHV1ZWWlp6Z3phbWhuUmt4eVdHWkZZVlZNV21GTGNWQnpSbE51VldrcmEyRkpjbVJFVVc5QmRrbHBjMEpHTjFkbE9XVU5DbWtyDQpURlU0YVhKUGJrbG5ZbUk1VGpWUE0yODVkR2gwZHpodVJXMXdZVFJZYUhwcWEwNDBOV0pQZGxobVJ6QkVVSGc0UTJZNVdHWkxkakpXDQpRZzBLUWtVclVGWXpXRXBEYVZaYVMyRjNRVk5LVEdSNGIyWnNiMEZCZG1WR1dFMW1SbFpRYlU1c1EwOUdNVkkwYVhKcVJIcHVlRWhCDQpjVlpyUlhWcURRcE9LeXR0YnpkblRsWTNRbGxGYzNsdmFUUlNlSHBKZVcweVNXSlVSblpoUjFGUlJFcEhjRlpZTlVZemMyeHlWM1JaDQphbkJGVkdRd0wyaFlPRTROQ2xCblVXOWlNVlYxTUVWeVdsUjJRMDFHVFZOMVYzRk1URVZZUldoU1IwOVNjbU1yVVRORFpVZ3lOa3AxDQpjRTE2UmtkelZuSlBSbWd4TXl0ME9RMEtlVU5uTmpoU1oyTXpjMFZYV1dGVFFtTkJSbVZRZDNSb1NGSmxabXh3V1VNeVlYUmFZbVZVDQpXV0pzZEZZeWVXMDVWV3h6YjJnM1dVcGxhWEZyRFFwYWJVdElPR2x0TlVaRlNsRkViV3d5ZGpSMlYzQTBaelpTWW5GR1ZYSlVieTlFDQpkR3R5VDAxT1IyRnlNemx5TWpWMmFtWkljbHBMVWtGdlNEZ05Dbkp3VFhwM05uSlBVeXRXVjB0RldWUktkVlphTkVJclJVOUZZVzFuDQpTMFpqV0RBME9GZHBVa2gxYTJaNE1VUnpRa1pIVVRKSGNYUTRjamxVVFEwS2FXcDBUbGRRYWk5Nk5XaDZZVWhOV0ZjMEwyaDBjVGRaDQphMDB4Ykdad1VtWnVZMlJ4ZWxWaVpXaHJOVFUzUkVKaFlVRjFaVVJUWjJkcmRHbFpEUXB0U1hwNU0yOWFLek5QVERWNWJsaExjMHBqDQpiRlUwZFdkTFUxQnFWbVZ4TmpBNVNtMUJZeXRtVjFvdmJEQlFSbFZyZW5wNFNESndSbnBaZGtJTkNsRnJWMGRCZHpGUVkyOWxZVzlXDQpjVXB0SzFrNWMyWm5hRmx4YjJOVVVsWkpWa05DYnpaRVYzbFpNVUY0VDFkbWVXMVBlbUY0VmpGQlpGbEZhdzBLUm1wRE5FMW5hbFp5DQpXWEZYYnl0VVpUbHFUbE5oTWpoclZWbzNWWGRNYVZwaldWZFBiMmxEUmpGelVuUnFRVVpzUW1aQ1NWZEhMMFF3VEdobURRcHFTV1Y2DQpWbFU1THk5cFVWVmtRbm9yVEc5a1JqQldUVFYzTmxGbFVVVkhOR05sU1hkWlZrdFJRV1JoVGxScE5HZG1VMUkzTm1aVFdXOXVaRklODQpDbWhXZW5SYVRtaDVXRnBaYmxNelZXTXhORTlVUVM4MlJYSkNLek5qYUVSRmVWRldTMjQyU0U1emIwY3lLeXRCZUZBMVVXaHNUelYwDQpTR1JaTHcwS1NVWlRVRmg2WVhabWRUQmlUaTl0VTNoaUwwbzNZV1UxU1V4cGFrTnVSR0ZLSzI1TlNFSjVlVGRhWjFCRlZXVlNlbmxKDQpLekIzTmpSb1JtaGhEUXB0VGtGb2JrcFpTMDVRYTBSU1ZXeGFjbFZQTWt0cVpWVkljbllyUjNWa2VsWlRSbEp0ZWtzeWRWZ3phbXhsDQpTR1pSZWt4SWVFNUJWekl2VlV3TkNtUkhjVEYxWkZoRksyOXlSRTl6YlhkMVpFaG5XRlZyU2l0WlVHWXZhM0V3VlVwTlpqQnFaMU5EDQpNWGx3U1RNMFVHWkRVWEphZEhkSGVsVlRjUTBLTlV4eE1qUkZUV3BKYlc5QlJVNUVPSEZMTkU1d1FWVXZibWh4YkRobEsxcE5jekJNDQpaVlJPUW0xVmVFRmFiSEJOTUhwU1RYTXJTa2NyVEVndkRRcFFSVW96TVdJMWMwbzNZa0U0VVRaeE1uZElSa1ZZT0V3NFEydE1aREE0DQpZMXAwZEhjMlJVOVJPVzFLT1hjMlZ6RTJaSFZXU21SeFExbE9jRmNOQ25CWUsyMTFOVzVJVEVaSloxQklXVTlDUmpjeU4wdENkV1EyDQpORU5aY0RCYU1YVlNlbkptY0ZCMGQxbEVkR3RGZVcxU2JqVnNWazUzVjBkMFN3MEtjVXBwS3pWbmFIZzJOMDFtT0hscGQySm1RMVZHDQpPRFl2T0RoWGIwWlRTM1J3YmpOME5HOU9lRzg1ZG5CWVZsQTJWbVpwYzJsNWRrWk1abGhERFFwaFVVNHlRMVJXYzNoQ2JHTllXVGhHDQpWVTFFZGt3M1dTdDFTV1pWYmxGVlozZzVjMHhWVURZdmJXTXdXRVlyVXpsd00yOUpTbWN4U1ZSNGNHa05DazVxZDNnMk1uZENVRU56DQpRMHRxTVVOVFJrSklURVpwZWpOUVduVTRjbWs0YlZaYVNDOVVUa2R2WkdwUWEzRXdUVmRqYmt0UWNXOWFZbmw0VXcwS01WSmFla0pSDQphWGhPWVRCdlZGWjFOVmhrT1dWMVptUmplVE5KZWtWRWMwTkxhSGhzTHpWSE5VVlJNR2hPUWtaME5rTlVRVlpEVTJ0UGMzcHZEUXBDDQpTeTlOTUcxcFduRXZOV0poVTBscmJtMVljbkJPVlhOYVQzaFllRkJTZEZFMVJEVmpUMGMzYWtOTE1uVmFRbE5NYlRKU04zcHJaWE51DQpRM2dOQ2tseVUxRlJPVk56VEhodGFXZ3diMjk2ZDJwWmJHczJVRlZIYlZSQk5YcGpVbmhUTVU1TFNIZFpla0V6UldkMVFqVnJTVlpzDQpLMlozZUhvM01nMEtaMU55TmtsdFYweDNMMmhzVm1kTmFGWlNRVmN2TDJZeWRYRnFZbFYzTW05TlEyUkVSVGhFZW0wcmN6bEhaa0ZKDQpMekJ6V210TVdrVjRNMFl2RFFwNVpuSndjblJ2YmpGVVFuVnlTVEl2WjFWbk4zcElOVTB4TDNVMFkwNVJhREZzY25WTlYyNW1hSFl3DQpaa2wzZVhCclNtbERWbVJRZFhORlRERU5DbkJVYTBoRVJtMXJXWE50TldoUVRYWjVNelIzWTFGeFNsaDJWbU52VVhoa2NsazBaV1JxDQpWM1l3UVRkNk9HZzVXR3R6T1VaR0wxUmFiRlJtTmcwS2ExQjBabk5JYnpkWGFVZEhWMUpFTURCV1FYVkJNbWRMY1VFeVVsaGxlbmxIDQpSM2xJVTJFd1UyVlJOMlUyUlU5SkwzbzRlVGt6VFVWME5UaFlEUXBqZFZodWMyNWhWWEJ3Vld0eE1FaHNORXd6UlZCd1ZqUkRNRzlUDQpNRFJqTVc1UlZYVlhiVFY2UzBSVVZqVm1XRWt2TkRGMVZXZFpNM2xNYzAwTkNqQmhabTk2Wmt0b2QwMTNhMHBSU0VSWlFTOTRWMnd6DQpUbVZKTW5KdFExVTBUSFUxU1hFMEswNXBaRUZvWm5Wd2VqbGtaWEEwY1Zwb1dGSnBlUTBLUzJ3dmMxcFlTRU5hUnpjcmRHdHpWRTB2DQpZbVpCY2xsSFF5OURTbUZMVmtnMVNFdG1VVzVwVTBzeFQwaFNUM3BXUm1sT1IydDNLMDk2V0hST0RRcHpMMUJpZVV4bWRHTklObWRaDQpPVUpQVDB3NFNUUTNPRmx0UjBRME5VTkpjWEpYZWtGV1ppdEtaV3R6WkVGbGNIYzRXVzFXVUZnNWFXWkdVVm9OQ21kb2JYZGFPRTlYDQpVRk5KWjJsaGNFTkJlbXR1WTIwdlUwdFBiSGh4YWxsa1dqQjJZVTVrVDNaTFFrUlZiRUZCUTFabFExYzBWWGxHTjJzclp3MEtkVGRDDQpUbkZGYUhseU1YSkJReXRUVFVoNUwzcGFSV0ZhZDBnNWRsRjZXREE1YTA1bFVsbzBTSGhqVEZOTFJtNVVhRXA1UTJWNmEybzRSR2RLDQpEUXBoVjJONFpGTlhiVEpCWm1keFdrVXhRWEpVTmtNeWNHaHJPSE5yZVRKRk4wY3JWbFp3VnpFd1VsQkdjV3BhU0RKRmRHUkZRaThyDQphakpMYjFRTkNqaFVXbmx4Y25KUloxVTRSRnAzZEVSNkswVnBOVFpQUjNsb2VFNW9Va1poZGsxaFRXbE9SV0ZqV0dGYVFUUkZNM0JxDQpOa0YzTTFseWJFa3hkQTBLWTFoS1VUWk5RemN6TjJoek5VSmxSV1JzUm1oa0sxRllaSHA2UjJRd2RsQlpRVWxJTDJ0dUswaDNVQzl5DQpRVGhPVkU1VGRTdG5aRk5TUzFGdURRcG9VMUYzVVRjeldsUTFkbEV3ZDNSRk4xZGpUamxQTHpsSlowNTNla3BXTVVNMWIzbzFZVTVhDQpVVWxPWVUwMk1GbFJVVnBvT0c1SFFpdEdLMHNOQ21GWVJVMUZhR3BJVHpVNWFtZFRVWE5aZG1KVlowaFRVa05JTWtseE1FbDZhRmxWDQpjWE42VkZsV1VDdG5kMmxtU25WRGJrdElTWGx5WWpKbVdnMEtWbmRzZGpOS1FVWlFPVVZxUkRCRVRFdHljVXByZFV0SWRYVTVObmRDDQpURVZxYUdkcWJ6bDBkMEZhYVdzM1QycFFMMGROTmtwb1ptTndkeTh6RFFwQ1NVZFdaM2c1YkVad05HbEtZMHRSYWtGSGVHRjNhMVZ6DQpOelY1WkRsU1VXMUlaV2h6WmtSeVRFOVpZV1UxVjBoalVtTmtabUZtWWs5aVdVWU5DbWN6TkVOa0wwVkJhMWcwWWtvNFpWb3dabE5SDQpiRVp3ZVROSldVaEpaM2RGVUdnNFJFaE1NekZTUWtWUkwzUjJWbE5HVEVsbmRtbFhaMEV5VFEwS1dHRTJabTRyVmtaSWFsY3hiRWh5DQpWR3BMYmpGdFZYUnVZMVExYm1kNE5rRTFjVVlyV1dOSGFtMUlUVmsxU21GRWJERXpSbWMwYnk5RVJVVmpEUXBvYUhscE5rNXBhMEZIDQpiamRCUjI5TEx6WTJlRk5DY0dndlRWRllLMnBOVmpoWVV6VXdjMmhQVDJ4MlYxazVZVzF2ZUdSNFR6SnRiVmx1TVVRTkNuSldUMDFuDQpVMjh6ZUc1Qk9XUjJkM294UzJ0RGEzZGtSbWRIYkRWc01YcDZWMEpvYjNZMFFXMVlUMHBWTkdkV1FrMVNVeTl4YXk4M2NteGlSUTBLDQpTQzkzWlZWNVpuZFFTVWMzUVc4MVkweHRSRU5sVnpsamF6UkpUa0Z3YjFKSVdrOXpSRzlKU0ROTGNuWkdkMHBtVG5CclRrTk9XV1ZyDQphRmhIRFFvNVkwaENRWGx3TlZOeU1IZFpUMWN6VDNaaVYyMUJNMkZPYlRsdE0wVlBNMmRLVlhwVlJpOVBVbkl4TkZWMFkweElkVEoyDQpTak5zUTJwMWF6Y05DbFUyYVRGRlZsVlBXREpxYVhaTk1UZFlObVZYTW1kek1UTXdibVpGZGs5elMzUXZOR1ZhUTI5dlZGWnZRWGh0DQpOSEp3WkZBclNVWldjVE5QYXcwS1pITXlXVXQwVEVRNEwwRTVVazl6Tld4M1JrUlFXRTlpUTFoc1VYcHpaa3BGYjBKelVVMWpSMnRGDQpXRWRPUVdoalptTmlWRkpwWWpWUVltVk9EUW80WjFwcmExRnVkVWRyT0ZSSGMydHRlbUZSVXpsa1lYWjRVVVJWUWpCUlNFb3habVpSDQpVa2hpYmpWbmFIbFZUVzA1WjA1RE5uQjNPWEZ2U2tVTkNqTXZkRmhPVkVwdmVYQnJXR294WmpGcWRVbFRNbWwwVmlzNVZsZ3lhM1ZMDQpNRGt3WTNWTVNVOW5PVXhpUjFwdlZ6VjFUMmhxYW5CR05qRlJOdzBLVG1OMlRqTklURE42TVhweVZ6Rmljbmx6U0ZkeGJ6aGFhRVZ2DQpjUzh4YzJrMlJXcFRlVGhHUnpFMVdXNVZSVmRvUkVSUU1FSm1MMjVqUVRJMkRRcFFLM2xoWkdjNFZVNTZRVFJCZGtaNlZIcDVNbU5WDQpaM2xqWm5CdGNUbHZMMlZzYm5wbUwxaDFWSFZaUW1sVVdUSlZlRGgyTVRKeGNYazJSWFFOQ2xoVldHVjRaa05LTW0xRGRISm5XRUZMDQpWMFIyTlZadlJsbHVMM1oxVEhadFZHUnpSRlpDYlhFelJFMTRNalZMY1RjeE1YRXJURk55VERSYWNnMEtXVlo0T0ZBM1UwbzVVVnBYDQpiVXB5ZUhoa1FVZERkVGRQZUdKWWVWQktZMHRMWTJ0SE5UVlFPSGg1T0hvd0wxVTVPWFJzZWtwRmNVOXhhbFoxRFFwS1RYaERla3R2DQpWa2hhYjA0eFJXRmFZbmcwZVVSMVRHSnpkVWhZWkdkdllUTklWWGgwTWs0MldUUXhkVko0ZWxBNGFVZHhhRnBQTkdVNVNuTU5Da3BtDQpVRGw0UzJWalZFSlRkSGd4UW5aWWJrOWxPRlZ0U1hrelIyeE5iM3BXYzNGUlF6SnNUelJJUkhGWVIyWlRUbk0wZERrNGNHWTVlWFZqDQpaQTBLVFVGQ1ltbHFiQzluYjBOaFlXWnRSVXBaUm5SUmJETlpMMDFQWTBOeWRucFBWbUZFYWtKaGVGSjJUMEkwTjI4d1RVWnFlWGRqDQpNVGMwVVhwU0RRcHlXRWxJU0c5V1VFSlFXVXc1UkZkb1FYWklWSFEwTVRkR1ZVRkxhQzlRUVVoWVV6TjNiRlJoYlc1aVkyVTJRbGx5DQpUa1ZEZGpOdmNraGpXRE1OQ2taVWRuTlFhRE5ZZEVWbmVWcHNjbHBpZDA5MlNGSTRaVXgyU1ZGelZVSlVUMDFDU1ROV1JrRm5UV2xtDQpLMFpWUzA5RFpUUlhlV1J1Vm5SVk1nMEtTa3N4WTNRMWRUUlVNSEY2YzI1bVVGazFSRmROVVV0cVRFeFVXSHBPZW1OblZGTlpRamRCDQpNVzl4TVdkdlNIVlRTRkp3Ym01WU5DODFja1ZJRFFwbllYRnhhWE5qTm01c1ZXVmFjSHB0U1d0MGEwOHZUWGc1TW14cVZUQTVXRkZKDQpVVzR5ZVhGTFdVdzBkbTFxYjFFeGJYQjBkVkZNVEVkRk1GZ05DbXhLTTFadmEyZHVXVzB6V1dwUlQwdE9aM1U0U25nMmVIbE1MMVE0DQphRnBQWmxWeVZtWkxPVTkwZURnMlNIZDZhMWhYTjJ0M09YUk9hRmxoZHcwS1ZtTnhNVUZUTVdkSFYxcDBNVUpJYVVSM2VVeEpRVXhRDQpXVVZCTW1ac1ZteFpLek55WkhabWNqUk9SRlU0ZGt4RGRtaE5SRVpIVjNKRGJVMUxEUXBaV2tGRU1sSTFkMjB3VWpVeGNrWkpTa1I2DQphR1ZxZW10UWJETXdSbVZ4TVVKWVRIbEtkMmRSWlRkalVYWXJiV3MxU0d4aGJ6UjVaazgxTkRjTkNqUlJaR1pSUVM5NmNFdHdZMjVqDQpOR3BTTW1OU1kxTk9jR1FyYTBWcllWWm9jVzlUVFdOSlJtWllSRmxVTUNzMlYyUkhaMkZzY1dzNFpVZGFUdzBLU21GWWRsb3ZhbVk1DQpVME16YXk4ek4zQmFlVkkzWkd0TGIxTk1PWGN4Y0U4ek5WZzVTVmxpYWsweVRGUnBkeXRtWWs1MWFFSjZkSEkyZW5ZMERRcEhSRTVODQpNVloyYkZaWGNXNVFVamxLUVRKYWFIcHZaalZyY0hJM1FVNUNVRUZQUVdWaU56TmFRbGR0V2l0d1pHeHNkSFJPWldjemQyUmpiMWtODQpDa0ZZTDNNNU5XbFdWRlZYY1RRd1dsVmpObTU2VTJkWlNESkRWRk5UWTJ0T1lrd3pkMjVVU1U5clEwSmFSVTAxWjFkamFqUnlhek54DQpVM3BxWXcwS2FYVk1iakF4WkRKWVdXNWlWV0pRT1RCMFVFcHRSR3h5Y0RNck1rUlpaRmQzZUhONGMxSlpXRU5KVnpac1duVnRielV6DQpTa2R6TldSaWJrNUxEUXBUYWxZeFVHVmpXbkJRVGxkRlJqaFVNMHB2T0M5VGRYaE5SSFF4U0ZVd1dpczVWV1Z1UjJKRVRUUlhNM1Y0DQpabkUxVDBSRU1YSldTbVZuVDJFTkNuaEZWVWhMV21Jd2FHVlJiM1JUYWxOME5WUlBPRXBVYzJJek5YRnFOSFJ5YWtoQlNVNTRkRnBxDQpkRlJGTTFaU2JrSkdZWFprYmxGdGRuVnlWdzBLYW5RcmFVTjVlbkJRSzI1M05FRnNMMGRQYURBNGRrVXlXWFZtVDFKWGJWSjFjR3REDQpNV1k0TkU1UGRHRkRiREZUYTBOemNFSXlURFpKYjJSQ0RRcFVZbHB3S3pWRE4wMVJTVWxxVEZkTFNXRjBNMFZyWW5CS01uWXdaMHh6DQpXR2xPTTNkUFlVSnhaV1JZVTNGUVpYcFJVWFEzVmxSWU5UZFNXR3dOQ2xGck5raFpjRTFDVFVoRFRrRmlOVEZGVms5TVFuZFZNV1IwDQpZelpVUlc5aVFqY3lXR0pKU1hNNGRIWnFRM0ZtY21kdmFqazBTRzFWV1ZKM2NRMEtVbkZTUXpjMVNVUlNOVXBtVG5Rd1ZIUkhZM0lyDQpRWFU0U1Zsc1UwRTJWa28xU2xkMVdsTXdOa1YyWkVObFEwOUphWFZoT0U5dFptdFVhalpzRFFwdVUzbFdNamRZVUd4SlJ6SlRUMWhSDQpjM3BpTWxWUWJrZFhkM0Z4WTFaeU0zRXlWR3hzVUZCbEwwbDZkRmhFVkV3d1JEazNUV1ZJYVhOak9YVU5DbXc1VTJweVJXaHZWVVpODQpaRU4wVEVRclJrRlpNbmR2T1hoSmMwSkVkMXBIUlV0TGMyRmxVV2RETTBsdFFrdDVRbVZVTDFNMldGVnNiMFo2TlEwS1pIcE1Ra1pyDQpSSE5rYjNwdFIxWmxaVFJTYm1GTFVXNU9NRWxFWVZWcFp5OTJRbXBJVG5OVllYbFNiSEpoVnl0R1YxSkdSek5VYTFsYVNHTllEUXBzDQpSblZEVkhWVWVucFRjM0J5VWxOWVNqQnlka3BWY0ZaeWIxa3dkalZvUmxwSlZFeEtlWHBpYkZwVU4yY3lVRTkyUWxSMVptaFBhSE1yDQpMemNOQ205ckwwTlZiRWROVGsxWEsxZEJhalJpVmtSTFJGcHBRbUZQVldOMmExa3pOMFJ6U1VGWE5VTTBkSGhSYURSQ2EycDJMMkZ1DQpZMjFhZFdOdGRRMEtTazlHUjNWT1prNXBWRUV4VVd4eGVtOUhjVzVvTTI4emFsVlVUVE5aU2xjMVpVNHJOMk5OWm5sbVZFVlJhREptDQpRbFpvY1hZNFExUm1RamN4RFFwblluRkRjRWxHY25KQlZGUnhSazAxVEdRMVJqSXlTRGREWmpCd1VIUjVVVmgwVjNkdVowTlJZMUZ2DQpiMEZ3UlhGbWJuWlFUeXR4U0U5VFZEY05Da1ZqYzBaMk5qVm9PWGhJUmpJd1dXSkpNbWR2U1RkelVHTXJOVmxXYVZoMFpEZGxURzQwDQpOWFUyYzNoUlpYUXJZekZ0UW5Oc1dGVlVTa3RHYkEwS1RUQnpXblJJSzIxR1RFRlBOR3B4ZFZsWlExa3pTRGxTWVZNM05HMUtaM0E0DQpkMWQ0T0U4ME4zQjZaVmh4THpSVVFXSlFUVEkyY0M5NVl6Z3hEUXBKZURaNVFUQjZOMEZ4Wm1GT2VXRmhSMkpUZERKb2MyeG9SR2xHDQpiVXg1Um0wd01sZFliMGhyTkc1eVEwOTVkbUo0ZVZwMmVVSjNkbkIyUm1NTkNsY3hjRTE0TTNCb05GaEdlSG81Y0N0dE1VZE1UVmt5DQpja3QyYW1oM05FUnBReXRuY0RseVZFeDNVMFpoTmpRMlRVVkxTR3BhUTFaUFdHMHdWQTBLYlhsS1NWUlVTbVpaVlhOdGVIaGtZVGhtDQpORlJIYkVKSWVITTRaMDk0ZGtKQmRYZEpVelZNVEVjeE9HcG5jMVUwU2xwTE5qQnJNRk5KTUZOWURRcGxhVTlHVVRSclozWmpiamh2DQpaRXhHTXpGRmRYUjVhRVUxWlhSeWRqTjBPVzU2T1VsdFdGVjJiRGt2TXl0dmNHNHhOMGN4VVVOQlZtOVRVRlVOQ2t4UWRWSkNhaXRHDQpSMlJoZUdsMFIzWklaREpvVEZSSlExbFBZa054U1VsWlpsVktSRGtyYkM5bFNFMU9hSHBZWmt0M2JVRkNPWHBuZVdOelF3MEtaazVaDQpkVGxOUlZVeFIxaEVXaTlhT0dobFdraFZiVEpVVmxkeU5GazBObnB5TmpKV1RXeFVkRVY1VTAxbmNsbE1iamR0YjBOS1pVYzVOV2RUDQpEUXA1ZVRodldWUjVMMWwxYkdGbWJHdFFSVFo1VDJkb01VSjJjVWgyYVhadVpEUTFUa3hYWjFCbU5VOU9PRFZRY1Rsbk0wMU9UelZLDQpTbGhzVG5jTkNrNU9abTlDY3pnMU4yOHdZVnBIT1ZaYVNWUlZWMmdyUjJOU1JHd3JaSEpxVUd4MmVtVlNkRGt4U0ZBM1FYRnJkamt3DQpVamhDTmxjd1VHd3pTUTBLWjNSamVYbGpVMDFPUkhGaEsxVmpiR1Z6VjJKRk5rWXhVR3RaWWpGcE1Fb3lOeXREU1U5SVRqaDRkVFpPDQpaamczTkRGUlFtazRkelpNVEU5R0RRcDJMeXR6WWxGTVYxY3pjMjluTW1ZMVp6WkRjRWhwVWxCVE5GZ3lhRkY0VkVvNVoySkZMMVJ2DQpha05ZU1Vsc1JVSjFjM1UyVlVjeE5rTk5jM2tOQ2tsT1FUSlZaWGcwY2xSNldFbENWa2MzZEVjclpIUlRVMHh6ZVZKTWRtbFZWV2hODQpWVWhyUW5sc1ZURTJXbkUwUjBSRlpVZEhRa2h6VnpKWFRnMEtORGRwU0Zkb2FUSmxZVVZTYVhkSVJFRkhURGt5UTFKQ1dFNW1jMGR0DQpOM0ZrWWtGclVtWkZaVEY2Y0dwT1ZEaFRWVkprWTFSRGFtOUlRamhSRFFwRFduRlFlVXhwZVhSR1dXWkpWbmw1U3paaVdYVnpZVXRaDQpOMUZ6WlRoRU9YbFhPVFpJTkdkbk9YVkVkbGRLTlZSblNpdDRkVTB5Y1hOalRrME5DalpCVTFaeVpsVlFLM05hTmpWdmNITlpVa2RpDQpUWFZzYjIxYVpFbGlOMDRyU1VwbGNHSlFURWhVWVRGaFN6VmhXa05VTWs1MmMyMHhOMEpVU0EwS00xQXlSR0o1WWs1Q05GUldTVkZCDQpTbVZ6T1Vaa05uVTNRbE5CTjNCSlRHdExia3N4VTJaelQwOTZNa1pEZEZCSGFtMHZUbWh6TWs1TFEwUkxEUXAzWldKMVVtcE9ObXhqDQpVMlJ2UmxwWE5UaFZkVWh1WWxJM1JFa3hORmt4U1RSNGVXOXNMM3BuYWpob05WYzBRa2hVT0ZkdFpIWkpUSGxxUjA4TkNqRlhhRmxrDQpOemRIT1RaSVZqWlFWSE5HYzNkbk4ya3pibGhUUnpFMU4xUTJRM0Z3WTB4NFVFMWtWMGRhT0V0R2FXUmpVMWdyTVVsUWF6UlJOdzBLDQpUalJqTUdSdmFFTmplWFZ5ZWtabVdHaFFaWFZQU0daYWJFNW5ZMVJTWld3NE5XZGpXbkJpVWtVMGVXMU1OalJvV0hFMVNteDVTV0kwDQpSRFphRFFwVlRqUXdjVmRCYUdoVVZGbFFiVGd6T1dOUFVESndaR3Q1YWtoUVQxTlpSMnQ2VVVZMVIyOWxXa3hQT1VGd2NITkVURWdyDQpNV0puV1VGNE5Fa05DbVV3T0RGaFRVWlpTM0ZuV21wbFkxaFJWMHRYVkZwdGVGUnJkbmRKVEd0blUyRnJlRGhJTW14YWIwOXhjM0JWDQpVVGxOUzA0MFZqTlRlbEIxY2cwS1RtdzNRMFpPU25ac1YwWnNSMGRvTlRkaWIyUnJWaXRzYTAxV1pVMUJWbFJ3VkhGcU4wRk9VVzQ1DQpLemRZTWtKWVQxSlhNWGh3UVVGU1JGUnJEUXBoYkVWWGNtVm5TMkZhTTNOeFMyRklSekEyTTB0TmRuSjRRMHBMTTFvMlFWTjRhaXRsDQpWelYzYWpWSFFrOUpjMlJYWWxCelFtMURiVEJCZVM4TkNrMWpXVTA1U2tKNFNUQnZOVXhtZEhkcWFUWlpZM2hFZUZoUVYwODFPRzlHDQpPR1J6Ym05cVRHRlpUV1JtYUhSaVFreHFNVnB4Vm5keVFtSm1adzBLTXpZdk1tOW1lbmdyWW1VdlIzVm9jVmhZU1Vrek1YcDRVR0ZhDQpiWGRQUkdKcWExWkNSbVl6UWxwdlIxQXJRMDlIUVZCcU5EWmtkMmxNWm01bkRRcE5RV3B3VHpGaFprWm5kSHByYlRadlEyNUZabGhDDQpRa3RHT1c1V09UbDNSVE5SYVVVeFVqbE1aRzB3VTFaVlNIb3hZV2hyVHpNMFJYSjJNSFFOQ2t4a1VIZDNlR0p3YVhObmNteEROMk5XDQpRWGswZUdaelRERlBaM2hOUzBJMFdVeDZRell3YVZrdmJHSnlPV0V6UWsxc1ZEZEhlVTA0T0dkUFVnMEtSemRYZEZSUmJGTlFVRklyDQpOM0pMWlRobFlsUjVkblZYSzFObWRuWlBZMFY1YjNKcFZqUnBNSFF6VUVSTGQxWjFPRkZQVmpoVVIwdFVjME40RFFwblNYaENRVXR0DQpkM2hpY0ZoWmNEY3JTSEZMYm1oa2NVUm9WVVpvUTBkVVExWlRaRlZMY0NzdlpFczViakl6WTJvMEwyUjFUVWg1ZGxSTFFsWU5DbXB5DQpTbVUwUVhOdlUwZDBNMGxtTVVkaVYzQldUR3gyYWpVMFIxY3pOMlUyY1hCc1VIQnViV0pCWlRsTVRtY3pNbTUyYzNwQlNFZzNXSGhzDQpTQTBLVm5sUk1sWmFNbU0zYUVwWlNVbFhlVzh2YjI5dU1DdHhSMVJTY2tjeGJqZHVVbE16VGt0TVVWSXhkSFp3YlVOaWVIWlRabTE2DQpOM0l2Ums1NURRcFRRWEpKT0RaMVMwdE5SM04wT0ZGRFdrMXJVMnhNVDBoaE56azNaV0ZyV0dwV2JraDVia3RPU3k5dWMwSmpSRzFUDQpTR2N5U2tsR1JHcHdaWEVOQ2s1NlZWTnlNbVJyZERaNVRtTmtSRmxQTlRCUGVVdE5aa3BvUWxCdVJTOHJiRlpSYkd4UGVFa3lRVTUyDQpLemRSZVdSTFdGSnNaR3BXUkdnMmRnMEtMMUJUY1VKblRVd3JaMjVQWlRacWNVTXpOamcyU25rdlZFeGFabkJLZGs5MlExQTBVbkprDQpaa1JMU1UxSGFVdHZlV0pLS3pVeFUzTktjRTVtRFFwVk9EbHlaelZhVlU1aWNXNTNiVE5MU1ZoNlVHRmpORWRZZWxOQ2VsRlJjREJNDQplbVZKYW5kaVNqVldLMkZPZDNSdGQwZFFTVFUzWmpGWWVrTU5DbTByVG1NNVJtaG5WblJsZG5ONlptMTNhV1pRUzA4MVNGUklNMlUyDQpXR2hFTlVOa09WSkhTWEE1VURNeFYzWTJiR3RIVnk5Tk1ITXpTVlJJYncwS1ZYb3ZZMmx1T0VKM1dYbzFlRGxZTTJsbEx6TkdkekpLDQpZMjFsZEZwVVJtbDRTVU4zTDFkTWNWZGlkREJXZEZGNksweHVkbEpYTDNScWQwYzJEUXBzWlhOaE9VaFliMnRTUWl0WlRucE1Rek5DDQphelJuWkN0MVIySmljek01VEhwSlQxaE1aWHBWUlhkcVYyVmxZek5xZEdseVEyUXJVRlJ4T1drTkNteHlORE5TT1hCUFptaE5hRWxWDQpjM0pRT0dOa05GSXZUVmh2UVN0NGNqbEtlRkIwU1U1elRVOXFWWFJMWldKSE5uQnpUR0p3T1hoeFJsYzRiUTBLU1dGd05uVlJiRlp2DQphM0o2WWpCNVlXNHhVREZqVlVWSGMxVklPRkJqYWtKSFJqY3ZMMVpUVTNoa1ZuSkRNeXM1WXpSek5pdFBMMnBETkVsNERRcFRWVWRhDQpTRVZLVGtOb1VIaHNZVzFaUTBoWU5VWXJUbE5ZTjJaR2JGSnNaMHAwTUdKb09HUmhjbmgxYWpCcFZrbG9kbXhOWlZWU1lYVklMMDhODQpDbEZETVdGcVRrbDVOMmRDUjA4ek0yMTZkemxYUjNab05IaDZNRUlyUnpZM1MxRktORXN4YWtwc2VDOHpZM2wwVEd4aFNXTkVSRU15DQpia3hRUWcwS1ozUkRiRFZET0VGQk4xY3dRbko1UjI4MWRqaHFlVWhoVTNSeWFUWlNhM0p6SzNkUlVEUk9OM1ZPUkU5VVVHYzRjRTFFDQpMM1JYYm1zek4yYzJEUXBZWkVGdFVHcGxlVUpGYzFrdk9FRjVhSEZaVVRaRVVFY3JVSEZVYkVGb2JWQnFRemxCUW1SUFJuUlFOVzFJDQpVbGs1UVZKclpYTmFXV3c1ZVdRTkNtSmljMWRzWjBrME1WZDJkMkZUTVdZMlRFb3ZTbEZTUlVWbU5VOUNkbXBKUTNaMFZYVnRNM0JvDQpjWFZGUlVoT1F6UjFWamxJZERCTlltOVpWUTBLTmtoU1lUbHdUemxtTDFkb2NIRlliMDVyUlRKVldVMUhVbkpEY0c5V1NTdDZjR3RwDQpWVXBoT1VabFNHcDBUaXQ2VDFwak56bE1iMGhIUmtNekRRcDBXRXhPY0hwTVQwSjZZelZZTW0xdlVXeFNkVzAxVTBoSlpDdDZjV3hODQpPSE5EVUVwNVYxbFJUaTlQYzFCRFEzUk1iMG9yTDNWbk9UVjBXR2dOQ2pGa2JHWm9XRk5qWjNkTmN6SnNRek5pVjNZeFlTc3dUaXMxDQpkakJGYlZRNVpqaGtWeTlpWmxkb05ESnBLM3BEYlZSbWJVaEpkRU52TW1ScmJRMEtLMGh4YUdsd1FsZGlkVWRwVkdsUWVEQkhUbk52DQpaRmhKTVV0dkwxWkpXVWxQV1VaTWFqbG5UbmxQYkZKcU5FUXdUalo0YkUxNlRVSm5ZVkZ2RFFwRVVXbDBNVkJYTW01dVVVSlJaR2xIDQpMek50Ym5aMFVWVkNXRnBFVkU0eGRXcG9ZMjFETTFCTmQxaFRPSE5EYUcxb2RIYzFRMmxTTnpFek5uY05DalpPUzNaMGNWcDNOa1JLDQpVbTl6UmxZeVpGUmxTR2t2TDBnNWQwZ3dkRGhYVFZCbFMwSXZjbXRCZG1kaFdWQmtUa05QZDNaVVpYazFUVVkzT1EwS05TdHBkVUZFDQpUbFJtWVZGSVdEa3JkM1ZTYldGd1JsTTVjMXBDWmtRMFdYQTVUVXBPTkVRNVNYSklhVmxLVjI5TmQwcHRiR001U2pKdlYySllEUXAyDQpVeTlYUXpsWE9YQkRPV0Z0V0N0bFpXNUlUbGh3ZVhCV1IxY3JhV3M1Wlc5c2RHSmtNbWxpT1hSTWJFUTFhVW96VjNCc1IwWk5Ra2xtDQpZblVOQ2xONVkyNXRhakZHV0hkNk9EaHBhbTlzY1daalFVWlhjazFXTm5aR2FVdFRZVmt4VnpsMWEycHhjRk0zUlRJNFVpOUxlVU5pDQpiblpDTTB4blJRMEtZV1kyT0ZGU01sTmxTV0ZETTI1bFdHNDBTMGhsWm1ocFNHMUhTV3BvZDFSbFEzSmhibEk1WVhWcE5rMXNOVkpTDQpkUzg1UnpkSlozVTVWMkYyRFFwU1RWQTRSVU5sTTBRMWNXcGpVMEZYZUZkaVNsZE5NazVTVlRkQlJGaDZhVUpUV1RnclZXNTRhVlJoDQpTMGtyV1hWaVFYcHNOVGxvV1hkQ1RWZ05DbXRUY1VkNlpTdHZPRGhhZURGek5VTlJhMXAzWkRGeE5uaFdPVEZtV1RVNWEydGtSbGcwDQplbWx4WWpSQ1IzaHVZV1k1WTFvclRUaFZUVzFrWXcwS1EwVTJWRTB4UlRGWVRWQmpVV05JTW5kMmFUUmxVRzlvZVZGRllTOW9NMU41DQpXRll6UmxWWGIzTnhaV2RRVnpWSVptZGhSRWRpTjJKU1oxcFBEUXBuYUZZd05XeFpUVkJ0YldaTFRuZFBkV0kyVmpaV1NHNU1RM0pvDQpObEJsWkRCNmVGQnNNR2M1YVdkWWJUbEtia2RxUVhNd1pEUTNORTFzU3k4TkNsbFVVSEZFU1N0RWRsbEhOVk15WWtsdU56WjNNaTh6DQpOM3BoVTNseVVEZG9WVW80ZVVOSk1XTnJRemhzVFVReVVXVktjekpYTDNoWVRVeFJRUTBLVFc5SFFrOHpSeXRLZVRaUWVqQjBXVFZQDQpkMjU0WW5sWVVXcHBRVGRtTWlzd1ZqWlVVM2RFVlZGQ2RVeHZWVXBhTDBGcFpXWTNTRzlFVFVORERRbzFaMjVDU2tKb1FUUk5WMkpqDQpaVGdyZEZoaVZtaERNbk5DTTFSelNVd3hWelJuWkd4U1FrUkZSV0p0UmtJeGRUVkJSMUI1ZW1od2FHNVNUMndOQ25aaGMxSjRZamRMDQpPR1EyT1ZNd1dtUnVRV0Z0VlhkUldFWmtabUk1YXpkUU5rbDZPVUpOYjBremQyWXhhR2xYVms1alNtYzNSR1F2Y2k5NmVBMEtMMmxEDQpOMU41YkVRMksxa3daQ3RaZUhkWlFrMVpNMnhJWjBreFZFcFRTV1F5UlVaVVVEaHdXblp3V0ZkUk9XdHJPR2xvYXk5UFMySkZRVFJwDQpEUXA2UjNaSGNtZEdkSFpoT0ZKQldVMW5RakZLWjFjeVoxTkViWEo1TWxkYWNTczRlV0YzUm0xcFpGZDBReTlvU0VsYVFWcExTR1ZTDQpSVXg2TW5jTkNrUndXakF2VFdsT1Mwa3hlRk5aT1hSa1drZEZiVk41VG1OaVZtRk9iV1oyTm1oc05XMVJSM1Z2VEVSd2NVbGhTSFoxDQpSQ3RKU0ZKd05XWjZlQTBLWVRaYWNHMHpZM0ZJTkdaMmJsQmpjMDlSY0dRM1oxZHFhQzlJTW5Zck9Wa3laekJhVWtabFZtMUhlWGR6DQpUME5GTDBRNU1HWndTV014YWt0T0RRcFpLMlpQTlV0emNuUXhWQzlSYmxCTFVFSkJhR3hIYmtGQ1MxcE9ZamxCZEZOTVptWlhRVFZXDQpSbE5EWW1sbkswVXJlVkI0UlVWV1JGaEVOVGdOQ2xZeVVVaHJUbE5DYmtselRFZ3JjMU5RVlhFMlpGVTRWRkoxTlM5SmVUSlZjazh3DQpjMGROZVZoaGJEUkNabVkwTTIxNlJVVkNSRzVhV1UxRlZBMEtXRlpWY1UxWlVrSnpjMHRpTDJWbVNIa3lTbkl4U0doVFZrc3hNMVEwDQpVa0kwZG1RMmQwMHdTRWxITWxaWE1YZElMMVpwYjFKa1VqazFLMUF3RFFwdGNFZHBlRmRKV2pCSk9GWkdSR05WYkVZMWQxcHZkMWt2DQpPRWRhUkhaR1NVVnBPWGwxY0hWa2NXa3diV2xWWTNBelJqQm1MMlJKTjBSNVJHOE5DblF3YlhGSVZYcG1OM1JoUVhvd2JTOXFMekZrDQpVSEJ0ZG1Gbk5VRlNhVEF6UjBOVmRrUnNjMFpoTmpCdU5tdGxVVmh3VGsxSWJ5OXVOellyVmcwS2FrVnpNamhyZVRBclJYRjBVVFJUDQpkekpVWWxsNE1taFZjRWRCZW1OVVVuY3lhVE5YUzBSblVrcFdiRmxvZGpkTGRDOTNjemd6Y0ZwUmFtcDNEUXBUYUd0VGFra3JWMXByDQpkakJpUlhaVFltWm9jRUZoWldwMlFrbE5MMkZOZEZNelMxQlVRV2xqVjJ4T04ycGxUVVZSYlc1WVVYZDNNMjV5WlRZTkNsZEZjRVVyDQpXRVEyYmtaT01tdHBSalV5UTBwb2QxWnZPRXQ1WVZOa1UyUXZlbFI0UmxCb1FrUlNjMkU1WkZOc1dsbzRhSHBVVWtoeGJWZGthUTBLDQpURzVIWVc5SFlYcEdNSFZhU1RCV1Vua3JkRVJYUjNkM1NteE9ZMEZ3TlZaeFVFTnNWMkZWVG5ZNVFrZEJZMDgzUjNwSGRIWkhiMDEzDQpSV2QxRFFvMlVscGtSalpuTVdwSlQzWTBOVFEyUm5CeE4xUkJkRU42THpBMVltVjRRbE5oWkdzNFNWSlNNRzB4UTIwd1JrNTVSSEZ0DQpiSFJqTWtoWlIza05DazR3YWpock5VSnBiazFaT0VVM1pITnZUMUkzWlZaNlZrdE9ValJaV1M5dWFsUmtNbWRPYXpCbFRXcFBhRFZ4DQpiRWxqYUdsRU9FZHFVbE1yVXcwS2IySm5SakZuZFZwdmQzVTBhblYwZG5Gb01XbFNVamw2UkhVMFRVMVFRakZYU1haMGNGUkJaMVZTDQpSQ3R2UVZGeGJFNDBja05MVUdwdFNtcHNEUXA1VFVSVmNsRkZSRVJWTWt4M2RFbEVjSFJhUmxwNWFUQktkazR2Um5oYWFWYzRia2hGDQpkbkJSVlZKQmRHcEpObTlFYUdGcFlsZzRRazVTVTNvTkNqTktWSE5GU1VkU1RWUkxUbk12YURsU2JrbG5Oakp6VW01d01YVjVhM1pPDQpUVFJZUlVJdk1UaERiRlV6THpOck5TdEpjeXM0THpOTk5TOVRaUTBLTDNKTFpFOVVaV0Z4VEdsaWFITnRZbVl6VVVWUlJrcHBMM2M1DQpkVTFEYUc5cU1FOUNOMjVEVVU1TGREQTNSMWRHUWpWTFVEZDBXa0pXVGtwdURRcHplbTFKYmk5ME0yRmtaMmxPUVZwMlNtVnBaRzFMDQpSV1ZNYVRCUVEyOWllSEZrTVZKRGNHdHdlbTFoYjI1T05tMUhkRWd4WWtreE9USTJaSFVOQ2xWS1lUbEdSRlYwVWxZelluazVibE13DQpkV05vVUVReFVsTklTak5TYlRsb056VnZXbWxNUzBScGJYQlJWM0EwWkRKa1UycFJjVGxyV21GTk9RMEtRV2N4WWs5ek9IbzNjbkZyDQpXbVJEV2pKWWVHSnRRMnhzWjNkM2NFSklWRU4wYWxCa1psWmlLMVU0ZEdsWGRsaGxRM040UVRGR2RraGxNbEpQRFFwM0x6SllWekEyDQpjSHBSWkVwd2FFdzRNVkpxUkhKNWIyZElTekpQVkU4clZYUlJkbkpYVUc1WWJ6VjNUelF2TTNWMk1FbFBWVkZDT0hOelFVNE5DbWx3DQpiM2s0T0VGMFZFNHljM2xKU21WclpWVXZjMUphU2xobFVYbFBRVko0VUhsVFZESjBRa3d6Y2pVelprMUROSFJZVFVKTWJYaG5TV0V5DQpLdzBLYWtac01HODBZVEU0Y2s1eFQxSTNUbkk0WkdKRlR6WmtWSGN4Vm0xVk4wWTFNMlEwWmtFdlJHUndjR0pVUjJwbVJUaFNMMVJyDQpkMGQxY0hWTERRcFlXRGd6ZFcxUWFXdGhia1pCYUVsYVdrRkljR2RNVW1rMFduTlBaSE52ZERodmNXMXplVEZaTlRkdE4yTjFXR0pUDQpXSEozVG1OeGRreFhZbUlOQ205Uk5VZFdjVm9yVjJaRWIybG5WaXQxZUc1R2FFaEdNbmRLWjJONVp5czVWRkYzZW1kTWNtVlhWWEk0DQpialJzUnpadlZqbFJWakYzU1RkUlNBMEthMkZ3UW1veU1IQXZZbEV6VG5Gd2VGUkVSblZhYUV4eVVHVkVTVTl6UTJwcFRFeHhaVVExDQpiekJLUVVab1pqZExWM3BQVERoVGMzRlZOWE5QRFFwSWN6aGFaVWhIYW04MlUzQTRORlpIU3paNmJ6WjNUbGx3VWpaWVYyb3ZhMEZhDQpUMUI1YTJZMlUzWlRjRE5RYm5CUGMzZFhjVmxDUldWQlpXME5DbE5TUzJKUFFVcFJWalkyVGxsclEzUkRPVU5oVDBoWVEyWXJPWG94DQpWV2w0YWpSVU9GRkZPREIyYUc1M1RTdElaaTlFYm1kUlVXSndZa05KZHcwS1EzRnVLMFJVZHpGRFdUbDVSVE5NZWtOUWRXUXJibVp4DQpRM2haYUhkS1kxSjFNV3g1T0V4TVZYWmlaV2wxT1U1SVRrRnZZMWxpUkRaVWEycHpEUXBaYkN0RVQzb3piaTltYmtKR2JrUkVPRmx3DQpaRk0wTlVOVFdUWnpiMFpDUVc1aFduZHBXamRSUjJaNFZYWklkSFkxUjNaR1UwNWFkbVJFYUdjTkNsaHZNM2g2Y2twMVUxbExRazkwDQplV0UwTWxSTWRGWjFlVkkyZEcxckszUnVRWEZSV2xkQ2NFWm9VV3RrUVZacE5TdEhiRGxKVkdRdmJ5OVlOdzBLTUdvNFpETkZlRk5NDQpkMkl2VEZGdU9WZ3ZRa2RCWmt0a1N6SlRlbGwyTVRoaFZrOXJkRGhDSzB4WWRIWXdhVWdyZEhab01VbEVVVEJFVGpkVURRcE9MM05qDQplSFprUTBKQloyRktVV0o0VEd4RGFEZFdXRUpMTVdWVUwyMTRWazlXY0Voc04wUnBjbnBXZUZnemJsWlVWM1pvWkV0aEsxWnJjRFlODQpDbXRLVlVGaVJscEViMkZSZVZkbVR6VkJZM2xSZEhscVpHUnVkR05sZUhFd1RtbElRelZ5U1N0eWFrcHlZVFpEWkU5WVRrMWFUVUo1DQpSbG96ZWcwS2JqRk5VRWN5YWtwMWVETm5MMHRTYW1WT1IzTjNNbkpMWVZReU1UaGlkMWxUVTJoSmJVdEZSbTV2SzJkSmJHaG9OV1pNDQpPWGRhYmtkV2VtUXdEUXB4TVdaSmIzQmhhVVZzT0VKUlZHNWFhRzUxVFVGaFRqRklSMUJyZW14UlRGUnZWRlZOVnpaWVl6VjZaVFphDQpUMVZSYVM5SVRVRnFUVU0xVUVrTkNraFVlVGxwU21SVGFrdFpkelJvYzFWeGVXTlBSRkZLY2xVd0wzWmpMMlZhZUhWR2RGUlpZV1ZIDQpVWEZyZG1OUVQxWkpORWR0UzNjeFJVdEVNUTBLTlV0NloyZEZWekpOTjI5dllsZzRaeXRWWlV3MU5HbExRMHQ2VEhoWGFYSkdSMjlODQpRVEJHU2xCaVZqbHJRelJtVWtOa1RucElPR2cyWjFOb0RRcHZObU4xZFRONmRVdE9VMDVIVEROT1dFVk1jSEJIUmxsaVNGRXJORmxFDQpiV05RVDB0dFNqSlJNbWh2Vnk5WGJ6VlBZVmhoUlhvNFNHNUhSSFlOQ2paU1ZDOWxhMFp1UzBwUlRFaG1kamhxYkU1SE9GQlhTMjlGDQpSekI0Ym0xaGF6aDJUVTlTY1UxSlVFazRMMjlIV0ZSTlprVXJkVzVsUkdkR1dRMEtabFF4VUdaU1FsSldaVkJ1VG5od2JuRlpUbTlFDQpSbWxWY2xKeVdGbFFSSGRuT1M5bVFrNHpRV1JrZFVOeE9VSmtlVTFHUTBacmRuWXlVV3RyRFFwVmJXTmlhamxLV0RZM2FIQkZMMGxLDQpjbVowWVhwc1FWa3JUbW95UzFOdE9EYzRSV2h0U1U4eFVGWjZRWFpoV2xnNVR6QjVLMHA2V1VSTFNYWU5DbFpPUzNaemRVTjNUWEowDQpXVU12V0hSb1JVMXpUa0YyVlhodVRFeExVMFowV21kRWVHMXRNRUpwT0VKWFVGaGlWM2hKTWt0NlNVdzJaRVI1Y3cwS2VGY3lUMGxHDQphaTltYXpkc2RWWjBlWFpLTURGd2FrTjRUemxZYmxCWVZWQXhlVkJIY0hvNE1rbDZkV0paVFVaUU9XSnNWREZXUzFCTEsxbHpEUXAyDQpRblJsZFc1UmVUQTBjMmRUYURGQ2RsbHpVRkJoYlhoSGQydzFWMk55VFVoVU0wd3laSE52ZDNvdmRtRndSMVkwVjBsbVZuUjFXRmt2DQpVVEFOQ2s1UFRFOWtNakpJTUhKRFRsSjBPVE5FVFRWQ1RpdDBNMWRZVGpadE5VRmhjbmgwY21kbFdHSnhVbXhaTUV4d1RuVTBLMmxsDQpXQzlyYldsaVRBMEtObkkyWXpSdVFVNVJWbUZyYTFNeE1YcENMMjB3U0hJMlpHY3hiRTFEYUU5eWIzTkNkRGRMU1dGTVdYbE1WMHM0DQpWM1ZSYVdoQmJ5OWpNV3RqRFFwaVpFdDZPWE5uSzNndmFtOVVkbmQzVGt3eFQxUkxjbFJXVlc5Nk9YUXlaRU5sUjJoS0wwMUhXbmxCDQpiREUxYlhvemJFRktLMHNyVGtGSVNGb05Da2c0VDNNeWRraFdUMjFxZGpoVE1tb3hTRmswWnpBcmFWVnRTM2R4TUZadlJFSk5SMWRtDQpjRGhKTlhOelRTOWpaVVpDZVRZeGNVUjFUVmRCWXcwS00xSldLMUExVlRCNGFuaE9PVEpvVEZGVmFFMTVWM0pZVVZCMU5rNXZTekp3DQpVMG92UTB4bGNqQmFkRXhsVUVWdFdFNVBLMnRuY0VoNVdGRktEUXBHZDJNMVZuY3lSR2hTTjJRdlNYRjVlR05OTWxCU01IaGpaMDVZDQphbEZ4YzNsb1Yyd3lkR3hLY2pGVmRIRXdaSEI0Wm1zMlJ6bHZkVWRSVlhnTkNsWlllbU5xUWxSdlZDdG5TbWhMUkhjdmRraFVielJaDQpRM3B2V1NzMldWSm9TRmRXV0hkdmNsUnhWR05GTld4MVdrSklVRE5zY2pkb2JscDRaQTBLWmtoS2NtSkVhRlV3Vlc5Qk1WbFplVFpJDQpRMk5CZERGU1VIWXlOQ3N2TkRCSVYxUkhNRUZGYkcxS1psRldiVlF3ZEhKeFkzaDBlRm92ZUc1bkRRcHRjazUyYmtOaFQxWXpiblpTDQpkR2xSVTFoMEswaDVUMjV5T1U5eFZURlZSbUowU1dVMlZGY3daMlZDYTNKbk1YcERSMHQ2WWxacGFGaHVjbUlOQ25aTFVUVTRPV1pEDQpSQ3N3UmtOWFVEVmpjM0Z2V21GS1ptWnFZbGd3UjBGQ2NYUkxTSEIzTDFWbk5TOW1TMnRDVVM5TlYycHdka0U0TUZwTGVnMEtkbVZLDQpkVVJPWm1kcmRrbG9kMDlsVW1SU2JXUnpaMXBZZWxKVlUzQjNORkZPVkdOMmNXaE1VV3N2VTBwS05XbDBVRWh1YkdNclJuRnZaaXRqDQpEUXByYUVZM1JUWlFWR1ZZWW1STk9FMVZWMVpEYWxOaFIwdG5Oa3g1Unk4M1EzWmpiRnBFUkVWS01EUkZMekp0VUZWdU9FVTNVakpLDQpkSFJHWWk4TkNrTnBhV05UVldoNlZIbDRUQzlXWTBoS1lWY3lVR2g1ZUZoTVlURm5LemRIWkUxNmNVaDBNRzV2TmsxaVlUWkVZVTVQDQpjRGxGU21KUE9UTkZZUTBLUzJsMFRVTjFOR05QUmtsVlRrbHBhU3RoTUZsTloyMUxUSEF5V0VkR1NqWlhVamhhVUdsaldrNUhZMmMyDQpTR05OYTJocVREVnpiemRvUlVZekRRcHNVRFl4UjFoNlQwUlRWalZoTTFoSlJGWkZPRnBPWVhNdmJFeHRkV3AxV0ZGS1pFdzNVSGRhDQpPVkZKVkRNM1JGaG5WVFkxYmsxRVltMTNkVE1OQ2pNd1UxcGpUM292U20xNk1WZHFlSE5pYVRGblozTXJZak0wUjB4U0swMUxSMmhSDQpUbTlxY2sxYWJEaFFjMDFvUXpNeWJWVmpVMGhpUmxaVmNRMEtZWGhPVVhWV1dHRktaM2N2ZGpGTWNqRjNTMEpwYzFWR1MwSXdOVXBsDQpVV2x3TWpkUVIxTk1WWFkzTHpOSFJHUlhVRU5KVDJoTGJXaDBMMUpyRFFwQmJHRjNPR1paY0hweWRUSlJNRGd2VjI1WFV6WnlVekJxDQpjamhJUWtObWRsTkZLMnhGV0ZsVWRuVnhTSGwyVDB4alRUSjNSMVZTYW1obFV5c05DbEpIZEdsSE0ybHBaR3R0WVdWSmJFVmlTRXA2DQpjVlpSZUZFelJsTTNNVVkzU0dZeVpGbzJjVzR5ZURob1RXRXllVmxDTTB4SVF6aGxPSGRSU0EwS2NUQlVSR2gxVURSWFEwZHJMMFJFDQpMMWhOUWxkVWRWQnRVVnBWUTI5RmNEUXhOR1o1ZEVwWFJrRkllVUl4UjJSbVVsSm9hMlZhVDFWQ1ZIRXhEUXAxYnk5WE5WVnFlSFEzDQpWMU53YmprNWFVSmxkMUJ2VG5WSVVFc3ZVa2h4WTBKYVYyMHhiVFpzUlhoeGRqbFdXbkpOVVZGWWVYUTNUVWhpV21NTkNuVlBaRkphDQpjbkZSYVVSMFZ5OWpaalJLZDNWc1NHeFRkbFpwVEdOQ1UzTnhkelY2UVdVd1kxUnJiMDluVG5WTmVUVnhhQ3RHTldVdk5tNVFUUTBLDQpjRE5ZUjA1MWNuRjVXbkJEUkdwT2RWQnVkRmRhU2s1bWRtaFRiMk5IWjNKT2JqSk9WRVJIYkVGaWNFdFlSSEIzV1RSRUwzbFZURnBTDQpaaTlpRFFveVREVk5TM0I1VTNOT01WQjZkMnRVY0hWVVJXMWpabkJUWkdSM1RIYzVlRmxxVFNzemNrOHJOVUY0VUhWQmMwcEpaWEZDDQpibkZrUkRGSlkzSU5Da3BvYTA5aVNIUkxOa3hQT1N0U05ERkZhbmxIY2xsb2FsUkRhMUF2ZFZsUlJWUlpSWEF4YjFKVFZGWXlhVkpZDQpVRUZUVFRKRVdYbERNM05NTUEwS1FrOURZa2RqV1VsNE9VWnFTemw0V0NzNVVrRTRTa3BDVlVneVJrdFFTbVF4SzFoR2FtWmxiakU1DQpORlVyVG1KTFVFdHJlbmN4ZFZSNk9EbHVEUXBMT1hVclNYUnBTMjFWTlVkaWNFdFRiMFZtUlVSVldtRk9iMmxrVURVd01qQXdaVUZTDQpZMFJTUm1ScGVVTlVVelZUU1ZsaFdYUmpZa0UyWVhNTkNrZFFSekZSYW1KemRWcFlUMlpoVUVSa00wUjRaSFJNWmpOUVoyeGFZU3RHDQphQzlVVWpsV1dsSjVlRmw2ZWtOMFp6aHZUVWxNWVdjMk1ITlhjQTBLWVZSNU9DOWpjMVozTXpkaFVYRldXSEJNVFU1cVZtRjFRblpIDQphVTUwZHpSNlRIRmpkR2gxYVc5MFZXSllXSFZrYWtsNlZFSnBOMU4xYTI5cURRbzJVSGhYWmxoMk4xTktOVmhIUlZVdlF6QjBhREpUDQpVSHB6TVRCU2NEWktjRWhpVDBkUk5taEJVMHh4TlRkT05IVlJlbkk1VldrNVVraHNZV1lOQ21Rd2FFMWxSMGhVV1ZkTmJIRjNTVU51DQphSFF6TmtSUFVuTlhWazF3VTBjNFdXZG9WRFIzZGtoclNHZHBUa1JzY1ZWWWMxVkJUSGQwWjFwMVlnMEtURUVyVGpka1RXZEtNMmczDQpRVTgwWVhsQldsWlhaelYzY0ZsalZqWklaVEZOVjBrM1JuVjNabkptVkRGVmJFZHpiVWhLZDI5S1JqTlBSRmRxRFFwQlFtTnVVblYwDQpLM1k1UlhFeU9XdERiV3B4UlUwdlRFUnZjRzVoUlc5VlQzTlBja3g2Y1dRNE5tMUNjMHg2SzFjMlFXSjNhRFJRU2l0RGRrd05DbGRSDQpZVzVRU214cldWaFNhREpYTDFaS1lVOHpaSEZxTkdoNFUxcGFNV3hYYVZkQmJ6VTBPVlprT1hsalEyUnZWM2gxTUhWcGRuSjZjbkpPDQpSUTBLS3pnclZYTkhZV3B0WTBKd1FVaEdVRmsyUjNBd2NHUXhXVzU1VFdkNlJGUkxka3RKUzBnNVkweGhkMDVDVm5KcFpqUnZaVTF0DQpjR2RIUVRWNkRRcDZlR1JhYkc1NVpVTjJjMFkyZG0xaGVtYzVaVFZUTVRObWVESnFkRlZ1WVdRMlVuVk9aVFJ3VDJOdFdqZEljVWt3DQphWE5OYWpJdmFXaHVTbk1OQ2xOamRVMHJTa053VTJWVU9YZFBRbkpJT0VNelJ6TlRNazFQTlRKTFJ6bE9jWGxtWVROek5YcDFRMmRWDQpUM3BuUVhSTVZrdE9aRWxNZGtaeVlnMEtWMGxuSzB0bE1UQjBTRFUxTjFBMFV6ZFFaMWxvT0ZGWE4zSkJSazVyYkVGUmNIZEtheTk0DQpNRzl2TjBwVVFsTktTVFF3VlVRclMxTTFNSEJURFFwUGRTdFJURTByWkRRNU5UQnFWRVZaTlVwSmJYTnpVMmt4YkhCbVpqSndNbEk0DQpLMVZLV2pkc1QycFhSMDl4V1VWcVVFOVBiMVk1UzBoUFRrSU5DbUk0VlRSWFMwaHdNRXBWTDJGelVEZFVPRTVpUWl0aFNqQTNRVEZhDQphakV4UzFSNlMwdHRXbW9yV0hWaVMzbHhkMFV6VnpkcU5ETmlaV1E0YkEwS1QzUjJRMFZSYkVoU2RHTkJVVFZtV0VSak5UQlViazkwDQpNWFo2YzI5d05YUjZXVlZ2TjBoQk15ODJRMU5hTVRsSmNUTnJNWFZyZVdSc01FRndEUXBJWml0bGNTc3liemRsVjB3NVdHNUVjMjlzDQphVlpXVEd4TGFVbGFlRUZaYzBKWlZrcFBhM1oxZDFaMVEwSlBWbTFIZGtVMldVNTJSa3hEVms0TkNraDBZeloyVXpFeGRYY3lkVEpCDQpXVUZRY2xGbFNqRkJSbGx0UzBkc1dGcHVWVlYwWldjMGNVcHNSbkI0U0c5ak5rdENLMHN4UTFsamVFOU9UZzBLVEVsT2JGazRaMGx4DQpkM015TlVac1lUQlJUR3REZUhkMlVIRjRUWGh3TURaMldYRnFZVXRyYzBGR2RrZEliREkxYTJVeGVTOXVSRWxEY1ZOdURRcDNZbUZyDQpTR0ZLVHpaNGFVOUlhblZVV1hnM1ptZEljbWxHV2tkcmIxWlZaRWhGZFhGeFYxQlFaM1kxVVc5RGQwaGpPRkl4V0daVVRVWklieklODQpDbmhKS3l0b2FVNHdSekZ4ZVZOcWFISlFUaXRTYVRkVGNqVjJMMFZCUlZBNFdEaFdibmR3WTJNdk5IQTNUVlF4YW1GME5tRjRRV2hZDQpSRE5FYkEwS1JqaDRjVnBLZDBvM1VYaEhNbVF2TkZJeVZWbHhUbEJoUkRObk9XcGpOVGRyU25sbVJuVTRaVGxZWjBKaFIzbzJWRTFMDQplVEpvYzBWc1ZuZHdEUXB2VFd4NlJtRkZSbmxGYUZWSGFEVjVUV1F5UmxoRWF6aElkV3hFYjFCc2NXUlhRVkpCTkhaTk1ERXZlakF5DQpaREZDWVhNd1VVdEZTV05rUVVVTkNtTnpWR3NyVDJSRlZHdG1PVTU1YzBGeU1UTmxUblpwZEZsTE9XOUphblV6VEZwdlJ5OTBabm80DQpObU13TWtoYVpscHJRVkpOY2pJNU5GbDBhdzBLZVZsT1lUQlFNRkU1Y0ZwMGJqRldXbkp3UVdjdlJXTkRVblpxZG1JMWJrZFJPRGN2DQpRVzB3TVRRNU1qZERTalUzUVV0Sk1FMUVhM0ZGVFRsSURRcFpjWGxETURsTFdqTllSV2hJYVhKd2VsUlpVMHhaY1had05UWnpOR2cxDQpTbUpUZVZSMGFXbEJTMnhtUTJJNVQwdDFhbklyVVV4QlRVaGpkbFFOQ2pNeFkyVlpVRGRaZUV4UVpuUm5VMVJ0Y1VSSFJqYzNVM3BtDQpkVzk1ZUVaM1NFRnpiVEJSUW1wU1FXazVlR2RhTmxwQmNHdFpRekZSYlVobU1nMEthMGRLTlVGVU1FeFVSVllyZFRoaVlqTnlTM2xrDQpjRE5EWTBSakt6QXdjamh4ZDNweGVrWlVhbmRSZDJWU2FrRjFRVm92V2twTFN6VmhOVmhDRFFwd2N5OUhTMlV3ZDNSbGJsbzBka296DQpZa2xVVTBkT1FuZGtibXhqT1VScU5rSTBRVEE1YkRSQlpEUlhZbXd2U2tkdE1IQTVlak5XU1V4cVNXd05DblYxWlROcU5YQlJZMDg1DQpXWHBPTDJSYVNGbzJjRmh4TjNSWVZteHZiM2RsVmpKR2MzcFhRbk41T0V4dloyMXVXbVZJU0dGa2NqbGtibXcxV1EwS1dEQnpibmhsDQpPVU13UjJsS2VtTkxLM2d5YlZoc2VVaFNNMEZRUzFWMFJTdEpXWE5pUkhobmNUVmFNeTl1Y21jMmJGbG5OekZhVDI1SFduWlhEUXA1DQpSVVY1VkhSR0syNW1VVkY2WW5sMlprd3ZhV1F3UWtwdlVETjBXWFJSUzI1UVRFcHJZVTR2UzJWd09VZzFjMnRLV2tWMVdIVTVZa1UyDQpSRVVOQ25SSWFuUk5jM0pUV1V4UmEybFROMXBtU1dWVFRGSnhOa3RFYlZocFZrVlFWRTg1SzJVcmNtVlZiMGhHYTJwQ1dUaEJXVVZtDQphbU5CUkV4REx3MEtSemhaYW5Ga1kyd3hSamQwWW5aR05saDVZMUJIZDNCdlNsUllhMDlzWjJ4dGJtbzNSRmhuVmpCeVNYaEJObE55DQpTMFZFUjNSUGFFdEpNVXBSRFFwd2FVeE5Ra1ExYVdGYWMwUkhOU3M1VGk5SE1IWnphVTVNTlROeE9UTlNTRGRLVXpCRGEybERiM0owDQpja3RvTW5GUlRFNXJla1J3VFZvMU0yZ05Da1ZGY1ZKR1kyVnNXRkZrYlVKYVFVUlBNbTluUVhBNGN6ZEpXV0ZRVG1abk1saFdiSFJyDQplWFpWUlZaRVlXNWhNeTlHVkdKdFREUXhOVzVpYkEwS2QwcHdaWHAwTHpBMFNWSjNObkE0UlRKRWJVaHFNVVpQV1ZsMFVqbEpkRlJwDQpjbU00YzBwTlpYTlhLM0pVTUc4NVN6TnlTbmh5VWtWdWJVdHFEUXBYUzJ0TVZFVjRhRFpQT1ZwM09IRmlORFpGZVhBMFdrVXdWbXd6DQpSME5RVDIxWlptUkpORUpaTm5WMVFUUmxSMWhXVmk5NVFsUjFTV3RZUzBvTkNrbHVOMnhpYzBZNWMzSTNVMVY0VTBOVk9FNU1iVlF6DQpjamxaVVVrNWVXOVdPR2d5Y21Sd2MySmxPU3RHTUZvMVNFRkdjalZCYjJ0dVpqQkRjZzBLTXpGRVpFZzVRVTU2Y2tkTlIxTktVMFZGDQpXaTkxVGs1MWRYQnlhMVoxV0V0a09XTllVRUZITjFwUWNHOVdXVnBYYUdzMU0ydDNaelJXS3pWM0RRcDViWG9yVjI0d1ZWbG5aWFpFDQpWWFJ4YjFGSWNVcHlOa3BCVkRsM1J6TkxVbXhGTW5kVlJtOXNUblZNZWxoMFpraFpTbEIwZDBsaWREQjBUa1VOQ25kQ1FsRk1ibFprDQpMMUJ5YTNwb00wNDVjMUJPT1Vac00wSlFiMjFxY2xCNVpsSkdkRTV2YTNnMmNrRlVhRko0VVhkVFUzbzNNVWxNY1dGNFlRMEtVMUY0DQplVXhaTmtGWVQwUkNMMlJpWjFNcmFYbHJNRk40VjJobWEwdFFNMXBYUnpGSGRWQXlXalkxUm5WME9GVXdRVmN3YjFaT2VVRTRjR1pzDQpEUXBsYTNkak1IbDZPVEEzWm1oWGRUUndOMnc0TXpGWFUyZGFNV2hYVFV4ck1EWnNUWGR5YWtKTE4wbHpiRlZOYlhrM2QydFZPRWxCDQpaMmRQV2tjTkNuWndNM1k0YzNoS2RsbG9hVzVyS3poc01UVldia05DY0RoWGNIbDBjakpsYmtOWmVpdE5URk4zYlVneGFXOUlMekJwDQpkM0JJYkVNclFtWTJaQTBLZUd4Vk56ZHRLekZPYUVZdlJGRktTVWh1VTBGWWNuSlhiRlpIWnpadVNsTktObEZ3VTNsRk9VTk9halJ2DQpiRmRxWTA1V1ZUYzVTblpLU1VaM0RRcFNSV3BxTWxOMUwzcElWMnRCWkVSTE5UaGtjREZ3VkcxeGNTOXlka1pEUjBGamJGcFhNSE54DQpZVzFEYTNkaVNGRmtPWEEyTHpsWmJFSlFNazROQ2tsa05YRnlVeXN5WlU1TVJFdHVNSEJyY1c1elFXWXJXSE4xUjNkMFMwbEhRWGwyDQpkVGRGZWxkcE5GSXZTRzEzT0VabFZUVkZUSFZvUkZCRE1RMEtUMFZKYXpSMFV6UlljSFpQVG5kVU1EWlhhV1JQV1ZOVGRFOXFUMVJNDQpVRTF2WlhkMmNHeHdjSEJFU21KV1lXcDZNWFpNVkhoTWVEaHFSbFJ0RFFwU1ZUaGhOWFZOTkhCWFRsWk9NVGczU21SMVZVSlhTMnRKDQpkVVpzYkdSYWQzQlJjMjkxZW5ac1dEQllOekZUVXk5dGVFVjVjRFJMU1ZjNE0yRU5DbGd2Y1VSaGRtUlBUME56ZGxOWmNDOXBNWE5TDQplbHBZZDJscmNFVktjMFJuTkhORWNreHJaVE12VERrMlR6aGtObE42U3pSdVEydG5XV3dyWXcwS1VrRlpVbWxTY0hSWGFtSkxRemRNDQpLMkpFYlhwNlEyUnRMMEZFT1hwbFVYUjVZbXB5YlU5dVRVVkZZVXBHTWtOVU9FSjZVMUZNZVZSS2RHSlhEUXA2YldKcWFreFdVVWt6DQphVWRNUld4ek5VSktWM2h1V2k5RWF6YzVNM0pCU2xkWlpVY3hVRUkyY0VGT0x6WTRVQzk0THpGUmVWWk9jbm92UlhZTkNqZDZWblFyDQpVRXBMZDBZelprVTRaWEpPYlZkS1JVUmxjM2MyZFZaYVFWazNaazFhUjFCQ0wwZ3lWRTVzYVd4bmVURkVka0lyU1ZOSVMxbERSZzBLDQpkbEl4VUVKS05EUkJWR1JyZGtGdU9WRlNSMFpTZW1WUk9Wa3hZM0ZSY2tKWGRra3ZhemRhTnpSck0zWldkVFUyVEdZMk4wSnJkbFZ5DQpTM05ORFFwbUt6VXhVblZZTDNCbVZXVXZNMVJNVjBkNmFHa3pVRFpSUkdkNWEwbFlPR3g1ZUdoeFlrc3JTRlpHUjFoM2EyVTViVEJpDQpXVkk0VXpoR2VrY05DaXRqWjJkdVNXRjJiRUY0TDB0blZYVjZZVnBJU21KclNFVXZLeTgyWWpWbWMwVkZhVU4wZFhWUGVucG1aMnBpDQpha3N3TUUxVWRFWnhlR2hGUkEwS2NFSlpaVkU0V0ZWWVZuVm9VSGxCUVVSSmRYVndkMUJZYVdoT2NFZHdabFE1WTNaM04xTlNSalpGDQpiVEk1T0ZCRFZYSmtSMGxUWW1SRFZuVTREUXBPTDFwR1MzVXdRVkpGTlM5dVkxWmtNMUF4WlZJeVIycHJaM0ppU0dOYU4ydzVTRmh2DQpOR3BXTVUxdmJGQnlla1IwV0RkQ1NsRktOM2hyZDAwTkNuTmhTamhDUzNJclltY3hlamhYVnpSYWNXNHJUbTVKV0ZJeE4xaDBiVlE0DQpaVTQ0V2sxbU0yMWlkV2xJYTFORFVrbDFXRFZVVTFGWmRXbGhNdzBLU1RWTWFrbEdXRlpJWTFka05XeG5OSGNyUjA5M2FURlBOM0p3DQpaQ3Q0WjNsUFNISTNXVk00U2tsMWIyNUJXV293T0U5M1FXOXlaVGd5TjBscERRcFllRlV2TWs0eVRFVklZMVppUTBoSmF6VjBSWFoyDQplRkIwV0ZGb1VraDVXRkZvZFhCNkwxUnZaMDVxVVVwdVVVNXVhamhzVWtGS1ZrSkhRMFVOQ2k5WFQyeHdNelZLVHl0RGVVOTVXRUZCDQplVTVOVWxWc1QzVk9ka2t3YzBWUlJ5czFRMHBaVkROWVNuUXdTbVV2Y0RKb1ZpOXNkMncwVGtaVVJRMEtNV3dyVW5OQ2JETlpObWhEDQpUM2hNTHpkYVdYbG1hREpOVVZSUFRXOW1RV0V6Tldkd1dWQXpSRWMzYkdZemVtVnZWMHh6V0ZoS1NEUkxNMjg0RFFwS2FUSnBaQ3RvDQpVMnRUVDFOellTOVVabkJLVFRKME0wSnNha1puU1dneVFTODRRek5yZHpaVk1WQkxkbWhWUldWRk16RjFiWGhhVDB0RlpYa05DbkZRDQphVFZTVFROTFdrMUdhSGRPWmtoQ1JVSlJVMlJxYTA5YVpYVlJWR3hzY2xCWWFIZDJRMWRzV2xOSWRVTmlNbVF4VEdkVlVXdGFUMEpMDQpVdzBLYWxFeE5uazBkRUY2YTJaS2QzWkZjRVpqUkc5U1NraHZiRGt5YzJWa1pqbEphVVZLU1M4MVdHMTVPRVpJUVV0M0wzUjVLMFJYDQpZa2RyY0d3eURRcHhaM2hDZGpSSk4xcGpkMnhYYWxBeFRUSkZWVk0zTkVGMGQyWXJOemQwYkhwRWNqaDNWbk5qVFdSM2VFOUpablJyDQpjbWxNWjBrM1JrUjNLMmtOQ205blduSnljRGRvZG00dlNHWlJWVVI0ZVRCd0wyNU1ibXhMUlhwTU1FaGxNbmxOUldWaGFUVkxSR2xqDQpNU3RETlRsWFlrbEZLM3BXVVZFNWFnMEtObEp3ZEZORGVuaHZTR0poTWtWNWNIZDZXakEzTVVoQmFrOWljVmRHZVRkeWR6Rk1jVkIyDQphelJXVEM4MlpVZE5RV3BFVG5KcU5tcFRTVWhZRFFvMk1WVndOa2dyUjNKcVQwOUthR3hFWlhkQk4zSXlkamhJTkhSU1IySjVWaTk2DQpjM3AyWjBoWE0zcE9OR2xRTWtaQk5VaHBRMWd5ZUhselkzQU5DbmhyY2s4eWQxSmFRa1Z4UTJNMGRtb3pWMDV6Tms1dFN6QjNRbVY1DQpjM015T0ZKWmN6WlhhRVZXZDIxcGEyWmxjM05XVm1oNk4xaHFZVEpMU2cwS2F6bFlNRE54VUZnMldVazNUSHBhU25Sc2NHRlBaVkZQDQpOVUkwVDBaMk5IZExNbWQ2V25SVk1rZzVlbE5NYm5kamVrcFJNakpNZEcxRVFUSkpEUXBrVTB0U05qQkNPRVprVVRsUE0wMWlTMVl6DQpOWEpvYTJGd2IxaFNjVVkzVEVWSlExRm5jelpDUzNkUmRsSnhRVEprTjJOalJEZEtjQ3RUVTNBTkNsbGpSMUYyZGt0YVEydFRSRGhCDQpka0paY204dlRua3dVR2xQTVV4TmNraFdaekJKYjNGTFJUTkxiREJaU1hkbU5HeGtXRlVyV2tWTFYybFNRdzBLWnpKTmNsVTRjRlF5DQpWM3BpTW5KUloxTjRSR1J2UWt4VVkyNDNXRlZwSzBKWlZ5c3dSR2hWYVhGcVR6RllRVU15Y2pZMVUyWjBObTFRUVVsc0RRbzVZUzkwDQpRbWswY1M4d2VHbDZlakZuY2k5Q0swbFdOV2Q0UzFKWGIwMDNZVVp0YkRoV2FXRjBlRlJ0WTBGTU9VUTBOelZLY0RZNGFGRnFNMU1ODQpDaXR5ZDNVelkydEZha1ZuUW5oME1qbE9aVVJpV0RaTVpXOXdVR013Um5ONFRqbENkWGhwVDNwT05tVjZTMkY0ZVdkdVdsaHdiekZqDQpaVGQwZUEwS2FHeEZTVkZNV2tWdmIxVlNRVk5CWkU1QkswUXpiblJVYVZaR1pUTkphRmxLZVRoSU4zSXdWbkV4U1ZsM09WUlZiVVZxDQpUbmRCVFhseVJ6UlNEUXBwZUUxU1RVTlJlRE1yWjFOSmEzSTBNbFJuTHpGaVNIcEhZV2gyTm1ReVFrVk5heTk0VUhFMFFtVkphVlJNDQpPVE54Vm01TlVGZ3lkMUJPWlhrTkNuVjZOVGhRWWl0QmJGTmhSMGhCY0c1RlRFTXlhemhpUkhSSlprUndjMUkwWkU1T1VIbHlkWHB4DQpjVFZzU1ZkaGRsSTJNbEIyVm10MWFUVk5aQTBLVW10c2VYQnVXUzlwWTJ4UlppdEdlRTVDTWsxT1dWZHBTbGRVWmtJeFlVa3pZelJGDQpRbkZtYzFkUVNFOVlRMG95VVRsWmFsRktNVEJSVkVSSERRcGlTVmxuWW1KaFZISTRVazB2Tnl0R01rRXZWMjlvUldSeldXWTNPRVZMDQpSMFJCVVVSaGFHNTZjMEZvVEZacFdWcHRRMVJDWW10a1pETTFaWFlOQ2tSWldYTmFVbmRKVDFSdGJXaFZSazVDVXpjeWNrcFVUR3BHDQpOMk5oVUhjdlNGRjNNMlJCY3pkeU0wZ3ZaMGRMYkhBMUsxRmtjMk5VVEM5WFRBMEtZa1l5SzJScFFXNXNlR1ZhWjIxeWVWUTFlWGQwDQpZbVkxT1Zsb2JYVlZhREYxVVN0WE1YaEJlVEJIT0c1alIweFhUV0pDZGtnNFFXTlRNWEUxRFFweVVIaERaMFZWTjFwb1UzbHVhVUZRDQpOWE5QTjBka2VTOXliazU2V1Vsd2RXOWFSbE55VFhKWlVHaFFlV1JsU25vM1VWbHdhRFZ3Y2pWUmVYUU5DalpsTjFaTGNHVm9VRTk1DQpRbGhLT1VWd2NFSlplV3gwVmpOSFpWcDNiMVoxU3pGNFZESkdaMGRSWXpObFYwOVVLMUJ5YWxCemRGSmhXRnBFTkEwS01sUXJhM0V6DQpkV0Z1YjJ4U1JUWjBNMWxHU3l0cVZXdHBSMWx1Ym5KTVUwOVhXRTA0TUVsS0t6SkZkSEpUWkdFMGEzSnpiVlJMVVN0TlFsQTNEUXBRDQpSRTluWm5CVVVIQkdTbUZ3VGxkWllVbEphM2hLYjBOeFluRllTa2hCYkZoU1RVTndVVlF2VkhWck0xZElPV2hUYTJkR1RGVlFTV1JaDQpWbk1OQ2t4WFNXUkhiRkpGTkhSSFpHMTBaVlZTUzJ0V2ExUktaVFpJV2psS2RtWXJka1ZXUm5KR01rRXdha01yY1VOMmRHVmhXV0ZxDQpTazV0TTFoSk9BMEtMekpxUVZCUk9YRXhhbHBWYzBOa1pXaEtiRXBFWW1OdGVpc3pjRWhOVTNaNGVUSjRkbHBJU0dSVE0yNUdOMll3DQpNemczYlVsMFNEWlNRWEI0RFFwRVkycGxNVFkzUmpaa2NtbzRVRGhOTDJGM0wxUlBXVmxVYlZWSWVFTjBiRnBSU2tSaVMxaExTa1ppDQpSSFpVYlV0aVZUQkNWRXhTVEVOSE9Gb05Da1l5UXl0cE0xY3lVV3BMYVU5MGJXRkplbkpqVTNsaWJHVjVjeTkyVW5wSWVYWXZaRlExDQpibVZWUVdOYVlXWXdkRlZzYm5kb1VtZFdjVVpCZWcwS2FDdG1NV05yT1d0b2NVUlhVM2wwZG14S05Hd3JjRXBRWTNGUGJsRTRUMEZIDQpiVlU0V0VKemJWbHdTRlV2TDNwRGJsWXhLekZLSzFKeFJIQmFEUXA2Y0ROV1UyNURSRVpuZWxkQmEzSTVXWGRqZHk5MllsVnVlVkJMDQpXVGRHUkhkaFJEZE1XbkoyWm1WcldEbG5iRlozVG1kd1pEZ3dkbWRtZDJ3TkNrMXVVRkZSUkZSc2RITk9USE5GYkhJclpGWlZTMGhXDQpRMVZYUVZSdFFWSlhUV1l2TjFkYVZsVXZOakpIYjI5bFQySlRiM2xyTjBwcVEzQmpOUTBLTTB4eVQzQkxTM1ZTU1RWeksyTlZZV3BVDQpabkJUWlVwcVExZHhVa2hJU1RFM1VHZEhTWGx2YW05R1pVUjRWekpEVjFOTE5uZDBLMlJJUWtRMkRRcDBTRkZ2YmpaTFpscEtPRUpuDQphakJsTUhabGIyNTNVemRKYW1oV1pXOXZkVXB5Vmk5MlFUQnRZVTlGYTFCQ1RqTnRRVXBCZEVoUGRqTmlVVThOQ2xKWGIwSXlOMGxEDQpZV1J1Y0ZKV1R6VmFVVmxsWldkME5YcHZUemhrWVRsVlRWVkdOM0J6Y0hONmMzaDVUQ3RUZFhGcGNWRkNNSEJ5YlROSWRRMEtNMkZ2DQpOMUZMZWxKa1VXRldaVWMzYjJweGMweG5Va2R1VW1WTmNrbHdVakZCVVVwWVZpOW5VbWhLZEhKS01ucFlXVVF5ZUhwelZqTjVTRU5TDQpEUXBPYlVaYUx5OXNhbVYwVFZSM2VXUkpOMjV1Y0dadFlYRkRXRTFaWjNKa05qUm1aMlpRSzBGVFRtVjNTM0oyVUZVcmFXZHVRbVptDQpPRTB6VEZRTkNtOVRlRk0yY0hWVk5GcFZTSFZDVjBoRFFYb3hNMFo0UkhSMlZFZDBOMEZYWWpodFIwZHNOVTlKTTBobE5ESk9WWEV6DQpTMnh6YmpSU1owUktPUTBLTDA5RFowOHpNbmQxYW5GTFFVeENZVTRyV25walUyVnhMM2hDV201NWQyVkZXV3hoUlRsTWVHSmxOa3hHDQpWVTVPUjFselNWY3lUa0p5VTNWbERRcGxkVzVzYkVFMVRVUTFaMnhOYlhvM2VFVkNhWE51VVRWTFl6WmhLM05rTkhOYU0wTjRhV2gyDQpLMjFCTTB0M1VYWkZaMU16U3pZelpIbE9lbFVOQ2psV2JWSnlibWt6V1daS1NUWnFiSE0wVFVOSWVDOTZjbmxXVG1NeVdsZHJVbTUyDQphMlZpYWpKMllWcE9hSEJxUjNKaVFVMDJaV3h4V0hSUFJnMEtaMjU0ZVhSaVVIZEJZa1JyWjFSV0szUjVaMWd5WlRJMVl6UndSRXByDQpWbnBWYUdKemJGTTVURWQzYmxoM1ZFVk9WbTg0TVV0UlJETkdUVXBxRFFwR01UUm9VMVpSV0cxQlVTOTJkelF2TXpSekwzQXpOMFZQDQpaMFpCZWpWcVMwZ3lMMVZYYmpWWVVEUlBORFJqUmxsaWVIVnJaWFZLZG14aGQwWU5DazFIV0ZOUWIxSnZUVzFLZUcxc1dGUnZkbmRuDQpWMWhxVlZkQ2JVWlpNREJhYTJ0cU9YQmxhRXBHZEZCa1NGQnNORUZrUVVsNloyWTFiMVIyVGcwS01WQjVSbVJLY2twUU1tMUtVRFpNDQpaRGxJV1U5cVNsaGpUVnAwTlM5bmIwSk1iemxZWjJKUk1EY3JlVEJ6V25CelRYVldPVXczTVdGbGJYWkVEUW92Y1cxTk0ycElSRVZzDQphblJCYTB0SFFrVnBOWGwxY1haclpVZElRVEJ5UmtSdlZYQkplVlJaTTFFemJYSktValZFTlVJeGVtOWthbEpqTkRVTkNtSTNZbVJaDQphR2Q2VUVaVFFrUTJVbTFqYlN0eFdteE9TVXRXZFZGTlQweGpSSGt3ZFVOVFZEVjVla3MwU0ZWSGFYbG1WVGswZUVwUFdIVmpTZzBLDQpZMVpJWVhCdlRrTTBjMDR2THpreWRGaFFkSE5pT1RWVmRGZEdhVmROTkc5b1dESm5OelZOYW5wdWJEZzBka04wYlRoMVVVOUtVM05PDQpWWFJQRFFwWFRuRlpOSEpKZG1OSE5UVnNSRWREYWtSeVdqbHZUVEJNWTJoSVNtUm1ORVZJWTFaUFdqVmtVREp3T1M5eFdDOTFjVE4yDQpMMXBKVkZaamRqUU5Da1p4TXpGdE5FOWhWbTFuVkRNMk5VaHVURzlsUTFGNE5qbENWVEF3TWpKV2RrRXlMMjFHWkZGRFZXSnRWbTAxDQpUbE15V1daTFpYZHFhRmg1TkEwS2JFaHJOek5KTW1zNFlVWnBhV3dyVUVwTGVtWkZSelV5VjNKWFdsZG9Uamg0ZFVobWJUWlFVRWRGDQpWVVowVmxWVVNWVm5kMU12ZGxNM1VUaFVEUXB3TUhRNFNUZDFWSFJUVUN0a1kwaFNkV1Z0ZFV0cU9UbExRa3hIYm5abVNXdFllazFuDQpkamRxV2xwdVpFMTVUMlJFZURsclFqVjVLemhhWmtFTkNsUmxWR2hMYlZkaU5HbzRVVWRGYlZkcFVYbzFlR2xVTXpkaWMyOTNOVWRCDQpZV2d5WjNGb1N6Sm9hQzkzY3poVU5XZHlWVTlyS3preFJFSjBWZzBLY1dkbWJUTTJXRlJpYzBWdlNWWlRiR1pJSzI1RVJEaGlUVEZzDQpSRmRoWmpCeldVWk5VMnQ0T0VOblJVZDFOMHRNZFRGbEsweEZMM2RrUTNCSERRcHJNMFl4TjJWUGJHSjJjVEJuVDNCbGJsaHJOa2hHDQphemx6ZUZOM04wNUlaM05GWmxBdmVFdDJhbEZSTjJGMGFWcDFPWFJ6UkdGd1MycHZRWGtOQ2t4clRtMXZZM3BaUVM5eVEwNU9WakJtDQpjM1JQVEZoSlZVWkJiblY0VG1kRFMydGhhbW93V2s5RVQwZHpVemhPVjB4SlkzQXpZMEl3TlhwSk53MEtabUZYV0ZkamFETmhPVFkzDQpUVkp2VlVJM2NGUXpVVnBPY2xObGRFNWFkMVY2TlcwNFMwOVlTV2RtWVRVMmNVRmhOekl6U0VWQlRrVTBWVkpFRFFwM1VtdHVhRXhZDQpUMnRIT1VadU5uSjJaR05JWVU5Sk9EbGhkSFZQYTJWM04waEhObkpZV0dodVVTODJUbVZhTW01c2NIaGxTRVZCTUVwSFZsRU5DbXBYDQpTMVpUUmpsak9HRjVlWEV3YkdzeVZrdGxPSGMyWVhnMWEyMU5NR1pxY3pST1MwVjZVeTh5VG1sUlNIZEhPSFpHTWtVdmQycE5kMFVyDQpMdzBLUTBoR05WSmtaR3RwYldkWWMycFBWRTVaTWtoRFdXSldRa1pHY0VoRE5qUnhPRVp0WjBseFVrMVJhV1kyYlc5U1kwRjJNRGN3DQpVbk5DZFZwUERRcFdjU3N4Y3pjdmJHZFBXbUpyTW05R1JUY3pjVlV6UXpKVFowUlRaWGs1V0RkNVZuQkRWM1JvUkdNclJYUkRkMGMyDQpUMlJrZG5welIzTnFja29OQ2xwb2NVVTRNU3RuWjBSSVVuUkpWSE5MUlN0SWNUbGlVMGxQVGtkaFJGcEphVTlZUjNkUFdFUmFUVzQxDQpPWFpyVERsb1dVRlRjMjlRT0M4MWNRMEtaWFZNUlhKRWNXMTBOeTkxWmxkTFR6VnlSVlJ2VHk5eWExRnliVVZ4VUhkNFRXODVRekJIDQpiWGxNYkhORFJDOHJNVVJsY0dGek9IWkdPRTAxRFFwNFNtaFRaV2xKTVdsVmMwWmlVU3RqTlZwbUt6TjFXVXRRTjJ4MmR6TlplRUpvDQpVRXgwWlRoMGNEZzVhaXN4UlZoa1NXSjZUWEl6T0ZGeldVd05DbTU2VTFOU1prOUtSV0ZzT1hGSVl6ZE9SRzFUTXpZelpVeDFVMWhMDQpZMjFLWTBKNkt5dFFRWFZOVTJkd1dIQnZaVXRHYVhsNVQyaGpWblJwVFEwS1VqRldja0oxVVZWNlUyRTRRM1p2WmpWdGF6WkRTMVJMDQplV3gwV0U1TVdYWjFXREZDWmxSbVlWUlljamt3WjJsWWRHNW9WVlpVWkd0RWVHdElEUXB4VkZnemFHMUthM0ppVml0S016TnNTVXRzDQpXVWhQU0RVdmFHY3pXRTlvTm5aRmFUWlNZM0J2UVhSeVUyOWlabmxZV0dWMU0zVk9OblV4UW5JTkNtTXlWSFJ3V0VKVmNEWnljRlZIDQpObVY1VVhKYVNtVXJWWFoyVW1SaVdrcFVlRGROVEd0bldWcFdTVXBDV1ZsQ2RXZEdMMHh6YzBNd1pHRmlLdzBLWkM5MVdWQmhVa3BMDQpWMDVYVVZkTlpEWklNR1F6UW14dFJHaFViMEZLUmxBNVdGb3dNR0ZsVGpJemEzcE1aelEzY2s5WFdtbGxTelpCV0V0UURRcHdOVEJCDQpRamRNUW5BemNrUlFaMWRUYTB4UlZUVXJNUzlHTWpCT2VESldhMFJZVFhwc1JsWmlZU3R3UWxaUWJXczBhRkZvUjNSRFV6TTVObTBODQpDbWsyZGtaelVuUTNkR0ZPYTFCd1YzaG9TVE4wUzB4alJHNHZWalZ1VVdVMk9FcDZUbk5TYzJoU1FXOU9lR1JLYm1GcllUbFFTWGh5DQpSeTlzVGcwS05uUTBjbkJZUkhWc1FrWnJjMnBNT0VKb09XRTRabEIyTmpGQk0xaE5UMFZaWlRGcWJEbHhOVk5zUlc5cFJGcE5UbEJQDQplbFE1YUZKMlZuSkhEUW9yTW5wMWFETkdRWGRyT0dKWlZtZHlTRmw2Um5OYU1WUjFOVVpJTmxkMlUwTm9hMFV5ZG5wRWMxQkRORkJNDQpaWEpNZFVOdlptODRWakoxUWxRTkNsZEtZbUp1VUZjeGExazFOakVyWkdGV1pYQkNjMEphTUROSVdqWlJha1ZrWXl0RFJrMDVVMUk0DQplWEpYUzNnd0szcENhWEpEZVRWTFZqUXhPUTBLU1VkcU5EUkhjMGRSWmsxT2RrdHJOelZCTjFWYVpuTlZiMVp4ZVRkcEswUk9PRzlJDQpNMk4zZG1WelpqQkhURkpoZWs1V2RFdGxTa2RJWmpoeURRcE9RWFpXY2xrNU5WUlNhemhNTHpOMmMxUlFkVmMwZEdKQlUxaHJOVGxDDQpkWFpMWVU5SlRIZG9LM0JLYnk5T2MzZEdNa05rVjIwM0wzVTBlVVFOQ2xwV1ZrNXZORWx6ZDB4NVRUTkpNVXB3YlU4M1VXWlRVMjkwDQplVFIxUnpNdk5tcG1VM2czVW5KMGJXRlFWV0pVWjJOcVFuQlBTeXRDUTBsUGFBMEtVbTVYWTAxQmVTdHpabmhCYWpSTWR6bHRUemt5DQpNMnR0ZUhCUFVrRjJTR1J4YUhGV2NDOHhTREJYTUhCRVZWYzVVVTVhYml0RE5ERTFTR3hPRFFwNFZYbE1XbTlGUVhKdWJtUkphWEZGDQpVbTlOVDFweGVtWjVUelpvZFhjcmF6SkhVM2xPTXpCWk4xZDJkM055T1dOeVpFRjBaakZITDIweWVXWU5Da1I0ZWs1cWVsQXdUbFV4DQpZVnB5V0ZGa1JUaFJNMVJLUzBnMmJXbFZVbHBZUTFOM1QxVlJibGwzWVU5cE5qZEZZbkZsUlRGaWVuaE5lamhWUWcwS05rOUVMMUJLDQplRlJ4UWk4NE9IaFZjM1pOVjNGcVFuSlZRVEZhVTIwdlpsZE1iMVI0UzBVMFVGUnFOMGhuU2xkbVJVUlJWRmRsYmpCdVRWUkNEUXBrDQpRM2hIU1hsR1dUVTFiVFE0VEV0WlRXNTZjbUpHZEhOR1pYbGxiRlJ6UkVNMVlqSXhhVTh3U1VoVFMxQlpVREZ4VURCdlRHUlhlRmNyDQpVVllOQ2t4dVRqQlZaR1Z3VFdsdGVVazJjemRuTkVKNVUydEpVVGxwUmxvMVFVUTNORWxJY0dWNlpYZHpkVGRtUzNscU1tNU5hamhODQpiMmRGTURSNWFBMEtiV0k1YUhwNlQzcHVNMnBLYUZwRGJHbEZjRGt3TmpKdEswbEhOMEpXYTI5bU0xRm5hemR0Y210U1lXY3JORWRoDQplbmRJY0daRE9YbFRhRnBMRFFwUFRtZE1iREJTUVhsUFdXTTJkRmN5VWxwdlVFVnhjM1ZNTjFRNVVVUjRaMDF1YVVodk4yeDJNemhZDQplVkpMUlhaeVRXOTNLMGd4Vm5CRE9HY05DbXR6Vm1GVE5GVXplRkI0Vms5UlFscDVRVEpUU3l0emRGWjRkVmR5Tm5kYWFHOUVlVzFGDQpOMWhTZUdSRGJqSk1hVTVwWmt0MldUQjRPSFpuZEEwS05YcHhWa295UWtNd01uaHlkakZZVm5aek5YRlRiM0ZZT0VST1ZDOUNkRUl4DQphMnh1VG1kR09XcHNUelkwT1RSdFlVUjFaRkZ1TTB3M1FVSnREUXBpVld0TU9VUlZiVmgzWkROWmFuY3hVbFZPVjBkd1pGbFhhbGd3DQpNSFpLTDBOTFUxVXhXaTkwUjFoQ1Vqa3ZWblpoTmxaNmNWQjZSV0U1TldNTkNrSTVZVzVITDFoVmQwd3pXREozT0VOUlQzYzFlV3B5DQpkR3AxWmpJdmVuSkhWMW96ZW1wak1VRm1VRzB3VGsxT1pTdG5iRFZJU1VOblpESkplUTBLUVZKQlRsQXZRazlxZWtKT05VTjZNbGRoDQpWREJ1Tm5sSVFYRldNVWRtYVZWelJXdHBTWEUyZFhWUU1HdzRZVU5uV0ZsNmNHSndlbGQwTUVVd0RRcElTVTg1V2pGbWFqUnllbWh6DQpjekpMWVV4NmRGUkVjMXBLV0d0clluQlpiM0Y1ZGxGd1F6VjZRMHhYV1VOaGJHcG5hR0prYkhkd05GWmtUbG9OQ2l0M2NDdG1OMnBSDQpVRTAxTkcxTFVXTmFRa1ZYYlUxT01WUkVOQzlYZFVGeU5XVllORFZUV1c1TlZFMTVRakpDVG5aNlVqVllOVGcwYTA1d05BMEtSWGh0DQpiRkZWUWpsSGFtNDJhVkV6ZDAwd01HOWhUakp2VEZOV1NWcHBaMWx6UTI1VlVHTnlOa1ZwYzI5cWJrTlpla0pRU1U5RVVXWjZjMHR2DQpEUXBJV1RsSlVuVkZjRVZsY1ZvdlUwVXhXVlJGYTNKTlEwd3hlR3hJV1daSFEyY3ZOSEl3YVRkSWJscHFUWEJwU0V4WGNtVm1TVFZVDQpkWEpaTUVvTkNqSkdWbEF6YkVSamVIbzBOVkprZFRSS2FIcHhWVmt4Y2paU1ZXMTVOV3AyZWpKRGFUWXhUQzlDVUNzelJWTnFRVk5UDQpiV2t4TDBkVWVFdHVkUTBLSzJ4d1ZWVTRURXQwZFdKU2FVcDFRMjFEWjIxaFNVUlVOMU5FWkd0VVRXRk5NWFpQZDNoSlJsRnpNakptDQpRamxPVFdVelEwVnNUbkJwYnpSNERRb3ZRalZOU1U0NU5GaFRORmsxU21OdlFYZFRkRnBMVHpaclMwWkZiVmc1UVRGeWIxaFFZMEZxDQpiMlkyUzNWMVNIVm5UVXBQZDJ0d2RpdGpObU1OQ2tWa1IyTmpZMk5tZGpCbEswTlhjVk0wWWsxWU0wOWhla0k1WjJSME9IUXllVFZzDQpUMEpNUjFSU1NEbGxRMU56VG1acGVDOUNlazVqZWtNcmNRMEtVaTlWT0RBMldqTkRjblpOWkhKeVFXOXVhbHBMVW04MkwzRnZSelJEDQpjRzFFU2xaWVNWTmtZV1ZpUXpGUkwxazBWVkF5TDFOUlF6TlVaVEl4RFFwR05rUTRVSGMwYkd4WVYyMVNSWEZoZDBsT2FtcFNhRTgzDQpia2R6TUVwdFZucENXblZ1ZWt4a2JYaEJkWEJLUVVwWmNXSTNUV1JWU0ZSWWREY05Da296ZDNsS1JXcE5NakZPV21sUGRrVlFWemgxDQpkV0ZVV1RKdmJYUnJiWFZTVGxWT1VEUXlNMGhqZVhocGQwaFRSakpRYjIxalZWcGtkR2hRZEEwS1ptMWlha3RGYzFwTmJtNU5ZV1pzDQpjVVpUVjFaMVRVSnhZbVJETW5kd2JtNU1WVWc0WmtoaFZsZFNPRVpvU0hONmNHTlJSSFF3VUVkU2NHbFVEUXBLU21wQ2NrMVliemRpDQpXR2x0VlRkU1dVTlVVVk5pU21RM1ZVcFVWVzR2WVRkVE5UWk1UV3BsV0hWQlkyTk5NbVpZWlZZclkyNDFiVzVLY0hFTkNtOXRVWEV3DQphMjVMUTJNNFVrVlljbG95VFZscmVETTBaeTlQTTJGcVZpdFViMEpGZEhjeFIwTk5jbTF4TlRKbVkwNU9ZVFpIVDJZMFpsUlRVUTBLDQpTRVZrZFZBeFFVRjBiM1ZxYVRSblExVk9iU3NyYkM5M2R6STRUM3BVWldZNWRqaFRRbXRtTVhwQ1NGRXJNRXhWV25wUWRVMW1hVzVsDQpUV0ZKRFFwQmFIRktUV1IzTmtSTlNFSXhUbGd6VTA5R1VtMXFiVXRtVUZWWWF6TjZSSEIxYVhaellpOVBkRmxtWjJzM1dYSXlOVEl5DQpRM1JGZVZKUE5Vc05DbkpVTldaaFJUSlNjMEpvZVZKVFJGTnNWbEJ3UTJaUWJtdEdSbll5TkhWcU1Ea3hLemRIVUhac00wODJPV3BxDQpSVW8xZFRWSlRFOTFWRFJYVVEwS1EwUTJjMnBwVjFCUGFtTmtkSEJ4V1dkSFdpOHdWbFpyVmtzMmEwRndPSEpUYzBsWU5EazJSRGRWDQpTSGRNUVVka1VXNXpiVTVvTm04cmEyOUJEUXB0ZVZOUlpXbGhXR3gyZUVSa1VIWk9ObGRIUm5SM2N6VnRkR2xFTVdoVU1HTXhhVTVDDQplbkJZVUhkQ01rbE9iM1JKWTI1V0x6RTJVMmMyVkU4TkNuaFVNa1l2VldkdVZ6RTBPVWN4YTBseGNqTlJNRWR4ZFd0R2FVRXZXbmxsDQpiQ3MyU2pWSGVWcHJhMlJhU1hOVlFtSm1Wa3cwVmpaNmNIZFBlZzBLTURSVE9TOUtOa0Z3UlZaNGRXZGhSMUpUUjJsdUsxcEVRM2hZDQpVbWh0V201aU5VMWhWMGg1WldjelNYZGxXVGxRVkdOWFFpczRjR1ZVVGtoTERRcDNaemN4YkVRelltZzJWelpVYm1WU2NtVnRNVVF2DQpXa3hSZDB0eWFHd3llVEF4VFZGWmVuWjRUMUpxZFc1MVJrTlVaV2RWWTA1VVNuWm5ZalVOQ21sYVlXeExUMFo2V1dGVE1XUlJZamQyDQpVMWwzUkd4SlpUUkhOblJ2Wm5jeVdsWlZaVWxsYUVGRFpGSjFSbU5QTWtaa2IzZ3llVEJOWlZOUmRRMEtPRWRRU1ZGU05XdHFlR3hyDQpXRkpoV1ZOR1ZFZ3JZbFY0UW0xSWQxbzBkMGxIVm5aRFFXWnZTbVk0VXpGR0t5OTRPRWRPWVM5WlVFcHBhVVE1RFFvMk5XWTFNRlJwDQpjVGRoTVVWc2VraEZiR1pRWW1KclpITkdZV0pETWxGS1FUbG9jMWg0YW1OaFV6QTRSbVZrUldsNGJXcDFVa2RyWkVVNFozVU5DaXRTDQpOQ3RETm1NeGJuZzViVTVrWkhOeE1uaGFXSE5EUTFsV2VVa3haMHc1UkV4TWNVRkZhVU5SVkhCRWJXdGFZVUkwUzJScE9HUk1UMmN5DQpZUTBLVlZoa1RuSndWMVJ1YlN0Wk1qUk9VRzluU0d3M1Fua3JkbFJDY1hoQlVXWnBUMEZXUmsxVFpVNVlLelozYWxSSGFsQm1hbGxMDQpUemxwVEdoTkRRcEdjRU5vZGpkc1RGaHVkWEpyYkRsQlZXZHpUVGhKVEhKQk1FNWxaMlY0WmxreFJGaEJZVkprUmtsNmNFNVRURXRXDQpUM0E1UWpWTWRta3ZhVXNOQ21KU09HZFpVa2N5YW1wVFoybG5aV0pZZVZVMlJuaFNhbXhUVm1vemVreEhVVmczYkhNNVJtMURNMVZMDQpNVVpSZFZCRFNsSmFUVzB5VlVZM2RBMEtWa04zYkc4MldGWktZMnh4WlRCeldrVnhZMHRIUVZCaWN6aHNja3hEU3pRNVJDOUhSRGxSDQpNekZEUW1KQ1NHeFhkRGR1ZGs5bVNTdHJkbUpTRFFwYVZUQlBkVXBFV0hkTWNXbEhiWGM1UzFaUlpYYzJTVzFSTTFwbVRXZHhjQzlCDQpNbTlPZVZvelV6WXljMkkwY1dGSVNqWkZWMXBhYURsMVRYb05DbWxJV0ZacmR6ZDRkVlJ5TVhaR04xZG5SVWRIYWtaNlREUk9jM1pxDQpiVzFGVG1ka2NrNVZTM1JITDFoTGR6UjFPV2xuTVcxa1NHeEJXbkZwYncwS1praGlNa0pXWmlzeFowdGlTbXBQVUVOV2NGSk9WVEZRDQpNRGRUYkdKb1luRnBSamhzVnpOVllYQTBkRkpEWkZZdk9HODFSMVZ1VUM5eldqVnNEUXBoTkUxWmREbExZMk5OYW5GRWJFbEdaVUl6DQpkRTlzYkZBeWNsa3pORmRSVUhoclRqRldWRlZuZDJKaFZuaFhkMWczUTA4d01rMXZaSGx0V25JTkNqbGtZekJzVjNGUU0yWnRkRUowDQpVMEptU3pkRVpFWm1ZVU5JTUhsTWVrMVNiRTlIYldreGJteEhRelZzTVdFNU1YVXJURGt6Y21wNU4xWktjUTBLTjNFNVUxZGhVRlJVDQphakJqTldsWU9FcFNiR0ZqV0haYVpXWmpPVlZKVDBwMVVreEdaRE5aWnpOc1dtZENUV3h2WXpodFF6TmFjWEZQZDJwaURRcHBlazFKDQpkbXhOU2xsNmMwTXlkUzkyUldaV05WQlVXREl6TjBwWmNHSnBNSEZoVVVoR1RrVXZiM0pVZDJkV1QyMUJlbGRJTWpsRU1tUkVWWFlODQpDbFZIYWtSamRHRnlOMFZ5TkVSeFpHaDRVRGRsWVRsbVpGbGhjbkF5V1hsQ1NHMUVSVVZSTURSUll6WXJORTg1UVU1cmMwNWxjMWhXDQpla2syZEEwS1dsQndNRTVySzBOaVZtRXlVRE5XWVhSR1MxVk9SRTVhVG0xcE5YaHZOWEpLUkRKUFlrUm9ZMmxOVEdabFNERlhSazF4DQpOMkprWTFOQ05qRjFEUW8yWTJVMGNEWk1TR05UYlVwV1dUVjFORFozT0Vaak9XVm1SSFpSUWtWelFsUllhR0o0ZDFJeVJFOHJiV2gzDQpRbGhoVml0UmEzTTRPV2R4V1VZTkNqVldjbloxZFc5c2VFUlJaR0pvZGxSWE4zaFZhblpuY0daMk1HTjZkU3RxVDNKMFRTOUhNVlpwDQpTbFYwV0VOMmEwWndWREZrVlVKR1NVSmpaQTBLYVhkcWJXRmlaVE5zVHpncmVrZzVTSHBHVlhod2MwVTBWRzF0U1doRmVEUkhTR0kwDQpZbEZDTDNCalNWSmFNSEptTlVWM1lrTkhSV280ZFM5QkRRcFhUR2xyWVVkallUZENSMVZXVEhncmRtc3hjRmh4VTNsREszcHFRbU5VDQpSM2ROZG1aclkxcDROMkoxZEdnNWNqUnhhR3hMTW5sRFpraDRkMlVOQ2xsYVIzWm1jakpXYXl0M2EzRXdSMHRCY0ZoMVZHZERaSFphDQpialozUW1kb09VSmtiM2xqTVVNemJHVkdZbmQ2ZDFkVWRYTldWbEF4YWsxWFp3MEtPSGg1WlhwNGJWQXhiWHBCUVd0NlVDczFka3B2DQpWbWhHVW1aVVJXMXBUREJtYjI0clNGaFlNRTQzYjNKVlJIbFBORTQ0Um1ReGFGWjRWalJLRFFwWlRYaGpMM2wwTkN0MFFsa3pUa1Z6DQpWMHhsZUM5YVRVWlplRlEwWVdSSmQwWkxTek42YnpKcUsyNU9XREpvUTFSMGVVZFFSR1JHZGpNelRGZ05DalZIYWxGVWVXSjBlRVI1DQphMmRqUlVRMVVTczNZMlUyU0dkUVJuUXZZbU0zVUVjeGVHbzNZVGRhV0Rrd1NFUk5UbWRuVGtRd2MyMDFVR1EyYlEwS1VFMURUR2RwDQplRGMxZWxCcFRqRkViVWxLTkd3dmVXaHBXR0pzUjNNNE5qQm9hRkZJVEc4NVVFcDNNRkkwVUdVM2IxTlpkMU40T0dsRlYwdGFEUXBHDQpRVkJJT0hWc2FEbHJibWxSTm5selNGbHVURlp0UW1oNFZIQnhSV2QzZDBwV1VHZEhjVkZTZGxCWk4xRlFSVkpDYzBjdloyazRkWEJ2DQpVR0VOQ2xWTGRuWjFhVUZxZUZOU2VXdDBiRTVzVEVOR2JEWjVjakZUZERoaU0wWjZLMnRUZDAxQ1FYZ3dZaXR5ZDJWcWMwTmFZbVEyDQpNbmQ2U2xkdGJ3MEtjMmRVYTFwcU0xTk5NMFpoYWxBMGVIZDNUREV2Tm5wcU5VcDBZbEVyU1ZwdlV6RXZSRVowZEd0YVRrc3ZWSEUzDQpaQ3QxU1d4NFlXeDFRbGhURFFwbGEyZDJTMk5XVGpOVVNsQTNZbVJVTjNCWFdVUjNSSFJvTkhoTk5uUkZUa3gyVURkNmREQlVNblYwDQpkRWRpZUhWNVJXMXRWQ3Q0VVc5RE5qQU5Da3RxUlVwNVJXaHJRemQwYld4dFdWaFRUbEZKZDA5NlIyVnVNRU5FUW5CTVRXRmtiamhXDQphekJQY2xRNFZVZzVaV0UwWkVwbk9FSnNURTU2VGcwS2FYZEpjMGswVVZObFZIcFdhMDgwU2xWcVQwcHhSVWMwWm01U2VYUnZkMkpXDQpTa3N3YWtweFpqaDRVM0pPY0RNdlpYVldlbXhsTWs4cmVIVjFEUXBRYUhCSlZYUkZUVUl4VkZKRFdIWlJTekpuY0hCMVFXeEdOVTltDQpWMDlRYzBKdU9XWXdSRUkyUlZSRWFqRTBOMlpVZDNneUwwZHVTakZoVmxvTkNsYzVTMEZRVUZJMlJXeHVaeXMzYXl0M1ZrSjRhbEprDQpVSE5OVEVSb2FWTjZjSFJZVTNWclFtc3lSVUZITkZCWVRVNVdOelVyY21WQk9Hb3lTZzBLUjFjMVJGa3lha1phV25KQ2VWbzRaelkyDQpTa00yVUVaRlNqaGxia1V2Wkd0ek1YZE5aVWRDUTBGNVMxaG1LMnRMUnpORk4yZEhiRnBhTDBWT0RRcHpSV0pwWkM5VVQyWnZlVGRqDQpWRWwxVUcxR2JYaHZTbko1YlZkbWVXVnhPSGxuWkRRd2FITTViaTl1SzNrd1dHWmxiU3RvZUhSRFQycE1kMnNOQ2taaGJUZE9TRUphDQpNRTVNY2psSWFIazRlbmhGYkd4NmNsaHdjek5vTm5KVWEyVk5kRUp1YTJ4U1dtOXpRMXBJY1ZaVFV6QlNSRUkwUVRsSlVBMEtSbnB0DQpiVGt2T1dWUE4xSlpiVXBqZEdkWGRVSXZObWR3YURkSGRHdEtXR2hLYUhaWlNYZHVWVkZUV21WUWNuQk9iVFp3UzBZeFZGbGtlR3R5DQpEUXBCTUhodmVEVnBSMEZXZEZaQ1ExRm9VVTVqT0dWSVYydzFSVU15VmpKaFdqZDNjRW8zTm5SNFIwZEhRMVp2VVRWeWNIaENWMkZsDQpVR04zY1djTkNsaE5aRlJvWVdvNFNtWk1Uek14WlZoc2JTdGtkalUwUW5GRlNGaDFWbFZ5ZVRKRlJIcDBiVkJWYWpkbFNIQjRaRFU1DQpka2xYZDBSWWRqTXhUZzBLZFhST00yaDJNRXM1WkdSSFdFNTNRVXRIYmtaQ1VtMUxXRGN6TTFjeVdIaEJXVGhKYkRsNVRraGtVSE5KDQpRelYwY1haRFJWbENlbkpZZDNvckRRcEVTMkl2YjI1emMxQlhVbTh6VjJONUx6TkdjV00xWTJkRFNUazVVMUYxZEdaeU5YRnJRMjVRDQpSMWhxUkdKUllpOVdhbTl3ZFd0VWIzcEhUbEFOQ2k5aVVsRlZPWGQwVmxrMWNVd3ZTMDlKYjJ3eWFEVktkems0YldOTVlWcFhNV2xODQpNVXRWYTFWS2IxVnBNbHB4ZFRaVFJUZEpUVkI0Tm5RclJRMEtTVk5XYUdaTE1sVmtVSFZZTVhCbVZraFZSRVZEZWpCdmFGRTVXWFpEDQpibGxSTURKT1ZISm1jVEZuU0RSUVRtdEZaWEJPUlVVMFdqWkVZeTlvRFFwSVRVaG5UVGRwUzJneGJXWTBSa1lyT1dzeFpraDNWVFE0DQpVVWwzT1VsdWVITkxaR2hhVFdSd1dYazNiM1pUVm5GQlJreE1SbVJTVG0xeGRGQU5DbWhDYjNGSlJtTkpjbTF2UkRaVlptRXJkVXBODQpSMHg2TWpZeVQwMVhVa3Q0YjAxb2VGTXpNelpWY0hKcU0xRlNRMnhXZDJoeGVEZERjbUpMUncwS2FqVTNkU3R2Y1ZnNVFYcDFkSGhODQpjbU0xUmpoMk9YaGtWelIxVWl0aU5WZDZVbTlOY1VOSVlqUnNNMlV5UzBSVGRGUTJMMVF3Vmk5UmVrcHVEUXBvU1RWUFFUaFRNVTkyDQphVUVyTlZwbFQwVXpabFpXV0dSWllpc3hkMkZVWlc5aFVYbzJNVmRUT0RobE4zVXdjR1kwZWsxeFp6aHphVUp0UldVTkNsSjVWa0ZoDQpWalkzSzNCTFFteFhZM3BDWkhkWmFXNWpaMkYxUTBOcVQxQlVZV2d4ZURsdWRVSkJLMkpKTTFwRFIyRkVNM0k0TlV0SWIwNVFXUTBLDQpPR0kyUkV4NGNUTnVjVXhuVTB4VFNtZFNOQzl4TW1VcldURTRkMWRRTDB0ME9UY3ZaV2RoT0ROcWIyMTVWMEpRVWxCak9IQjRTMUo2DQpOSGxuRFFvMWR6bE5ORlEwVlVoYVZpOXpjVFpqUjJGUVUzbHBaWEIyTmtORE5rdEdXbkpQZDNwek5rUlpjelZRWjJoMkwyTjFaVU5KDQpRVFpEZGpadk4zVU5DbGxNTkVVMmN6VXpiVE5GTVhkVldua3lNSGw2TkVsdVoyOHhhMjE1U0dnMWRrOUJWVFo1VWpGWGRDOVNRMjVLDQpablJ5UkVSUGVUZHdhMXBrUncwS2EySTBja1phWm5KRVMxQkRPVUpvZFUwcmIzTTJPR0ppVjBkelVGUTBjbkk0TTI4M2FUaHRZMUJsDQpaSE5DTnpVMFRsSXpjVkV2TkdKMVVVcHlEUXBuZGxNeVV6SkdSbWRoTnpKamFXNTVOMGRKT0V4SE9VZzNaM0U1VVhseldrSnlORzluDQplbmR4T0VneWRIRm1ZV2R6U2xkWlRWVkpPWEpQYUdNTkNtNVljMU0xVTFaNmNEWmlUVXBpWVhVdlQydHhVMFU1Y1c5cFVFNVVkRXRNDQpVRTFrZGpRdmFERkRNVzFpTDI5NFZFeGpTRWhxTjJ4bVZWZFdTdzBLTTFZMGJsZEJWV1pyY0hSdVUzTmxaMUJuY1M5eldWYzVPRWhEDQpOVlI2VjFRemQxZDVXRU5yZFN0T1pIcDFSbTFXUnpCekswVllRVzgzV1VKWkRRcHNjSGs0V2tjeFNFUlJMMGx2Umpoc05HaGlRekZvDQplR3M0UlVjd1pEZHJjM3BPVkVsbVZuUlNNRkpLUmtrd2QyZG5Nalk1YjBjM1RVdDJaemNOQ2t3ME9IUnZablowVjFGRldHMHdkVmxxDQpjRkJ0ZWtFelNYZFlSSEV4YzFac1VGWkdWSGxtTjNob1l6UlZURmhhV21sSmNYaEZkMmtyYjJ4SFZnMEtSbGx1TkhGdmVETkNXVTl4DQpLMFpuY3pBMU4ySnBMMll6YWpNd1NtaEtWemxXWldSVVpHUlZiVEJzWXpsaWRIVkRLM2xVWTBVdlMzQm1OazAyRFFwMVExUlZVbTFMDQpkbTAxWTFsd1p6ZG1jVmc0ZFhkeGVGUmlkakZwUlc4MVQxaGtXRlUxTTFKMUswSlVRbTFhZVhaaFJHVkhlbFl6TVZWT1dXOE5DakV6DQpWWEIwZFM4clVsTmlaSFZEVWxaMFJYTkdNVVprY0dGTVQyOXJabk5XU1VabEswdHFaMk5yVUVGSGVqZDNVMFpZZG1GMk4wUmFSbTE0DQpaUTBLZUdGb0wyVlphR1l5VGpocFdESlZjMFY2TlVOeWRESjBhMDVWYldkRk0wUnlNRU5yVkdSb2VubGtNMGR1ZFZGWmJDdDVhWEJNDQpNVmQyUld0akRRcDRTSEJITTI1bk4zcElkaXRCZG1WTGJuTm1LMUp1ZEZCdk5XSktlVlIzVmpsc1VEUXhVV1pHU2t4NWVrcFZXR3RRDQpUbTlPZG01T2FFNUpha2dOQ2s5eVUzYzVVV0pwVVhaTFpucEhXREZMVWxnM1FVOVNVMEpTVlRBMVJraFBOMEp4ZVVORGJEVmpVbW94DQpSVlYyVHpSTFdVSkJjVFJVTTFGU1lnMEtWREF6VkRkWGNUaHRTalJHUWt4RE0yZHJXa2xCUmtKWWFrSmxkRU5USzBsWlVUWkdNMVoxDQpPVFl4UTFKWU0za3hRVkUxUVVsUE1XcHpNR0YzRFFwcGRUZHhiazV1VXpSWFJYRk9hRUpLT1RGR2RWWm5jRzVtYW05MlZtWm1RelpqDQpWbEZtWlhCbmNYRnJlbFpOWlRoQ1duTTVUV3BSYlV4VmNua05DbWRUTURKMGN6RmpNakZQZEhkSFVFMUZTMUYyUlVFeVNGVXZZbFJVDQpTWGQ2THpSVmFqTldOVEpCTjJaNU1VeFVVMHRCVlV4NlNGTjZjMFZsVlEwS1Z6bHVSMmN5VkRWcVFUQmtja2h3ZHpkT1RIcG5OekZ6DQpiWG96TUZGSU5WWnljR3B0YVRGSVkxQnBhRUZHUm1kRWJISnZORGtyUVc5SWNETXhEUXBPY3l0RU0zcFVVbVJMWkZSbk1IVldSV3BSDQpTa1JVZVZrM2RrbFFTVzl4TUZKUU5GZHJkVFVyUlVWelRFeHJPVzk1Y2l0MldFMUJjMUZVS3k4TkNrZHVhakkwYWs5bVpsSkRPVGM0DQpiSFpyU2xacFUzcExXVFZPV0VWM1VIZG1abE5rVDNoVldISnlRMHhaVUVSd1ZYVjZZMUYzVWpKM1kweHJidzBLVWxsWk9HcHBhR1E0DQpVbVZqZVUxVVZHMDJWVVU0WTFwMVJsaHpiSEI1Wkd4dlVYUm9WMkV3WnpoaVdGTktaWE5SVUZkd1kwUmtTMkZCVHpjckRRcENRbFIzDQpTMGxJUkU5NGRtMW9iRGxpV0RBMlYyVjRUVEZhZFRCTmNtUTJVVXg2Y1dSc1RUY3lRVVp5VTNjd1dHbFhVREEzUVdSbU1FMHdXV3NODQpDakJ4ZW1oRVFUTndaa1ozYTBkT2IxWnNjbWhuVFdOQ09FVldOVVZEYVUwNFZXTlRValF2ZEd0M1YzWXhhbkEyTDJSVVIwc3pUMDl0DQpObGhWWWcwS2R6RTFVV2RYUm1GTU9WTkxTemRMTDNSVk0zUmhVREJGVlRCUVdGZ3JOa1ZaV1RkTE15dFNTVWhOUzBZNGMyZHpLMDFKDQpabkI2YzBKMVdEQnVEUW81TkRkbWVHMXZOamRyWjFaSFpTOVZTM1JSYUhwRVVsWnBaelZHWWtwbWEyVlFPRVkwVDBoMlluTktjQ3Q0DQpUa3hrY1RRMlVVWlZWek5oVG1VTkNqQnJVRmM1UlhsbmRURm9jbkZHYmtaVWVsSmxRWGN4ZGxWSFFXcEVSWGMwTWl0cWRIaEZjU3RUDQpkMjFKWldGaU9IZHBNV2RxSzFkWGExWXhiUTBLVG5nd2FtVlhNVXgxVkdSelYzSkxlakp0VTA1M1kyWnJVMmxFY2poa1lucFNjUzlIDQpUekJtVlZWa1pXTnpOQ3RuTkdGa2FHbEZSVVJwVTBwakRRcFFUalY0YkhReFZFWlpaMk4yVVRKSVpXVlJhMnRpWld0Qk4xSkVjVGxrDQpaWEpUU20xbVdXRlhiM1puTUZVMFRDOVdNMVZYZFRVMlJIZ3lTMklOQ2s5NVNURkRWVmxPTDJVeE5pOWFkRVl3Yld4bk5XaENjVlI0DQpiMUZYWVVkelowdEtiRzl3TmpkMVFTdDJVbFZHV1hOYVduTXJWRzE2Tm5kV1dBMEthUzkyTHpsRGNEZzNTeTl5YVVvM1RIVnhNSEpYDQplbGhXYzNoeFdYcDFSM1ZhVldoalQwRmFOM0k0ZGxaUWExWnZla3RTTXpSR2JUUm9NMEZHRFFwQ2QwWnVRVVZDTDI5eGFtOW9SV2dyDQpaMk5OVDNRM2VtMVNSVXRETTI5NVVYQXpkbXBHUVZFME1GSXJXSGh4VDBGSGVIVTJOMnBoVG1Sak9IY05Da0V2TTNGNU9VcERSRTVEDQpiRlE0U2l0bVlsRnFSWGhwTUVoUFNsUjFUbEV3ZVdOUFdrbEhTMlZ5U0d3dlJsTjNPRXR1WlhkQ1ptd3hVWGx0ZVEwS1QyTjNWVUZXDQpPRlI1VUhaM05GTk5OMmhLT1ZZeGJua3ZTVFIzWTI5VmVYbEtaVlZPTWtWT05Xd3dZa2xxUjFwRlIxWllMM1ZWU0dWclIwNW9EUXB5DQpWWEZSZURBeWVYTjJRbk5zWTAxRFlYcEpWekpTWW5OWWJuRnBNMFpXYmtneGFsSndVRWt4YUVjNGNHTlBlVEZ0WkZkQ2QzWm9SV0YzDQpkRTBOQ205U1RHTmFVSE5zTTFoNVFpOWpXV05sVms5RlkyaHFkMUZvS3k5RGFuWmFXR3RrWlVjcldHUnNiRkprUm04MFQwa3plSGhODQphM0IzUm1scUt3MEtUakJDZEVad01tSnVaVmgzTHpCVmJtaE9TMm81TTJ4cmNYb3lNMEYwWVU1bVIwdE1iWFp2SzBGV2EwTndjM00xDQpTekYxVERka2F6WmlSekJFRFFwRGNqVXhMMUJNZVN0MGRUQkVabVJCYlZRdlZVMVlkME5MYm01bVNqZ3pibVZSY21OSFlrVjVaVXhSDQphRmxtTDNSdlFsSnlVbFkxWVVzMlpWTU5DamN4VDFvMmQzaE1TbU5vVlVONFZHWktXRGhwVFN0WFNEUnRSRzlJVFd3dmMzVm9iVmxGDQpTako0S3paclF5OHZXaXR6YzNjd0sydzFZbHBRVVEwS1RYaHFiVTFLYVU5bk1tNUpWV3hpTkV3MWNWSkZPVGRpYzBsVmIwTTJaM1pJDQplVkp5U0VwQlRXaGlWRVZFWlVGemVqQlFOV1pPTUVkeWJ6RlBEUXAwVjNGMGNEbE1lV2RIZVVONVowTlViRWxJYW1GalVtRmliV1ZuDQplVE41VVdseVQwVk5ZVGxPYlZKRWRIVnRWblZYUmpGWVpHbG1iMkpQZURNTkNuZFZNVVZFVTJWS2EyTlJMMlpDV2xaUlMycDVlVVpDDQpRa2w1YlVkNmNGSktWRm96UTBsNlYwOW1NMGx6VG10QmIzZHdOM05ZWXpaVVREbExOQTBLY2t4ck1DdGpRVlZhTVZCQlNWUk9NblZLDQphVmxGUWxObE1FWjRiRGg1U2pSRlRsTXlZazFaU2sxa1dVcDNTRWhwYTNCVVoweHVNVGhDTDJzMkRRcHNRMGhUZEM5VFRXSXpSVmRODQpTa1pKVW5SSVJIbFNWbVpWTlhjclFqVkdla0YzTTBWbmFFUllOemRpV1RWblNVOTFkVUp6UnpWblVsTmpVVUVOQ25ZelFXdHlSSEZKDQpUVkJNVWpGaFZuVk5iMGhCYUhvdk1saDJRVkJpTTJwblJ5ODFja0Y2V21jemFUbHBNVm8zZERCaVFWZDVXbHBGVUVaelJBMEtWVVZXDQpObnB5Wm1OdVpGcDRWMjVHUmxOQmVWaDZSVzVOY0hOSWNVWTJURTF2WlVsSFVWSXpaSEJEZWtzNWVrcGxTWFZXTVhWdE9EVnhNbXBJDQpEUXBEYldwdU5uaDVkMmR2WlcxNk5WRmhWME5JUjBaVGFqTmhibk5NT0VOclJVWXpSRE5UTHpaRk16QXdVV0p4YURVMWNESjNVMm93DQpjSFIxTDNjTkNuY3lkMnMwTXl0RFVGaHdVbUU1UmtzclRYWnZNazUwYjJGMmFVTm1USGw0YUd4SEwxcHFXVzl3VHpkaFQxVXJUSE5tDQpSbEZJZDJsRVJtUkJkdzBLYm1aM1NTc3pZWGRMVFc1VE9HZFVlR1ZWVW5OVGNrOWtibGh6VW5ZNVJGWllUVXBNTm5sRGFFaGxWME5EDQpVRXRZZERFNFUwSjZlVEUyTWtWTURRcDJPRlEyVkVkQ2JHMUJhM0ZWVFZRd2MwcFBSRFJzV1ZSUmFra3dibkJaZVZsTFRHNDVhbVZIDQpUR3RPWW5rMldXRklRbEJ5VUZrclUzRTNXazROQ25kVGMzVk5aM2h2VEVFMmJqSXpUSEo1ZDNWRFdtZFBiSGxWVjFwdlNsaDVVMGx4DQpWMHQxZWpsYVoxVTFkR054YVRkSlprOW1TMVI0VlRoRFRRMEtiR1ZPYm1veFJDOXBLMjB5WjFFMVRtdEpkbTk2WVUxS0wyNTJhMWRKDQpWa05XY0dGNmRrTldNVE5EUlZKNlJHTjVWbG8wYldoQ2R6bDNjMmdyRFFwQ1Nub3lORVZRZGpFMU5VSk9VMkZZVTB4blpXUm5UelpsDQpUVTVoYWxKU2FFOVRkR2RzTVdGcVVtbFRRbkpJYUd4VWFITTBVbWhYWVUwck1sVU5DbmhrV2pkVVduSlhkRk5XU25Wb2FUVjFUV1o1DQpPRmhQVGxCbWJWaENXR2xwTkhOYWFtc3paRTl5ZG5ReFpFVmplRGhTZFVzeGJITlNjWGxJVncwS05tUlZWamxUYlZFNU5IaFlVSEpyDQpSeXREVFRKcVozWm5WVk5QUjFOelptbFhUUzlYZGtwNFdGTk1WemhpYjJaSlFXNVNSMnhOWVhKV1lqZ3dEUXBIYkdwV2R6ZExXaTlvDQpNR0pPWTBzdlVXSjRiSGRqVTNCMmNDODBMM2t2Vlc4MFVIQXliamxaVVd0R1NtRndTbHBoWVZFd01tWjZjMmxQVVZBTkNtMXRVRTlJDQpNazF6YzFWTVdHWXlka2xpVW01RlEzSTBRMFl6TkVWbmJ6SllNVFpCUVhFemNuWkRRVWd5V2pKVFdsTlFSRWRXZFM5VlNFdExadzBLDQpOa2xOV0ZSeWJ6VkhObU51Vlcxc2QweFdWVTAwY0RNeVVWcFlSRGswU1dwaFlUSnVZVGR6TkRkNGRsVnRlaTloVG1kUGFsRlNURmszDQpZbkJURFFvMGNuVlphMjlsYW1GT05FaG1jWFJWVjFKMFJubHRVWEZxTWxvNGNGQnpibWxtWkU5bU1XaGtlWFpwWkVkeFNWWTFiMDlIDQpaWGxFTVZBMFJITU5DblJzVGxwWVIydG9URmRRYmprd2NYSjNZWHAxWW5Ob2EwVkpkR1pDYmxreE5GTlFUVGxCV1hsRVVWa3pSbFZXDQpVMlkwZVZWeEt5dEhjREIzUkEwS09IUlFNRXhIUldsMlVFNVpUWHBtYlZSek5WVXZOVmhUZVVka2RtTTVZWE5HZURFNWFURXZlRmxoDQpWa1Z2VGpWU2FqZE9UbUptVFVGdVNESkZEUXBLZWpSeGExSk5Sa2hGVlVzcmFrRlJhbkpqV2pCQk1ubHdPWE5PWWpKYWJXb3hRa0pYDQpORmxxY1dNeVpsTXhNM0pEWWtsSWVDOTVhR2dyYVhVTkNtbDNWMUJUWVdsb2VrMUdZbkJhVVZaaGVtNVZkRUZRTW5KRE5uTmpOVzE0DQphMng1Wm1WNGJ6WTFMM3BFT0RWclltOXBTRk5pVW1OblYyNDViZzBLYW1wemNtTndRV2hRWW5wMlJFdHhaMEZLUzJwNFVVaENjbG8yDQplRXBJU21OaE1HWXdibmhIT0d4SmFYSXpVMVpUWTJSSVpEYzNTemh4YmxGNURRb3lkemw1ZEdobWVVUXpLMHhyYW1KS2R6WXlSSHBPDQplbkZHZVM4clRVYzRSQzl6UVRaSGRGUkthWGxwT1RkWVdUQlFjRzlZUzFoS1ZFOUpNVkFOQ2s1bWJrTnNlRzB6VkZoek5sTmpXV042DQpWVTl1UjBOTllpdG5RVnBDWTBoQ00weElLM05xZFZJMVFVcGplV2sxU2pCeVkwRm5XVWxHYWpKQlpBMEtNbk01YlZZdk9VVXJTMWhVDQpTblpPZG5wUlR6bHhSVzloZVd4WVUybEdiVEZDWW5CbmNIZG9WMEZqYW5wS1NtdzBRV3hQUXpWUVJFcHZOR1prRFFwcU9GWmFaR2RSDQpUblJqVjJkWVNVWmhlbTFTYkN0UUszQkJXSE5KVERKRE4zVnpUME14ZURoeFpUbHZiVWwwUldJMmVUSkdRbXBtTkhOcVV6VU5DbFZTDQpjRzgwUTNKQlNuaHBNMlpHVEcxelkzUTFjbU52U1ZJeVprWkVORU5LYTFScFJrOUNPRGt4WW5GcmEwdFJVSG96VDJWdlJHVXpUV1k1DQpRdzBLY1cxMFdrZEZkMnhMWVUxUGJWWkplVlJRU1hJNWVGUXJlRUZrTTJoSk1IUkVhemRqYkZWa2MzbHhUekZEUjJGUE9VNHdLMDF2DQpORTVWZUhkYURRcE5XRmRGVEZCR2VtOTNVV1pETXpOS2RIVkVjSFUyWWtkWFVsZFhTWEp6Y0RBMk0xazBVRWxUUm1Sd2VuTmpTV2g2DQpaM0pHVUhKdGVYQlZabXdOQ25wSFNYRjZaMWRHVjJSTVdEQm1haTkyYnpnd1VUSk9RbWRRYVVOck5sUjZiVTA1VDA0MmJrY3ZMMnBXDQpOWEZ1VEhONk1DdGpSbUZ6TTA0NGRnMEtkVTVuYTBsQ04yNUJhbFpCUTNoaVVUTk5RMGRGWmt3MlYyMXhUWFl5U0d4bk5VVlBhRXBuDQplbFpDTWs1NE9WQjJTVGRPVjNGRlltUkpWR1IyRFFwRk5UWk9hMVV6U1ZGdlNXWk1ZMUZoY2s1MmFWZzBTbUZtZFhCaU4yRlBXbVZ0DQpkbVJMVUdNMWEwTlpSbTFIU1doa1UzUjJjMlpRVm1wRWJrd05DbWgzWVdaNGFVa3hiV1p0VFRsSlZHNVhWbWhxVVdwVE5URkdPRlZ2DQpOVE0zTW1jemNIUktZakJuU0hkUFJXbEVSVzB6YldNM2FVVjNMMVpNWncwS2J6VlVWV3hFV2pOd1ZHRlRTU3QzWkhsbVZua3JSazU2DQplV3Q0ZVdoblJYTnlkRmhOTjBGU1JHcHJWVzFvT0RoV2EyMUVZVlpUVURkemRUUXlEUXBaZUVsbWRXOTFTa05zV2pKeU5tWlpNa1Z0DQpSMDV6ZGpsbk5YRnBjRmxITlc5bWRGSXphbGcxVEdkcWRVdHBPRVkxVUhoWFpDdHJXV2RWYURZTkNqaDZSblprYmpaYWNGTmlUbEF6DQphU3RCVlZoMU1sbDRRak0xWmtob1dIZGFUeTlPWmxCd2FUZzVUVkZYVlc1S0x5c3ZOMmN3VHpKc1FVMVhTUTBLVUdkWVFrSTJXVUpQDQphVU5CV1Zsd1pIRTVZbFoySzFRMldWSk9kbEZWUTA1TmMxRnNkVkJtVTBkVmFtMDBPVTlETWtWaVNreERiVEl5YjNGNkRRcFlaMjlzDQpiVmh1WmxkelkxbHdTbWREVXpoT1oxTnBORGt6UVdGT1lVZ3dVMDlxWlZaeWRFZ3lMMlZJYjJwd01uUlJabFZaV0hKSFUxQllURVVODQpDbXhLTUZoS2F6RnJRME5FT0hWVlUwUjFNak55ZDJselFYTjFOR2xyVEhZMlRIZFFWVGR5T1dWbmVUVkRhM0pIYjJocVltZFBVR2xVDQpPREp0VGcwS2FEVmtVRTlRZEV3MFRtSk9WM1J1Ym5OdWMwdFhURFF4Y1hCUVNHTTRWbFpoSzFseVl6bDNXa3dyVFhReFNtVlNUa0pvDQpLM1Z4ZVVOaE0yMUxEUW96V2pSR1EyWm9aVUZUWm1wb1IzVk9XVGRXT1VWeFJtazBUREZrUW1Vd00zVjZaMVJZZDJrM0wzTlViMmRTDQpURE5TTUZCM1NYSnRjbUZIUlVRTkNsQXZNV0p2YVdkRmF6QkRNSEU1TDA4eGRHSXlTbk5EYm5sM1ZXUjNlRVUwVlhFd1dWQkZjR2hwDQpkRGhwY1ZSdlVHVktNbEJSVm1wc2FreDVMdzBLWkZkaVlUazNNMFpETW1oUUwyeElSV3RKZVZCbU4yVlhiR1JhVDNRM1IyZFBZbWhQDQpNWHBqUnk5TVVXeEdXVE5rY1dWMVVXWnFVREl6ZW1NM0RRcGtZMlprZWtoMUt6TlZORE5EYzFkNWRFVlFTUzgxV0VORmN6QXlTbUpKDQpWaXMwU0dwR1IxaHZlVVJWUW5rcmFHdE5MMVZTVEZkRVUwVXZhM1lOQ25oeVlqQm5OSFIxY3paU0wweHJSRkJ1WWpGSlFqUXZOamRyDQplbFJ3WWxaUGRFUlBkVUZ6WldRclpGWTFWMWhWTTI0M1EwVnRRV3hIY0M5alNBMEtiM0o2UTBkTk1qSnNTMmxqU0c5UFdEVTNZVU5pDQpNRXBWWm1oS2JEWnBiMkpCVWs5eVowSTFkREJMWVRkRWVXRnJiRmhCUTFOdFZWQklSRzFhRFFvMWN6aHVURTFoVkdkSGFESlFTVlZIDQpTWEZ2ZEZSalNrRkpSR2M0Tlc1M1kzQkNMMFZTZGxjelkwaExOaXRXTUhsUlUwOVdibmhYTjB3MVdrd05DakpqYW5vdk4xZG9VbnAwDQpaRFZzU1daWFR5czVkVGR0VEhwSE5HaFdUaXRyUVdkMmQwWkVWRmxXZUVoeVNuWnJRM2xaUjFsWFRsaDJTM0pWVVEwS1dGWjBiREZHDQpZVXRTU0UxS01HaHNLMDl6YVdwdGFIRmllR1pqYkU5cVdWRjFlbXBJTTA5UVVqRjJhRE5GV0hSSGN5dHdkbVphTWtjNVFsTm1EUXBNDQpZVUl3TW5GdmN6bDRiVGMwWjNsV2JrcHZSbE5IWnpBeFJFcHdhamQzV2t0RFZUTmFTSGx4Vm1ZemNGUnBOMjFPVGxwT1REaGpjV1ZoDQpaa01OQ21sSFJUaFBaR2w2Vm05U05sRk9TVEZGTXpadWJWSnRUa2hSTUdadmJsRkZSbXR1V0dkWFlXZGxPWFE0YVdnNWNqVk5RVk5UDQpMelptUlRGNVJRMEtXR3B5TjNoeU5rSktTMG92V1ZSTVZtZFpZMXB2ZVhOSkwzQnFaMGxMTTA0eE4yZHhPSFEzV1ZKRGRuQm9jalp5DQpVVEpXTUV4RlVVOHJOREpQRFFwdU5sTjZkR3BWYXpob1ZsRkxaVmhpWW1GeFNscEpVMjFOWVVkMVMxbFNSRXhIVWl0NVFWQllLMWx0DQpUblZLVUdKU1ptRnJRMGxMVlRFNVNtNE5DakYyVUVkWVlqSXZjRTFsWlZOTVRuQnhWa1JrZW1SSWQwMVVRMUJWYlZreFowb3JSME41DQpjRFJ5YW1WVGJXb3hPV1IzY2tOVE4wUmFSMms0UXcwS1RrWTFMMmM1VUV4TmRHMWtaMVpWTURsa1RWQktiRFZ3ZERCR2FFRmFXbkExDQpUSFZ5UmxCT1dIVnlOM1pwZUV0Uk5VZHBiVkJaWVc1T2VWcGpEUW92TVhCaVJFMXFVa1UyVVVWTE1YbFhSbEpRY1hZemJXOUtPRU5pDQphM2R6Y1RBMVlWSjFLMUp5Y21KamRIRk9SRkpoTUd0QmVsVkdUR05yTHpZTkNqWnFXbmdyZUZwMmQzbGtZbTlUTWtwQ1JHVm9hemgwDQpOa2hKVkdwcmExbFhiVlE0V2xsTGJVVkxhR04zY2taSlMzVk5TbmQzUzB0U1lTOW9SZzBLVDBWNmVYZ3pibm8wVG5jNVNUWjZSQ3QyDQpTVTR4U0VKYWREaHVVRGM1V25FMEwwYzFjRWxsY21WNFFVZGxMM2h6V0hkQ1Ntb3ZVbEZ2VTFCT0RRcHNSaXRWVmpKdVZETTBMMEZZDQpMM1F2ZFhwMVZYaEhRbU0yUVRGT1VDODJkVUZMZFRkcEx6aFlVWEI0WjIxWkswc3ljbmRJT1ZsTmIzQlRPSGtOQ21oaGRsQXJOekYxDQpRWFpNWlRCdVZuWmhXVlJ1VEcxM1YwbE9aelJaTVV4RlpFRk1aR3RCV1RseFoxTXphMmMwTjJreGRtZzBOSE5sYldWSFdnMEtMemRLDQpObVJHVEhkTlRYSkpPVGhSWVZCRGQwbEhhMGhwYjNwVU9YSlFSazVPTldkV2JVaERNVmhMTlhGdk4yOWxaRFJ1ZUZkUVVFbDNkRkJCDQpEUXBWYlhGcU5IcGFaRTVZU2xrdkszUkxOVWx2UVhkM1R6UnJNbTg0WTJSTVVWaDRiVkZNZEdJd1FWUXdkakZyUkVkamJtZFJlRmt2DQpORlZ5YW5FTkNtVkhNa05tT0VKMmFUVjVZVkJZV201NE0wSk9SbGhvVDNOdE9URm9LMlE1Y0RaaE0wSlVOSEp2TkVwMVdtVTNjblIyDQpOVlZoZUROdWNGcExWQTBLZURseFRsVk1VaTlpVW1kb01IUkZjM3BuWTJGaVpYRlBRVVYwZDFOVlZVVnVWbEp4WjJ3d1pFVlFMMFIwDQpOSFJ1YmtaT2VUWnRkbGx5VDBoM0RRcG9OV1JxWnpkdE1tazBSWE5HTmtSRk1sTXdRa3R5VG1SS0wxRk9kMlJtVjFoM1dVVjJlV1ZTDQphRGxEVDJ4WlpqbDRPV2gzWjNJeFoxaEZTRThOQ21wNVJUVXJOWFJqVVRrNVNXOU1hbnBZZWxkMEswZHFURkJyZDFFeFVYb3dNMUpSDQpXalpwZUdGcWRYbFpLMjloU1VSNFZFOUlMelpHUldsSk13MEtiblZIVDA1bVpscEljbGxSZFROR05UUlRWbE5yV0dVeVNHODNPRThyDQpLeTlOWjI4MVQyaDVabEJ2VFRNdmJsWlZPVUp0WW05TVNWZzNOVGxQRFFwWWFtWldjbmgwUkdJNVNrVlRiRTlLTjJKUlFVZG5ZVVpRDQpTVzQxYjIxNk5tNVlRbXN6Y21NNGFIQkZaa2huVkhOV2EwZzVlR2w2UVhWb01WQU5DbXhZUWtkNFpYRkdZbVpOUzAxaFYyVlVOVnBGDQpkV1pzTVVkdGIwZHNhWFkxZGs5S1R6TkljR2hEVVhkVGNtOXJRM0pRZVhsUVZGVjZjVmw1TXcwS2RFSkxVakpZZFRSd2RIY3JiVlJZDQpkRlZCWkc5UVFYaExSVGhaTDFnd1NtaDJNbkZrY0hBeU0yZDFka3BKVDNGbmRqaDRaRzlvWnpkWWFFOXJEUW96UW5CSlQweGhhRlJvDQplR3AzTkRKYVNGcHRNRkU0T0dWc1duZDNOMjkzUmxwaldHUkNUWHAwUzBvM05GUlNWMGx1YjJWSGVrSm5jSGRIVkhvTkNuWkhTelV6DQpSMWxtVVd0eFdWRnRXWE5UY1ZWSWNWZHpUM1ZxVG1GNVlVNXJaVWhMTm5wMlJteFFSSE0zTW1GMlV6UXllR2xXVnpWRU0wTkNhZzBLDQpWRFZIVUZabU5GbHVMek5yZEVNeVUyRlpha1pZWlZWck4yeFhaaXM1Y21vcldrMTJWSG80YUZabllrcFNibGRQVEc4M2RXNXVZbVJFDQpObmRFRFFwMFpXbFVla0kwTUcxT1NpOVFVVXByUkRrck9FTnVkbnBJZGs1SFMwTXZNRUpTZUV0SFkyZFBWV2R1VDA1S1pFaGllREJLDQplRWt6WkZveU9YUU5DbWhtZGxCbVZTOXpiRFJ5Wm5WU1FVaExiR3BVVTFaRVJGZ3hiVk40UzJOSWRFdEhSMEZrZGtsdFUzWk5RMEp3DQpSRTF0YzFFME1YQmtNVE51YVEwS01tVkxWMjVvS3psbFJrVTBVWGhGYVhsRVZWSnVXakZUWW1aaE9HWk5UR1pZVjFWNlpuZE5jVE5oDQpXSEE0TUVJclpGZHhOSEZDWm5aMWNqbGtEUXBMU2xWSGExcG1WRXh4ZEdWbFZIQlROVTE1VTA1MVUwdDZSbmhHS3k5bWNVdFlZVWR4DQpTRkkxYTJka1pVbGpjbTE0UW1kTE1EaGtNRWdyV1ZNTkNsSkNVMHRtUVRsd0swRnZOa2hwU0hOTFdIQkllRWsxYmxSa1dIaENTVFZNDQpWbFl2ZVhvclpYbEZRVXBSUjJ0cmFscHFaMnRMTVU1d1JYUTROZzBLWVZobGMwdHlTek5PSzJOT1FuZGtiVlJYY2xkUU5GWmxXamhoDQpRMnN4ZW0xNVRWTkNNVVJ0ZURkbE9WVXJNV3BKVXpZd1ZGSnNaR1F6Vm5SckRRbzRTRzQxZERoUWRDdFZlbGs0YUZONGMzSlJkbXRHDQpjU3RFZUc1bVRrUTJWVlJvVWpBMWIweDRZMUpzWWpSb1ZtbFhZbmxRTVhaUFZYWlRjMjBOQ2xoSlRXMVBiVlpYVjBGeFJrVmtWR3AzDQpLMW93Tmk5SlUxSjJUVGhZU21oUWQxWklhbkY0Y2tVNE1tNHhTMWhoUXk4d1ozRXJaVkp0WW1kRFpRMEtWRlpGVUZFclpucEVTbWRyDQpRalpWVGprM1R6Sm5RMmhDTmsxUVVXbEZabFEzZG1WSloyVmlSVEV2T0UxSFJraEJTazU1Tm1Oc1dVUkNlbWhhRFFvM1ptUTNUWEk1DQpNMDFMWlhCRGRWbElZVmRhTW1sVGIzUkdZakp1ZURSblJVOXhUMkppSzJaWFdDc3hiVVJOZFRCbk5GRk9UVkYxTnpNM2RHd05Dbk16DQpWa0U1YWtGSFVWVlZNRnBOTlZsUGFHeGpaMnh6TWtsVmVWRmhkM2sxVGxoU2FYaExlWEFyUjNoUFkwc3ZjVmxGTjNRd1ZUQlpXVVprDQpiQTBLYzNScVRXeE5lVGh3U0UxVFZtdFBja1JhUjB4VWQyWkJlWFo1UVM5VlUxTlNjQzl0TlhkcGEwcEJjRzAxUW1sWU4zUlhSekJDDQpMeTlsZVZJeURRcG5VVVk0VVdsM1R6WmFWVWx4TkVvM01YQmxUVlpIU1V0MVJsQmhUV05uTkdrdmR6UkpjRnBsZDIxcmJqaDRVRU0yDQpNemxSTkRCcWJVOWFVQzhOQ2pWelRYZDRZeTlXWm1KSk1tNVpNMHhvTTJ0SGNWcGtLMUkzYkZKMGIxQjNPVlJ6T0VNNGJXUk9RbEIxDQpiRFJZTW01b01VazNUelpLVTJkcVZ3MEtORlJ3ZEZCcWQyVmlaRTQ1V0c1Ukt6TlFhamN5TURoME56SnJSR3BYU1dONVZsZERZVGhKDQpVMVZzT0RnMlRYRnhhMGxRZG1aYVUwRmlPUzh4RFFvcmRGY3JkMjR2UW1Ga1ZUaFFlRzFMWkdSWmJEZDFkbkpCUW1ad1pscHpOV2xTDQpVVmhKZWpKSk4yRmhjWEJDZUU4NFJtWmpXbFZpWTB0WU4wWU5DbmwzYUUxV00wMHJZaXRyYVdOT2FHbHZOVk4zV2xJclJtTmhNRmhCDQpRV3hZUVhWR1NWRjNlRkZoUXpGamFrNWlhRXgwWkRkT1NFOWlMemhYVXcwS1ltUkVXblp2TjB0cmNsUm1PR1ZzUzFZeWFHZFNibEUxDQpjelJoYUM5dlpXMWpZVGczTWpoemFFcGxkRkYwVTBsRmNrUm1jbHB6Um1keWJWZFlEUXBMYWk5TmRUbEZkRWh6TmtOaFJtaGtjVmt3DQpjV1ZsVUhSTFZYZ3dXWEpCWlhveVdVOU1kMEZCVTJwM016QndOMHB3WVdsTVMzbFVPWGhGYjJjTkNsaHBNak5CU21OeU9XWjJlbXBDDQpSMFJuYUd4VlFWSjVSWFYzV0ZwSVpWQXZZVzV3U1V0QlMwb3dVVGxqYmpsVllUbHpNakZRUmtsb2JXMXRRZzBLVmtsNU1Ua3laMnhRDQpUbmxYWTNaVk0yUkdTbkJGV0U0clpuYzVlbEZTZW14Nk5VRTFZVVJyTldKTWFuTkNSMGhMVEZOcVMwSTFTa0kxZFhaeERRb3pOREUxDQpWbW92T1hKMEsyNTNTSEZQZUhCWFRGQXZLMmx0WWxsdWNtaExiblpDZGpGbFVVRlJkMHQ0TjFsUlFWRmFhMWhsU0d4UGNITjJhbmtODQpDbU41YzBaSkwyZHlSVU40Y0hwWGRIUlFkSFZHZWtwSVpYcGlZM1phUTJOaFNHVlJOVVUxUVRZMlZscENWMDlLU21KWE1Fa3ZWV1V6DQpNMFZuTncwS1pFaDFOazUzVlhWWFZtUnNMMWxvYjBkb05HUlFNR3hEYVRkdFJHMW1iaXRaTDB3MFFuZE1ZMlE0TURVeWFIRXpUVVZIDQpWa0ZMUkhSd1F6ZFVEUXBaVVRoTlVrdEdiamxEVDNKTWMyWkNNVXBDVlV3NWFHMXJUbmw2UzB3d2NpOXZNR0kzY0hRcmJqSlJkV0ptDQpLMUExVjFkTlNHZFNlWE5LVlU4TkNrOXVRbEZtVjJKUVNYRnBWR3BIVmtGMlkxUXJVMHd2Wkc1YU4yVnVkV1JWY2t4eVZVbHBPRFJtDQpZWGg2U2tSTVEzZEtXbWh1WTJSblNsQnRiZzBLZUZKdVUyUkRha1pUV1VsNGMweEJNa2swYVhwMVVVeG9hRzl2U1d4TVVrMVFjekJvDQphRlV2U0RkVFZXZENRVXBEVm13NFdGTjRRV3BGWjNwSkRRcG9iVlJ5Vm1GdE1XZFhlVlJwYm14UVpXcEhTR3Q1ZVRSMk1FMTFabFJODQpiamhIVDJGdmRUQXdTME5rVkV0clJVZzFNWGR1V1ZCT1dFMWxNazBOQ25SblFUVk9LMWcyWnpOVU1pc3hLMEl4TkZWc1kzSlliM0pODQpjMEZDTlc0dk9FRmpjRmhwUW5kRlZGZFZSRXcxV2tZNVkzRk9OVWxPWnpSdFJ3MEtVVmR6Um5GNGF5dFNXakZCUzJ4d1ZucExUVTlPDQpNMGRtYkVjNGJXdzVlVXA0Y214bVlqYzJWMVZ2YnpSM1JUZ3hiR2RIWkd0Rlp6UkNiakJGRFFwNmIwVlBORVExV1dKd1psbFdWREk0DQpUV3AzU1hCUlFtUnNNM1J5Y1cxMGVVRkJUR1pKYlhodFMwZHBlamxuYms5a1IwcHdZWHBIV0VsaVNrRU5DblIzWjNWWmNFMTNhblp6DQpjSEU1TDBSRmFHdFZRa0l6Y2pZeFpIUkJWR0pIVEdaRVZuSmtaVTlHU1dGdk1YUlhWSFJ3YjFSbFYxSlBTVWRUWlEwS2MxaFdaa3hVDQpRMWhOZWxKd2FEZExNeXRqZWpCVFYzRktjV3BwVURSV01DdGxPVmgwVW1kUllUZE5RalJDTjFwUFdISmhNVlUxZURFeWF6QjREUW80DQpNbWRhYkV4cE9FTkpRMHcyUkVadU1uUkdZbFZaYjI5TlEwNXRORFpKTjJkVGVFNDFLMGhYYlVoNlNuSnBUMHB3V1VrM1JHUlpVR1JwDQpVbW9OQ2pkVkswRnBVQ3RFWjJwR1EyWTJUMEZNUkhOeWNraHBURzVRZUdJd1oySjVUMGQxZEU0eVQzTjVTMFpMYVdzNVpWTjZXVUZ6DQpja2w1WlhVNWJ3MEtUMkpzTVdweFptWlVaMmRvUkcxTlFtdDRTR3hMVEdWME1WbHFRbkpXWVhWM2RqVXJWbGd3VjJwVVYzQTRaak5EDQpUVTFKVkZSUFZIaGFZWEk0RFFwc1NIbzBSQzl2TW5WTFlsYzRTSFJTVDFwSmJqaERUazlVV0ZWakswZDZiRlIzWjJzeVRVRnVOVlpTDQpSVFZ1TVVGRE5VRXhkMVUyY1RRME5HZ05DbUp1VDJGcFZXUXlUV3RpVERFMUsxTllSM2xIU3l0ekx5dEhNREZIVjFvdlNYWldkM2swDQpjemhRVUhaSVFteHpNVzgyVkhNNEwzZG5ORWRJZGcwS2ExaEpWMWM0T1dKVFRrWmhhRXN6Y214cU4ySXZNR2s1TVd3MVZXWm1RMEoyDQpWemg0ZHlzMlRYVlNXSFZIZVdNNGQyaFVWbmxWYW5GNmVrdHpEUXBVVHpkNlRtVmxabEZST1hoS1lWaFZRMlZOYzA1UFZHMTRhMVZODQpNMkZvYjBKYVptNWxkbTk0YlRKcGFHNTRNMVJPT1RneWNtOU9NMk5vUlVNTkNuQm1ibEZGZUdnMWVHMVpSMGRQVkdwWVkyUm1iRmR4DQpObEJzT1RVeFJHSmlVRzU2T0dWM01sSkZlRWRsYVVkV1kzVkdWbHB4TXpJdkswdE1TQTBLUTJOUmVFMHhaSGN2VDJSdGJHaHBSRzlWDQpTWEIwVTNaVVpVaGhNRmwwYldOTmEyRTRRWEJTUkVGQmFWUnhRMWx6T1hjNWMxcGpXbGM1TWpJeERRcERNRTVhTVM5RlVEbFFRa2xTDQpSbEV5WkVKaUwzRnBWVlJUTVZORkwzQkxhR1ZLUWtWbGIxZHhUekpHZUVremR5OXhXbHAwT0RsV2NWQnNhRkFOQ21sR016bDFiREJQDQpZVGd5ZERZMFJTdFZaVTVFU0ZBNVZUVkZjV3gzWVdKNFQzTkRXR1JIU0hoNlFVUlhkemRMVXk5RlZ5OXZXV1ZWUjFWck5nMEtXakZtDQpjVzVHWlVoRE1YcEtaMlkxVkd4WEwyOVNLMEpEUVdRd1dYWktWbHB4UTJKT1lWWm5jVlZRVGtweFZtcDVXRkJNV2xkYVRIaEliMjVYDQpEUXA0VVRoaGRUZHdZMWhaU0ZrMVRFVmFlVk5hV25kV05uWTBORkZxVkM4MVZTOWxVak5aU25CM1MwMTZNVlJHVWs0NFJtUm9lRFZPDQpVR05RVFhnTkNtaEtRM0pKUlM5NVNFVmtkRmhXYUN0NVMzbFFhWGRFU21SMWFqUmxjV01yV2pkaWRscG5SeTlHWjFaTU1VdDJiRFZPDQpUMFZzU1hWMk9HVkhjUTBLZW5ndlNpczRNRGcxT1VwSVFYTjFSMFpMS3pCS1ZXWktORWMzVFcwdk1saEZaSHA1YkdGMFUxUTVNbWhPDQpSRXQ0T1hGeFpGWlljVGxVWmsxVERRcHhaMGsyVFZWRVJqRTRXRmwzVTA1Sk5rMHZlRlZQYTBOU1dsUkthRVUwZURJMFEwUkVZMlIwDQpaREJNTlVWS2JIa3ZOeTgyWkVsQ1JrRjZPVFVOQ2xsaGVITkxlbmxQVTJkNU0xSldZMUp4ZVdGVWJXUlpaMkZQYmpGcmFtdDNUakZ6DQpVWHBVUWtwVU1VcHVNVGxVWkd0Mk1YY3ljM05NTW5Walp3MEtNWEZDZHpCelIwaDZVVFZGV1hnMGNrNXplblZtTVZZeVNrMHJTMlpxDQpUMDl1YURsd1VETnhZMGxITVcweVFYaDBPVmMyWVhCV1JFczNhVXBZRFFwNE1HMDJRVGRySzJORVRISnFkbGhJZFV0M1lVRmlUWEJQDQpXa2RaZGxaT1VrWmxaRmhtYW5SRlZHNTFVemRpWWs1S2IySnRVWEY1UTFWVU5IVU5DblJqU0RkWk5uazVhbmgyU1VoQlMxcFVkbGhWDQpMMUZpTVZwVE5UbE5VRWs0TTJ0Q04xQnlWR2R6VkRRMVFsWlRhM2xuV2pSaVkyMW9TVk4zVGcwS2NHaFRMMWsxZDB4aFlUYzFPRzF0DQpNazluUzBSbmVUUlNTakYwYzNwRFNpdDNlSE5SZEV4Q1J6aERjMHgyWmxrelRqUlZUVmxYT0hwMFkzRndEUW9yU1ROa1VubFJNRVFyDQpSa1oyVDFGa2RHaDFiMUZWY0RoUlptTm5kV0ZtZDNwcVRrdEdTR3RaV20xV1IyTnRTbFJXWmt3eVEwNHhObkpOZGpVTkNrOTNNbk0yDQpRemxvU3pGaGVqUnVhRkZ1VWpKVlpFcFJWbGg0WjBkRVNtTnVPRWxHT1dKcVpGcE9NazlwVWsxd1RGUXZWekZQZVVzM1lYaG1ZdzBLDQpWMFlyTkVWV2QzY3pUbXRtT0dobVdtNUxSa1pEZHpsSGRqSm1UWFp0ZEhONE9FcHVWMkp1TWxKdk9WRkJlRVZvT1dWWEsyNHlVRkpPDQpjRFJORFFwb2VUZE9ZVTEwUmk5Rk1FeDFaVVZQVjJSUVJrUnFTU3RsU210YVEwbFdTMHBQYkRBMUsyRXpaVGx6VkhSeU9UZzJZU3MwDQpSMG81UW1KemIwNE5DbVIyUm5sSVFXWnlUek01TUU0MVdXeHZkblo2TWxCcE1EUlJRMHBSVFVGR1NtODRaREoxVWpKM2RIQndRbXhODQpXbWt4WTJScE9GTTRhemRQVkEwS1pIaG1jakU0UlZKalowZENXakIwUzFOaFp5dFBZbVp6VWxscVlrYzNUSHBWUnpCTk0yeEtZVUZuDQpPRWdyUVhRNU1URk9RVFZzZFc5aFdrWmpEUW80ZFU0MFkxQXJOazFpUlhWcFZtdG9aekJNYURSalpqUnNlWGxPYjJWallYWnljV1UyDQplVUo2YUhOWlkxQlVURTlqVlZSMGVWUklOQzlSS3k4TkNsaHdjMnBPWVVSYU1FVlFiV3RHVHpodk5VbHNPR016ZDJSelkxaDFOMjV5DQpabFpYZVc5SmNGSm1aMnh4VmxoRFJGVmlabGhGT0hVeVoyZEROQTBLVkc5cFVrRnJWVU0xUmtsM01WWmthVzFIVkN0YVkzQjRaVmN5DQpNbUpVTTJwQmJqUmllVTgyYW5kdlRraGxZMGR1ZGsxQllWRTFiWEY2ZVhWYURRcHZNamxQU2tkdlpYVjJiRVJqT1d3emJuWk5UM2htDQpRaTlDVW5SSWRUTldkRVV2YjB3dksyRXZRbFJHU1hWSGEyVldkbFJsT1c5bFJWSXdhek1OQ2pSbFNqVjVlbkJUVTNOT1dUaHBaMjl0DQpka1l3UkdaRU1HSXlLelpxZWtJMGVHSk9SR3cyYTBkUVdVUktNa0pvUkc1dlRuWmpObU5DUkZwbVJnMEtTRGx4YjFoeGFFSjFTMFoyDQpNRXBhVkZGa01Ha3hkek5QWVhONldHaHJUVWRxVTJwM1VUTmxRMHh1ZFdKUFpHWXdWVTVNU1U1a1JGb3JSMUZuRFFwcVJrUjRTbk5VDQpVVkJEU1dKTVkxaE5ReXMwTXk5c1RrSjJTVEkxWXpkYVQydGhhVWxuYTFOQ1NUbFRTR1p2V2t0a1ZDOUtkazFXZGtkT2MwOE5DbkJwDQpkbkJsTkRRMmRERklNMnd4VjJKc1ZVbFVaMkYyTmxobE0yMVZiWEZhY2xSVk9HVnVjbEZ2Ulhkd1luSnNSV1JKWTI5WlNURXpNRE5vDQpUUTBLYjFobVZrcGtlVmxSVkhONWFISnBOSE5RYlVWQmJXeGtZM1lySzNGVVVqaGxaVlZrVEZwTGNsRkhZbGd4YmtrMll6UlNLM0pNDQpZMlE0TnpWQ0RRcEtlVFYzTjBjMldXVjJXVmxVUm1kcVdXWnVObmhEY0dNd09WQTBla3B6Yldnd1JWcHNSRXhQTmxSek9FbHBjSEZqDQpZM0UzVjFSdGRpczFPWG9OQ21Fd2IycHpkMVJOVEZGeGMwMTJabXh5ZWxKYU5ETXdRM2xUZWxCTFNHZHJhVE5FSzFWclprNTZNM3AwDQpVMVozTWpaaVptdFplRkkzY2xGUU9RMEtTR1JMUkV0VmQzaExWRWRqUTJSVlFrRTFOMUZMVGxScmRUTjRaa2RvVEd0aGRsSXpiVWxqDQpUSE5TVGt4YWF6ZFZNVEpqVnpGcWJsTnRPWGx4RFFwVVJreFNlSEpUWmtZcmFVNWtVbmc0U2tJd1ZVWjNWbUkyV25wdFYxY3pSbEp4DQphR1Z2SzBSVFFVcG5SVFJLVmxWNlMySjFTa3BOYlVadU16Z05DbGhYWnpoeFN6SlpTV1o1Y0ZKSVNtcE9MeTlSVDJGRU16VkNhMFZSDQpXa3Q1TmxCMU5qSm1PV0ZqVjBadU16SnBUR2xCUkdsWGNqZzVPRmxIYmcwS056VjFNaXR3UVdGWVIwWmpVbTgyTUUwdk1tUTJiVE5sDQpTWFptV1ZKVU5IZExibWhaYUhSVFMweENTMWRsZVRWcE9YUXlNbkoxT0ZaWlJWQlNEUXB1V2pSNGJsRkRWakIzWVZWcWN6QjRNRGxrDQpUMEZYTkVSSlVVb3paSGcwV0RWaVFYSkpNVEJFT0VWUmNqSmhaazVMVEVRMVIzUjBhMGhOUlVzTkNqZFdSR3BEVW00dmEzcHZXbWRvDQpSMDlzTTJZMGNFWnVhaklyVVRJNVlXc3dZMkpEU2pGbU1XTldZVU5XWVdwUVZrOXFXSGxYZDFJdk5taHFMdzBLUm5adVIwOVNha2xODQpRVkZhYmtkYU9HdEVXRE01WlV4RmJWTXhWMUpQYzBSeGEwdG5NRk5LT1VRNE5sUjFSVVJQUkdNNGJWZExka3h3TnpSWERRcHRZekZtDQpZMU5rUVRjeFlURTFVVlpOSzFscWQzbFRXbE4xV0ZsMFZqUkpjMlJsVkhsTFFsVTJRM1phVURsV09VWlNiMDR2TlU5NlFsRnhUemNODQpDbUl2WTJGbVdtNUNZa1ozYlZkNlRVMU1jREV6UzJSSGMwdHlZbXQ0ZVdvdlZXSnFibFJsYUZObFIzbFFORmhyTmxsTlV6QlpUWEF4DQpSM1U0WWcwS1YwWXlaMlZpV0ZaYWJsWnhTekpuYXprME5rOHZSVkV6Y2xKcVYwYzFkWEpFZG5CR1dYZHVTQ3QxTmtsRVZIUlZaVTlaDQpOVzAyY2taeVoxZDFEUXBCY1hKU2RXcFJRMFl2YW5NME5EZE9WV05EVnpCRU5tOTJZamhGTkc5VlRHTlZNVWxqVFd4cFozaG5NekpGDQphWE5oUmxoeVkyMDFaVEZNTURZTkNrWmFVMWR5VFZOTWFUQldRamt3ZGxGMWJ6UTNOV1pwVEVKT01rSlBLMmRGYmpKVGJYUlVSak5TDQpiR3h1ZDBnd2FXVjBaME5NVDA1d01GWlliUTBLZDFGS01ITjBiVkJ4Y21KeWIyODBiazF3Y1RCNGRWSlFUV051TWxaVlIzSkhhalUyDQpiR3hvYW0xSGR6aFpjakZMVkRScVZGZG1aVGhPYUZJeERRcEdWVXRFVWxaTVpGTXpjVWxxVVU0eEwyTTFabFJZV0U5alMyaFBiamN6DQphVVkzTjBSdFRYZG1WR0pMVWt0WE5HOTZSemxyYXl0VWJHTlZORzROQ2tZMGNFdGxXRFk0ZDJsa1ZsTjZhRWhYTlVNdlZXMVdPV1JzDQpZV1ppUWtabWIzTnROemxYVUZwcFYyNVRja05xT0ZWaFlqY3hXR1owY0hSMU1BMEtUSFp1TTA1U1kxcGphVmhMWkZwYWRqUnpUbkEwDQpOMGh2VG01cFIxSm5PVXNyVHpOT2JWazNia1YwZG1ONFdFaHVOV2c0V2xGWFdYSldjM2QyRFFveVJVaFpTVWxxV1ZwbFRHWjVXRE5XDQpRVVpMT0VsR016RkRZbmxSY0dVeVVGSkNlVWhRVW5WRFRrTnZWMWxoT0VocGVscHFSVzlXU0VWUWEya05DbUpOVTB0R2RrRjJUVTk1DQpPRGM1TWxKM2VtWnZaa1J4T0dKNVEydG5jbmRKYUd0U2JqUmlRazFXUVhGdGFsbHRNR2RKV0dsdU9EUXpVMFkxVEEwS05URkdieTlYDQpkMk5sYTFOTGVqTlJNMHRQUlhwSlkyazVNWFJ4Y0RGdFkzSlZjVmMxVkdWdVVrbGFNRlpUY0ZGWU1Gb3ZUaTlTYmt3eFdGaHZEUW9yDQpjeTk2SzBWTk9WUlhTR1Z1V1ZweFVtSkpZMjU2TlhvME1uRnliRWhqTmt0bE9EZ3pRMHRqU0M4NFNWa3ljM1o0TDBkRlFraEdVVzF4DQpkRGdOQ2xsQ1RITlFWallyYVhGaU0yaHZRamxWYUhaQllqUkhkRWhOUlRBeU5tZE9iWE5SY1UxSFZpOUtZM0Y2ZWpWbldDc3JjMjFzDQphbFJEYzNGRFJ3MEtSR2xCTnpsdFlUQmxhelU0YlRoRWFWbGxjMjV5TlV0cVJuRnpOamh4TjBkTFpWSkllbEF4Wm01cFJVc3ZkWGxyDQpWVzlOT1hsdFFtaDFXSGxPRFFwQlp6YzBMMU5zUlN0bVFVWlFVSE0zZFhkRVYyTjJLMUJsVVVOTFJrZFJkM2hEY3l0dkwyVnJZMmt5DQpUMWhzY1RFeWQyeFJhVkZEVVdsNWFrME5DalJXWm1jek1YZ3JjM1JyYUU4elUyUmxlVmhWZFZWeVNXcDNPVGhKWlVWSE5YbERibXhXDQpSRkZ1WkUxTU5HbE9TWE5EUjBaalRWTkdhU3RwT1EwS1dUQTFXWGx3UlhaekswZ3JUakJ3YlRodFIyVTJWRkZoT0dsak0wVm5jMHhIDQplRmxUTjNGM1NXcE9SUzlqZGl0VGRUUlBSelJSU0ZCd1NHTm1EUXBLUlhJck5tb3hNV3BJWjJFNFVGUXpVSGxvVFdSRWFtbEhhMnBTDQpjM2R5TlhJclUxZzRiRmhNTldzMFRERjVlVW8yTTA1RWRHbFFSME13TlVjTkNsa3JTRWRUVVVsSmQyMW5aVU0xYTA5UlRqZEpPR2RPDQpSbTV2Y210T00xZEdSVThyT1VVMUsybFhielkwWnl0eU1XNVpVV2hIVVZSRGFtZGpkdzBLUzNSNlowSlVLMVpuVEVsVlVHWlhRbTl2DQpWRkF6YmtGSmFrRkdVbTF1WVRWcFVHSnljbFpNYjBNMlIyNUZUV2h1WnpSbFNsUk1OV1J1TTFoS0RRcGhXRzV1TlVoUmMzQkhVbVI1DQpSRUZNVVdVMVJITlVibk41YUVwWU9IZEdZV056Y2pnMGREWjBhME5GVjFkaFlXSmxkWEUyVEdSUVYyUnVVVXNOQ2l0WllXSlpjalZ2DQpNemxIZVd0Wk9FaEVlRVZWYVU5TVVXRjVTakpJYVRobmQwMWhXQzg0U3k5TFJsVnJVVWxyTlZscmFGZDVOMFo2ZGsxNVVnMEtZWGR2DQphV2RyTlhoelQzRkpWekZNZDNrM1F5dGpiMUZWVUZacFpGcG5iRmRyYjJsek1GVlhVbVJKVm1WbmVXSTJMMkpOVXpjeWJXcFdRVVV3DQpEUXBNYVc5S1ZFeExUbnBET0dKcGRVSk1Vbk52VEVRelkySlFLMDFCT0VOaWN6ZHhSMFZOUkdGd1YwdERUemRDVGxBM09YRjBNbFIzDQpVR0ZtYldrTkNuSkhWRlEzVVVKb2FDdEdNVWM1YUVobFpHMW9kR0ZFVm1GT1REaElTbVY1VUdoUU5USkZSakJXWjFkd2NIQmphMEk1DQpRVGt4TkVwSVVWbzNkZzBLU1VGNFkwSmphM1ZxWmxKbVpqaENaVlZ0TVRCRWEwTnNTMnRPUlZBM05qQlVjV3hZYm1Fck0wZDRRbTFIDQpTa2hIUTBGaWVFOUZNSGx2ZW5aRERRcHdiMmRTVDNSeE5qRXpRbWczVlhCSU5rTnpkWFZ2TmxreVpHOTNjR1J2VVZaYVNWSnNXbEJtDQpWWGxUVTNsREwzQkhkRmxxYjNOSllqRXZVREFOQ2pKaVZEUk5WWGx5Um1vcmJXaGpUamQ0YkZoeE5DOUtZamhXUnpNd1RrWmliU3RWDQpWM1ZMTmxsdlprZ3liV0Z2ZFVWSVRUZHlhRTg1YjNRemVBMEtkMUY1U0V4aFkxRm9RazVKVEdONU56Wk1kMXA0Vm1KV1dqZEVVbEZYDQpMek50T1RWbVNTOVViMUZSVFdSNk5XUnBkVVl3U1ZKalExTklLMWhMRFFwcVQyUk9TelJUWWtzNVNVOUhZM28xVFVkR1dYTmlNVXRvDQpVVGhMYUVGQmJXWXJRbWwxTWtsV1RtOUpiMmxGUW5VMVJGTmFMM2xNZERKV09XNE5Da1IwTlRWSVFYVkZUSEZtWVRCVk4yRXpRbGx1DQpkMDFUUmpkdk5YbHJNRE5IZEc1bE1VRTJWazVHTkhGT2EwRmhZMHRsYVdSQlQxQmpSM2s0V1EwS1QyeElhRVJ4TWpKT2VEUmlXREZEDQpObTlvUVVrMGRYUnhWekJGUmxFeVRGQXlOemxST1ZOTVZVdFRkSGx5TTJ0M2VYUkpXbmd6TUhGVlQxTkdEUXAxV0RVdmJXdENXWEY1DQpSbHBVTUhwMlZGTnVTSEI1TWtWa1NuazFZMkZoV1VKb01IUkVPVVZyU2sxYVZqbEhUMU5PYjI5TFdVazRORkpXUlVvTkNrcFROMmRwDQpRU3R4VkZwSE1XdEZVa2hVTWxsc1N6WjVNVTFTZVU5T1ptSTRWbmhZZUhoVFlXOWtjeXRvVmsxblFWSmtTRkpuZVdKR2MxWXpjUTBLDQpaMmhEZUhwbFYwaFpiamhaY1ZScEx6aEphM2w1YkVKSFpsTnRTMUZKVG5CUVpUSjRNWFZWTW00dlYzTXZjU3RhVkZnMlRYQjZiREZCDQpUalkwRFFwc1Z6SkNTM1pMVnpFelMyNDRSeXR6VUZwa1kxTm1iREpvVERocFJqUlNORFIwU1VkUVNIQjFLM3BXVm1KWk0wdHVTMnRTDQpSbkIzTlVOSlQya05Da3ByUkhOTVozSnNiakpqT1V4eVIyWnpkMEZKTW5OMU1raEVVVEJZTUROMlUyZDRRamhYV2twVmNqUjVWWEpVDQpRV3RrTWxjdk5FUTJZVE5RVkEwS1RHMW9NRTVNWWtwQ2NDOWlZbkUwUjFOWE0ybG5ZaXRTT0Rjd1ZURm9OamtyTVV0S1RqQlZibnB1DQpUM2R3ZEV0R2EwTjNlbUZCZDNSa1IyUjJEUXBWV2pOVVoxWnJSVU53WkRab1kzRnlabWN6Y0hFMmRGUlFiV3h6UkM5RVYybHpiRTF3DQpZMkZ1YjNoUlRVVkVWR2htU21JeWJtODNVMDVGZUVJTkNtbHhNMHhJYlVwMWFVTklSM05UVEhsUmQweHJjWE56VWtaMmFubHRSVFpxDQpTV2swTXk4eWNrRXpLMk5hVkdKRE5VcGFNemRKVFdSM1NDdG5NZzBLYVhsdVVIaHJaakJ2Y25KRFUwMVNVVGd2Yms1VGFFaHZXRVp5DQpkRnBHV1VnMWJVaHdVRzltTlVGeGJ5OVJZV2xrVUVGUk4zRnVWa2hJWnpkcERRcEJNRWRyWjFCYWMyWkpZMHRMV1daV2FESjRMMkl4DQpXa3BUY25sTFQyMVVLMnhNTkM5T2RtNWpWRzlKVVdrcmRuaDNjbFJRUmpkWVdsazRObThOQ2xRNE1sVkxTelZvTm1wYWF6RkNZa2htDQpNRlJMYWxsYVdqWjVRWGhTWVVoQ1ppc3JjR0l6VUd0NWVXODVjMVJIVkhkcGEybHdVV1pYTmk5VVlnMEtaM1l6UnpreWVuTmphWE0yDQpiRVZhUjBkc09IbHNVamMxY3psNk9XSnpabE5sUVVSWlZYZE1OVE15Wm5kWlQxUnNValYyTTNRM1RrOUtWVkZsRFFwUFJETk9UMDFUDQpPR2hrYUU1bVIyTkNZM2MzWlZrMlV6VlRiMVZ0U1RkT09GcFNWSEZZUWtseE9WSktjVWxUUWt3emIxUXlOMmt5Y2k5dE5FTU5DbVJODQpNbkpLTDJ4V0swcE1PR0o2Vm5wTVMwcHliVEpOYUM5Wk1ESXlhM0kyYTNwbVIxUmljMlZxT1VkNmVHTkZSRlJxZW5sM04xRlFiRTFuDQpNdzBLUm1ZMk9XeDZSSEo2WlZGVk1reG5USGd2ZVZsME5uRkhMemxJZVN0UGFHSmpOelUxYTNOa05ETjVNRkoyTmpadUt6aFhkMVJ6DQpObVU1WnpOeURRcHFMM2t6T1dGbGFrSTBaV1V6UmxWdU1EQnNkWEE0TUdWMVRXaEJSakZvY0ZSaFJraFhabmhQTmpaM2JuUnFiMUo1DQpRMlUxZURGbk5qSkZSVkVOQ2pkRVR6a3ljbTFLUjIxSlpHeDZialJQV0d0WWFXSnBSbXBPYUZGSldrNTRaMnhTWm5ZMlYyZExjM1ZvDQpLMk5UVjBweWVtMWlXVFZOVXpSdk53MEtkMGxwV0ZSS1dpOXJOalF5Y0VGV2FYWmFSMGcxUzNsalQxUTVOMlpIT0VZeGVqVlhTVmw1DQpOSE5qTDJKcEt6aHVWV2d6ZVdKR1FqSTRXa3hpRFFwUldFSXhLMDUyVUhGTVRrSkxUMUZzYmxGaU5Ha3JkMjFQWTJrMFpHUkhLM2t6DQpZbUZQZGt4VldXZE5TVEpoYnpWd2RuSkVLME5VZEcwMmFYWU5DbUpOZWpoWFpXRnlWbnBWZVhjMlJubFRiWFI0V25aQ09VZEhTRlJyDQpMeXRuSzBGVGIyZHNRbTlpT1hseE5raFhRek12WVVKNlVUTjZVbUpDUlEwS1FtSXJSbG95UkVvNU0wVkxURWg1ZGtWdFpuUkhNMlJqDQpiazAyY2xSMFREUjJaMjFZTjJ4b1dIRk9jazFNU2tGb1YzWkRiVzFvUldOdldVVjFEUXBPUlN0SmFrMDJlbVl3ZFhSTU9HUnZiREZtDQpNV2QwWkZWRlNrYzRPV2RFZWt4QmJqWlVha042VmpSWU9IWllkMnhCYTJSU1QwTnBNMk12ZUdRTkNqbDZLMjE2TkhkNllVZEthRWx3DQpVa1J2UzNwcldXZFJXRGhUY3pOQ1YzUnBkblphTjJZNVpsRkNLMjVMV0Uxc2RuQkxMM2syVldoSGIySlVkZzBLYjFKMWJFdHZVa3RKDQpSMGRhVGtNNWMxRXJkV2d2VGpkcmJscHZSRGRUTUhKUVQyVlNaVk55WjJaaldGQnlSVUZqTVZsc1JVRm1XVEJTWTBod0RRcEdhRk5uDQpNUzluYldWbk9VY3ZOVlIzU1dKWFVuRllRbWhyY0c1WVVFczVLeTh2YURCT2MwbzRlVlZhUVVKaVNIcFJLMWhCZFRoSE5sRnRhMWNODQpDa3RMWjNKS1dGZDZWekYxTDFCTEszaGhNVUpLVWpKblpuVkZZM0J1VjFaV1NsRTNWRFpCZUVGNE55OHpSMHhoT1VnMVdFMHhXVVJEDQpPRkJhVlEwS2NtNUNhbm95Vm05d1QzWjVUa1oyUW10MlRHWmxNek5xUldwaGNDdGFNM1ZYYm1weFFrMUVOWEJ3YjJWMWJYQXlOalJPDQplSE41YnpWVlYyMUlEUXBhUkNzd1IwMVdZbWhVYkVsb2NVNHhWMjl0Tm1KeWFsTTNTR2xZTVVWNFdFMU9Nbk5rTjJ4M2RIY3ZWRmRWDQpVMkp2VjJwTFdTdG5RVWM0ZUZvTkNrMDNjMVZKU20xeGNVMVlPVXBGVEZOQ2RHZHdiRU5hYjJzd2NYbDBhRkp6YUZaNlF6ZHZNRWhLDQplVGxLUlZWYUsxcE5jVUkxZEhKTWFFWkRNdzBLVEZaaGVVVTJZaTlNVURRNGNGcGpZVWx1UVdoNVF6UTRTR3BrVDFwbGVqRkhhVXhYDQpkMU5vYVRBNWVUWTBhbVJvVXpsTldIWndVMEpGTmtsRERRcE5VbEZxVDI5T2FFTkdSRmt5UWxKMFFrOXJjMmhsZEhaelFsRnNla1JvDQpTV1ZTTWs1SFdYRk9iemgyZWtObGVYSlZkVzlyWVdnMWFFUldieXNOQ2l0NlJuSkphV2x6VkUwMU4ycHJiMkZMY21wNk9HcDRNVGxODQpXRVV6U0Vrd1RWRkpTbEpNVFZKcWFGZEVTM0psVVVJeGVFUTJLM2gyV1ZSM2RRMEthWFpzVFVkS01EbFNWR052WmtwVE5qSjZUR1pvDQpWM3BDYTNsdGFXMHlNa3RvTTNSdFlqSTNjblIwYVZwWGRYVllRVVEwUlRBeE16aEhVVkl5RFFwQk5VOURRVkJ5UjA4d1VVWlZUR05JDQpaMlV6Vnk5eFkzcEpURVpSTjFKeGIyZGlkM042Y0RWeWVGQlhaekZzWlVKcFlqa3hXVEJtTDBGVGMwY05DbGhoS3poWk9WcE1SaTlxDQpNRFprY0d0NmRFdEdhVkZSUjJSaFpreGllalEwZFhaNlZtdFJZVmh3VTI1TFdVTXpaMlJLSzNWTGJ6RXJSbVU0UWcwS1IzRjRhV0pxDQpiMUY2Wm0wMGNIUjFXSGswVm1sQlJscDRhbXRZUVZSck5ITkpLMk01UjFkSE5GTnBPRkEyWVdka1QweDBiSFZtYW5WdGRWVm5EUXBVDQpZamxWZDA1RFV6TjFkM2xTT0VNNVQyZFNjbGMyTTFZMFZEWnJORkZtYUZCNlZWRlZNRXBEWWxkM1dWRTFNbGROWTJKSmQyZDFVakZwDQpkMmNOQ2xCaFlreFNOVUpvVWxCSEx5dHdOa1Z5VFZWTFJsbEpNM292ZWxCUGNHbFhVM05TUW1KaVQyRjBPWEZMWVZWSmJHNTFjakF3DQpVMlJzVFRKbVVBMEtkbVF6VDFWMlJFWm5VVk14U0hoUGRuSXhVRWhOWkZrcmVFZHFhelYxTjNaNVMwTXpXWFU0YUhKQk5Ga3ZiekYzDQpkMDVYT0c4dlREbFFNamx3RFFwVVlWSlBUelJzV1hOblRYSlVVbVpWVHpWSlEwSnlWRU5aVTJSUFVERjNUbkJJZGxWWGVYb3ZkU3RIDQpRWE5SYjJ0Q2Vqa3lTV3htWXpaSWExVU5DbnB4V2paM1kwNVJRVE5VV0Rkb2VtMTBZamhVZW5SWWMxWjRhMnhDTVdNelVYVkRTR3RsDQphbVIwY3k5QlFUSm5LMUJOYml0RU9GRjRSa3hFUlEwS1lWUmhaV1p2YmtJeVprRlBSRkJFWjNkTFNsSmFObUZaZGtsbFJETmxlRTVZDQpWRWRLTjBsV1RXSkVlV0ZPU25WTFFVVXdZM2haSzFWcFpFNVFEUW92TmxCTVpHdHdjVXB2V21Vd09EWlBPV3RWVDFWQmFYUkNOMWsyDQpUM2RWUjJ3d05WTTNjRVZqTDFSck5UaG1MMGcyVkd0UlkxY3dhRWhJYlRJTkNsQnJNWGRuTjNkWU1raENNRTFTTVM5WGJUYzJTbXhvDQpSMHBHUzJ4TlpYUm5lbTVSTVhaM09YQlFNVXRUZUVSWVFVazVPVmN2Y0dWMmRFbGxhQTBLVkdSalJucEZlV0Z4VjBSUmFYaHFPRGMzDQpWVUZ2V1UxQmQwNVNhR0V2VXpGeU1qSjBZMWR6UldkSFRrSkNNSFZFZW5aNE9EbEhOWEl2WkUxdERRbzRaeXM0ZDB0WlkwWkpiVGwzDQpOVmM1Y0ZSSloyZENjU3RpWTNOcWRVdDFkMUZaWTNVM2FUQlhOV1ZYV1RCQ1NUbDZOMFJJYldzdlJVUkZXbVVOQ2t0clFtOURRbU13DQpTemszSzFreGJIRXZObTkyV0RWclJYSlNVbEZFZUhodGMxVXdNMGhJZVVsM04zZGpNRTA1T1hKQk1YSnpNVnA1YUZaS1pnMEtTRzVVDQpUV015WkRWWVRuZDFNamRMVGpoc1lUazNVMmxuT0dSNGFXOXZlV3BOWVVKT1JURmllbTloVUdSWmEwUnFOMnBpZERGNlVISTJTSFkyDQpEUXBvTURCSWFreFVVa2xtVHpkM1pFRkdWR2RsVlhNemVFaHhOVTByT1dsMVFrOUZRbTE0T1ROMGFWaG1jM1I1VTBNeFJYUmlabmt4DQpSbFkzVUdjTkNrVjFhbFJSYlRoQlJUUnlibEJYU1VSdk0ydHNSREJLYmpaUFVtb3dSSGhRZEhOcVRXOXJhVzlNTVZFMlpESlVVVEV6DQpiMGRsZDJ4aFYwWkplZzBLWjJSME9WRlBhRGxaWmxsVVlUUkNRVWRtZEZSS09ISlBTSFJrYUdWa1lWYzBZMmg1Tml0V1UxSjVNRE5MDQpWblFyWW1JNE9IYzNTbGxRTm5WUURRcHBSa05wYW5GeFYwbFNaVzlwZG1WS1RsTTNkV2Q1WjAwMWEyZDFjbHBFZVhCUWVVNUpWRVJSDQpUaTkxY0haWWRXSk1SbVoyTkUxdk0zRmxUU3NOQ214UFFWTTRWakZsTWpWbk5GVlNiVWRMTUZRd2MydFZWMVpTVHl0Q2JVcEdZbkp5DQpXR0pHVnpSeFJrSXpWV2s1VmtwMGQwZE5UR3cyYUVneVV3MEtPR2RVTUd0RVJ6ZEtSRXRpY1ZobWFqWTRaV1FyY1VKbVJUaDFRa1p3DQpNRlpUT1dwaFdVZ3ZXVkV3UzJ3MlFraExWWEpaU0dWaGVrTnRUa0pZRFFvNGFGUmFla0l4TkRreVNtUkJSRFI2Y25BM1pDczVOMUpuDQpOV1ZXZVVrek9Tc3JObXRZVEhobGNWaG9hVkp4TURsUmNYcGllRVpqZEROMU5tVU5DbTE1U1hZdmExRkxUaXRQZW5jclpsTnlOMUY0DQpWSFJEYm1jM01IWTVTM0pYUjNnd1FuaGhURFpzZDFKQ1QwWjJZVW81UW10a2RGRkRXbTl3VlEwS05tbHVPVlJqVmpaMVVIWlhWM1ZLDQpja05pVGtneU9XWlRWRUZqUWxOcFVVVjNZelJqYWpNdlJuWlFOemh6UVRSS0wwVkZWRmx1UkROQ2ExRkhEUXBVYW5oS2NWaHBOSEZqDQpiMnd2U0M5UlUwVkJWMmRxYlRCUVVVOWFZM0pZVmsxb1pGVlJXR3hNZW5KNVNWZ3Jla0ZFZG1aUWJXczBPRTUyUTNrTkNrazNSVlpLDQpjSGhPVm1GTFEyaEJhVmxIVDBzM2EwTktiVUpZUTFjeGNHbHJhamN3U1hjd2JHTkJSRlpxWWpWaVZsSnRjWFJ6UkdSM04yeDJaUTBLDQpkMmRDVUV4M2IxQXlaRlpDYlZReGJXMTRkSEJtY1hkRkwwcDBkVlJUTkU4d09HMUJTaXRvZGxSNGVFdzJNR1F4ZG5aS1R6Qm1hVWx0DQpjRkZaRFFwQ1VqbHFSVWxhVTJaRlVtbzJkbXRJYW0wdlkweFBRWEE0VjJGdk9XUnhURzAxWTBzM1VFZHVRV3hDSzNoeVpIUlZUbWt2DQpaRWxFZG0xTGVFb05DaTloY21oQ2NqUTVSbkJIVkVscWNGSllMMFpKWVRGVU4ybHZMMmhqY2pGaFVYRXZlV0ZFVTBwVFZsUjVhVloyDQpORlJJTTFSTVdIbFFiSG93YWcwS09VMU5ZVE53TTB0WVdGZHlWVFpqWjNBMlptVlhWbXRWVWtwVVRHVjBabEpJZW1OdFVsRTRUVVV5DQpiMjlXTm1scWFTdDJSelp1U1RSb1NTc3hEUW94TnpkdmVtbHRhalp0WnpsT2VFczNRbUZ0YmprNFRXbEZVVVp4Y0hsQmJEWjNkRk5JDQpiRXBpY1UxcFkydGlRMWM1YTI4elpHeDBWSGh3WjBJTkNrODVVRUZMYzFFMFMyNDJRbEJ5UkM5WU4wTXZSazQzUzJJMmQwZEVOWGhDDQpXVTQwTmtKaGJtUkxNbTE2SzJaSlRXWk5PRE0xTTBoSVRVVjNiUTBLWjFkUU1HNXphbEY2TnpOd2IyMUNOazQzTVVWWmNXZDBWekJsDQpaVWRLVm5CNlozZFJSVkp4YmxBemFsTTFXSFJCVDI4MFJpdExNSHBoZHpjekRRcHlkamxpUkUwd1RTdGpNWE5EUVZSYVZuTXpLMmRIDQpRekpwYzI1SVoyUnpkR3haTkU1MVRXUTFZVUZGTjJkNFlsVklURGx1TlN0WlFXTjZheXNOQ2xONE5rSlJTblpYUnpsU2JXcGlVMWxRDQpObXBzVm1WNUwwWm1SVXg1UWxWT1NXaDNVRE5hT0ZSSmRIUktOV2hZV1Zkd1dWWlljQ3M1TTFwUlRRMEtibUZhV1dGT05ISmpUR3BIDQpMM00yUlVSTlUzTnlWRmMwUlhOblJtWkJUVFZLYzJwMlRsQXhjVEIzVGxBMGRIVkxXVzFPTkZvdmVHRXJaVUUyRFFvM01teExXVE5GDQpjR2hTYkRsUlRFWjFiWE4wZFdvelEzWnRhRTVaYmt4b1ZYWndUQzlqYlVKWWJsY3plRzFrTDNCclpIUm9OMnByYlUxTlNEQU5Da3gzDQpRV3BXYW5GemJtUjRVVU5pUkRkV2VUaE9Wak5EU0ZSa2RUbHFSRmRCUzBSbFYwSlFjRXBrZVhocE5UZFhXWEIyV0VKTWVEVmpjVk5tDQpaQTBLVVdVcmMxQlRlbmROWjNCVGFWaHVjbkJ6YVU4cmJtazBka1ZFVkhoUWJYQTRUVzA0SzNoSVZ6SjJhWGhYVjNZcmNFazRjR2RKDQplWE0yUVVkTERRcFdWSEpPZW5Cak4ycDNSMGxXUWtkaFkxaEhXVVZwZUVaS2JtVkZTWEZ6Y0hoWE1qUTNlRU0xY1ROTVFrcFNiRU5RDQpkVUY1ZEdKV2VuWkxPRElOQ2xKRVNDdFFabFV6UVRoSFYyRkVXV3BVWldjdk1FYzVVa1pFVG5FNFZrZFFkamt3TDBOQ1JXbGphRmxvDQpLMlozWmxKS1F5dEVVWHBuV0cxWFNRMEtPVTVFTmxNNE5FeHFXV1Z3WW5kNVZGWndiak5tVFc5V2MwMTBMMUEzYnpOa1owNTRNM2RLDQpiak0zUW5KWEwxVkZXblUyTlVkMGJubHVhbVl5RFFwSE9IZHBXRVV3WjNsUWJrcEVkamhPUkdGMGFqaE5TR1I2UjNFeFUzTjVia0pYDQpiR0ZqZG10SU9ERTNURzlTWm5veVVuWlhNME54Tm13d05GUU5DalkwUTI1eVpuVkZNelJPVFV0TlYzWnRNbWxSY1VkWWRURnZabmx6DQpRVFk0V0VNNVdrRTRUMlIyVEZaVlUxcElhME01UkRGR1JHRlRLM1I1VkEwS1ZGaElNMko2Y0ZaMmFFOXhhbVkzUTNKbVNHOWljM1ZVDQpaVEpOWlhOdlNVWkpNR2w0Wms5V1psaEJiRUZHTUhKSWRTdHZiRTl1TkZwclowOVREUXBJZFV0alRYTkRXVXRxVTA5c1dGcFNjVXBsDQpUVmhEYzBaMVFqUXpiRkpWVFhCVVoydDRZMWRCUXk5cVVsVm5TMHRHZFZOVGF6WXJXRFp3TkhJTkNtaElZVmQ2V0RZelUwNVZNR1pzDQpjbUZMU205aFZTdGFUMjFQTUZWNlUweHJiMDVQUTFaUmFpOHhRazVsZW5sNWQzVmtkRlJWV0ZwdFlWZE9PUTBLWlZnMFJ6a3lkMjR6DQpOR05vWTAxc2IyNTJjbkZHUjBFcmNtVm1URTFpUTJ0TU4zZGlVbk14UkdkVlYweHVVMDVFY2xwM1VVOXhNR0pNZUdRNERRcHFUVmhUDQpTRkJYUkhOMGRWZ3ZSRXAxYkRkNFVVeFZha05XTWxaQmMzTTJkRmx6VEVwRFpGTnFVRWRUVERJd1duQkViRkJaV1V3eFFuSk9hMHdODQpDbWhHUjFvMFlsTTFVMUowWld0cmN6STJWbTVPTmtKbVJIWm1jVE5LVkZwR0wwSjBTRGd2ZEdKWVpHSjVNUzl4ZWpGWlpHMUtlbmhFDQpWa0pSYVEwS05XdFFjR2g0UmtOeVRtbHRZWFZ2YTBzMVNHVnRhVEI2Um10b1RXVTRZWFY0VkRjeU4ySlhSbmRzVlhjdlNYSlNNR3RGDQphM2RMUWtOcFpYWmpEUXBKV21WRmFVbFplRTVrVFZoUE9VSlBSamsxT0VNM1RITlFTRGN3YVdkQlNsRlJTMWN6WnpoT1EzcHpTa2gyDQpNV1F6YVVWblVYVlhZbFpDZWtnTkNsZDNhM2xMVjFoWVpWbG1TWEoxTTNWNmNuaG1WMlZzV0ZscmVYaDRkR3hQYm1kak5VMUNabmRrDQpNVGwzTTJrMVYwTlliVlkwWTFvemFXZDZVZzBLVVVGUVlURnlPV0kzWnpGeWNqQTBXVzQyY210SFdsaHJNMlpVUTJwMFprb3hNVmMxDQpWbW94YzJvM1pHNXdOR1Y2YlVZMmJtTk5ibEI0YTJoMERRb3daSGM1Y2l0Nk1WZE9NRWROV2pGbVVEaG9VVXRPT1VGaFVrZGpNM2QzDQpUa3N5V21VMVJHZGFUSGwwVjJWV2JYZDZiRk55UlZaQmJWZDNUV1lOQ205R2JteGlVa2xqVlROWmQzUmpaVTFJTWk5cFNFMTVkbXgwDQpiVTgwVG10bmJWTmFTVkJIVGtrM0sybFpiRzUwUjNsM1VYSlRkeXQzTlUxeVZ3MEtaMjFJTlVkaVRYWTNVblpvY21RNGNHZEdPUzkzDQpaVWhJVEc1MU4yMDRlWEZJWnpCQ0wxZ3pSRXBaZERoWVZXZFBaV2hTVlc4eFNHWmlibXh0RFFwaVltUmxhMk5DZUUweU1USlZZbVJsDQpjRnAxTUcxamNVTkNPWGRZVmpsaWNYaElNMEZ4Yml0UVRYVkhablJoTTJrM1FVRjVNMWh1V2xjMVNYZ05DbkZNUzNCc09FcGFTVlJVDQphMHQ2TWxKdmNrOVJVMEVyYTNaek16SnJiRzVXTkRWc2F6TTNURXh5YUN0WFdFZHpZMkYwWWtWSmRtdDBjR1pRU3cwS1EyeFNhVXdyDQpPRFEyZGtwQ1IxWk9VbW81YzIxdlVWRnJhMlp2YTFJeE1UbDFhRkJvTkhwQ1YwdFVLemh5ZWtZdlMwVjZaa1JJS3poRVdVUlFEUXBCDQplRFJ0T1U0ME9XNTBRMjg1UmxaeFJXUktTVUZFVWxobkswbzNha1ZhVlZZM2VFSTFVVlJ6VFcxcFZWbHljMnRHTmtSMU9URlFLM2xJDQpNV3dOQ21aQ2JIQk1haTlwWVVkbmQzUkpiRTU0U0dseVJsaHNZVXhSVG1SNEwyTnpNMk41WmxRNVFXTnVZVUk1TUhKU1NrTlhUV0l4DQpka1pQVFVOQlZnMEthV014TUVJMk9GaGtieXR5VmxneWVWSkRZamRuTjJFcmMwdG1ZakJqY2xOdVQwb3hjMm93TlRCd2VUUkdiVzExDQpTMmxJUTNCVldubENPVzEzRFFwV1dFSk9NblZUZEVGaVYySm5UM2huWVdWc2JtNHZOM1J4YkRVNFVrOWpXVE13T0habEwwWm1aSEZNDQpSVWxGZDBWMWMxSk5kelF2U21WNmNtOE5DbmhzYkZaMWNucDZZalpKYjI1RmMwWkxVbVkxUm1SbVJEZHlTbUkyYVVWSFF6bGtVVE5vDQpUVlJMYUUxRFF5dElWbEJwT0haSVZrRnBUVTRyTmcwS1VHbHhkbVZtTmtWbVltc3pia1prY0d0TFNYcGtXVEZLY1c5VE5FbGhkMFJsDQpjV0pwU0RKV1luaEVPRGh5VFhwU1oxTXdhMEV5ZURoNlIzcFhEUXBrT1RFNGExVk5VR1ExVDFwUE1sQTRXRGw0WVVkUVRUQm5PV3REDQpSMlY0TVRKVEszTm5UR3BPT0ZkRFNuaE1kbEZ1U2xwRVUwczJUbmx1ZDNnTkNrMDBWMjVSTWxSR1JtUlBaSFY0T0hKblJFMUpUbWx3DQpUMlo2ZFdWME9DODFjbVpIZFZFd1VsWkRRaXQwWjNkblQyTk9SRlExV1hkTVZESTNSdzBLVTFwRVMwOUxXVUZIWTNkVVdIbEdNakJODQpiVXhaYURGRk1HOURSWGwzZG5aVGRTdG9PRVZKYjJkUGNEUTNjM041WW5aVVIwVTVhR2RSYmtOVURRcFBaQzlDTVdodlQwMVhhREoxDQpaWG92ZERCcFJVNUlWMUF2ZVU5UmVEUnJMMGxKYWxaMlUyZEhWblZqUWxWWGVYaFlTVGhSTHpaT1JHSTJSMW9OQ2pOYU1Fc3lObVpUDQpiazFITWtFNGNsVkJURlk0VmxRNGMwdGFWMDEyYkhOcFVWaHhkMFk1VVhkRVNVbGljRmt5T0dSWVlVZDZObkZ4YVdjelNRMEtaRXhzDQphRXBwYWtsYVZtdFVUbU01Y2pKclRrc3lOa1EyYldVNUswMW5SM1oxY20weFkxTnZiWFpwWVVKUlIwNHhXamxsWTNWV2RUbEdTVmMyDQpEUXBzUjJ0aWFtOUdVVVJrWW1kMWNWcFVTR3RpVWtGM1p6Um5NMnBRZEZsV1pHTkdhbWt6UldkTk5sZHpPRzFqVlRWMWNITmlObVZXDQpaa2RNYkhZTkNuQk1RM2RKVldKSllteENWM3BGUTFWaFYyNUROVFI2V1UweGJWWkpNR0U0ZERSYVltNHpUMGt6Wkdkc1MzaDVjRXRKDQpibGhxZGpNd2EydFZjZzBLYTFKTlRpOUtUMWd3YW1ZeGRYUmpRalpZVTJkbU4waHdNbTVFV0ZWT1prRjRhMHhGVWxCWk1IaFFNRVE0DQphWGxMTTNCUGJqUXhaVzlDTVRkMURRcE9SV3g2UjI1cloydDVNREJMVlRSR1JqaHFOMDR2YVRsWVQxSjFRa2xWTkdWUFRGUnpSbTFJDQpXRFp4UzFwU09EbE5ZM0JWY2xWS1oyZFJhRk1OQ2xaU2JVNXFlRFZqUTNod1dIRkxZa2REU1dkRkwxcHVWRVJGYjNkcFpUUk1Za0pzDQphMUZZWVZSV1lXZERPVGxJVEdOUlJXeGtiMU55THpRclVBMEtaak5tUlRseFVIUmliR05UWkhoS1VVOTROVWM0VDNRNGVITlhlV2hLDQpaM0pRTWxkclQwWTFVRlZQVVRGR1RVZGtRbVpJUlZsdUwxTTJWVVZaRFFwUmVYa3pORVEzWlhkTU1sTXhVMEl6WkZBelZXUldkV1ZzDQpUMHRtTW1WblUzVlhLMVp6ZWsxWFFrTkNVRlJZVjFsTGFYUnJTblpUZGxCV2JVOE5DbTlYVVRsTVNYUjNUMHQ0V0hsU2FFbzVjMVJCDQpNMXBZYmpGTFEwNVpVRVZYVVVaNk1HOXpaa1IxYldSV2RXVmpWR1J6WVVoS1dHc3pjSFZqWlEwS1YxTlFPSEJzUzFWclVuZFhNVWhSDQphbXBzV0ZkamFVMTVkVnBZVVNzdk1FVkdSbGxsYVhsRWVHNTJWelZNUWtGdVdVaHBTRmhOWVVOM1VIVktEUXA2ZFZwdlZqVkZaa2hPDQpZa2hyYXpaS1JrdDRZelJQWm1OUFVtdFlTME5STkdOTFdVVktTR0ZWYldKd1pVeHNRMWxtVjBOWmJWUjZjbGs0YjI0TkNtdFNhR3h0DQpSVTEwUjNReVIwTklNakE1SzBacWRqZDJaM1J1S3l0M1NIYzNhbEJSWVRGbU5HRnpkV1Y0T0ZOaFZ5dG1SbGwwUXpaSUwxTkpkZzBLDQpVMGhtZWpGclRHd3Zja3RHYkRsS09GQkROalV3ZGxwU2QwRlVaa2RhYnk4clQwNXplbFpTVWpSM2JISndiVEpHWm5saVpXRlhNRFJtDQpRbTQwRFFwUFNtTjBhSGxOTm1zMWVYaFZSVEZQVmxaRE4zTXdWWGx1VWtoU2JIZEpWR1pxZHl0cE9FVnFUM28xV1VJd1RYbGxZMkZCDQpSVGhwVVd0bVUzRU5DbGs0VkVsR1JpdDFiMUZvY0dGcmFtVjNLM1Y2TWtaSmFHdHhUR1J0T0RnMFZVRjRNWFV3YzNaMmJGUjJRMmQxDQpZakpQT1dsMmRqaEJWMUZJVkEwS1puQmFReTgwTVV0Qk1ISkhaVlExWTB0bFMyOVhUa0pqUVc5dFEya3pXbTFZZDBGeFltOXZkM0p4DQpaa1pEWlZaNmVuZHZkbXN5VW1seVVFNU9EUXBRVVhCalpFUnJZakpaY21oM05rTXpha2xCTlROSVVFMU1Ta05uT1doMWFuSTJXRnBtDQpjR3MzYlZkNFUxWkRLM0p3UTBNMlVVaFBPVVJETUVNTkNsRTRaeXR5UVRkalFVZHVWbFJGZGpRM00yZG1NREJQTDJZeWVVZG1RMGRqDQpSMHB3TkhobE1XZEhZVFZ4TUVaeWRHcGxlVXgxT1U5U2NtVkdiUTBLUmtOVWJIbDNkV2hFUkc5TGIxTlhhR0VyZEhwdGVtcFBaVVpsDQpWbGxYUmxkamRqUlRiVkV5ZFhGWFEwSnJNSGxtWnl0aVpIY3ZRbGxxVVZwSURRcEpkazUzVkhkeVJHUllhemxJUjNOTmFUWm5PRlU0DQpWM1kzU1RaS2VWaHVSekZhUTB4TFNDdDBWemgwU1dwU1lsZFJkakYzTTNkRU5YZHdWQzhOQ2poc1EySllSa1lyZGtkR2JUTjVhbUZHDQpNRkJzWVhkWVpVRklaWGh5ZDBaSmRVcHlTRVpZTnprM1ZGTjJaMDg1UlZnME5XSk9UM05WZFRoVFJRMEtUM1JzWVRnM05GcHNPRWhRDQpPV0pzTlhVcllrcHVRMDlvYkhScFFrOVJVMVp2ZVU0Mk9Fc3ZZVlJDVFVwWFpGQnFVM0JCUW1aamJ6aFViRFkyRFFwbE1UTmpSbFJpDQpPRXBTT0RGWmFtaHBSR2t3TTI5R01sWnVhMVJsT1hCNlJHaFpMMVppS3pkeU1Ya3hWVFo1WVZKU05UbFhkemx6TVdWWVJUWU5DbEZ4DQpNMGhQWXpGRFZ6SllaRXRvTm1SdVIzWXZZa2swYjIxS1owZE5TbEJ5Tmt0cFUza3liM0ZGWlVSRllVSmhNVFkxUkRad1dWZzJlbFVyDQpZUTBLTjBSRlpVbGpOR1pXTm0xM1VESTJSMmxqV1VOMlRuazNRM0ZvVEhFNFNVbFhlRVZwTldKT2NXSkpjVWx1WlRSRFRscDRhbFF3DQpSRUZTWkZGVkRRcFRjVzB4WVdSRGMydGFNMlFyYUZjNU5rWmpPWFZpYUZkb00xWm5iVnB4UVZSNlFqYzJjbGw1U2xSWllXcG9ka2szDQpPV05pT1ZFMlIwRkVaMUFOQ25SV1IzSm9TVzVWYjJWU1ZqTk5VRGRPYkZSak9GUXJWRzVwVkVSWFRVRkRaRzlTWlhCSWVtNU9lRXB5DQpUQzlYU0M4clEyZFJPQzlRVVZSS09BMEtOMWgyYkhoRmFXSm5Uemx4UWl0eFkzcGxLMkpuTjA5eGQwOHdjbFYzZFRBMEwxZ3ZkbE12DQpOWHBTZGxsUlVpdHpWVlowV1ZWTFdHVndaVVU1RFFveU5DOUlaalZIZG1VNU5VTlpOMVIxVjAxS1NYZEtXRGhSVDFZd1dsQjNTblpqDQpSVWxRYlRSc1kyUkZlV3RqWldWa1oxRldRbEJSYzFRdkx6Y05Dak5VTWpKUFJsUnJlWEZJZHpjeGEyMXFNek5zVGtaaVRXRTBOSFp5DQpkWGRSWmtreFRETkRaazByZVdkbVZWQnpjMFJ1ZGxOalNrdHpZazV6WXcwS2J6TktOelZJT0hJM05FVndlakJaZUdvM2NuaFZlbmh1DQpkVGg1VVVOYVNFWTVZekZ1WVN0ak9EUjBNMnQyV2twV2NISTVNbGhMWW05TFVIZ3ZEUXBIWVZSQlZUWnBaMjA0VURoU1drNWFNbGgwDQphelJ0UlRObFlWRm1iWFJUV21oeFVGTnJRalZ6VUU1cVdqSlNZbkZDZDJRMFJVbGpZMDQyUzNjTkNtUXhSamRzZEUxRk5WUk9XazFxDQpWamhVV0RCS1NWTm1iM2hGTVROUVdHdHpVbXBzYjBSbE9HdFpVbVJPYWxSWWVtOXVXbkF5VG5CVVRtbEVidzBLUjFseWQwdHllRmd3DQpWakJQUm1wU1JVeE9WMGcwYkhremQyNTJSVVpTY25kWU5rc3pXRTVhYmxGNVlUbFJObFkxYWs5NmJWa3JOakJDTDFwWERRcDBabGRpDQpVMkY1VFdaVk0wOTNZblZ2ZGxZek9VZGpLM1ZzV2pscFUwbEZlakkwZDI5R1puVkxUbm9yTDBWUFduTTJkM1oxVm1GT1RYWXJlR2dODQpDbmhhZURSSldVSTJhMlpuWjFwSFNIVnFjVlpXZDFGcE9VVmxXbFp0YlZwd1FuSXhiMkpRWjJ4dWVXTjBMMEZTWWxSRmVuaDBXRU4yDQpaMU41YWcwS1REQmlhM0pIUlRFNGJXcFJkVlJMY0ZKT01ubEtPRmR6WVZKTFoyWm9lbHBQUzNwbmRESkNTVTF6U3pOdlVDdFFUazQwDQpOMGx0VkhwM1owUkpEUXBuZWs1SFpDdGlUVkV2YlRORmEwTlZUblJRWkZoNGIxZE9kVTlqU210V2EwUXpZa05VTldKaVpuRk5ibVJXDQpUVEU0ZDNVeWJXMWFZVm8xV1VzTkNrVTJNM1JvWjBkcEsyUnlNMWhNTmtNMU5VUk1TbXN6TUVoRmRtWjVUR3B3ZVhwMGVGQldNWGxJDQpRa1ZaWldwRFJGcHhXbk5UV0hGNFRESklLdzBLYXpoVFNHRmpjRE5RUjBSSmR5OURSVmQzYkdNMFRrbGtWVk5EVEVsWlpISk9lR1Z4DQpkVkZIY0dwdE9EaEdkMVJsVlhkU1N6Um9OQ3RQY214NERRbzBSbkY1Wlc1NWNrczNlSEV3VDFOdmRscHFZemxEUlhsWFRUUjBNMDFLDQpNRTFhV0RWMWMyODRjamRwTW1GbVMxaGxka2hNVkU1V05GRXlRMVVOQ25aVFkxcFdkVXREVGxWcFIwTXpkV05ETkhCc2RXSkVPRE41DQpNMk1yV2xWSlJsQmthM0ZPZDJWeWIwbE1PR1JyVUZacmNuUnpUU3RHZG1sQ2VBMEtMMEZXVmpKVmFWazBNWFJZU2xwWGNVaEJkbmN5DQpkVGxIVldocmFWWXpWelJTTDJkTVptcFhia1ZaUm10MldsRXpUMGxpWlhwbmNrRkdZakF6RFFvd2IxQllXVEZ3T0d3MVF6QnlPSGxzDQpSUzlsZWtSdVlXTjZORU01VkVOV2MyWnpkR3BRTUZVdksyY3hibE5pTlhJNVpUVXZTak5DTUhWS1NXWU5DbUZUU0VadWNVcHpWblp5DQpWV3BHVDJ4VGFrUnBSR3BGWm1zdmRWRnhWamxtU0ZGUU1uazNOVXBhV25aSU9EVnhhWGxoVVU1U1QwTjNNMFFyZVEwS2VVMWtiSE5GDQpTVTFZTXpJMVZHTjJWeXROVEd0NVpuSlZNbGcyU2xwc05YRTJkWEZaTDJkWFNWWjVUMmhyU210cFFXZEdOeXRKTjNNeWIxaGxEUXBuDQphRGRRVm5aa1pXcERkMlZKYTBjeFpsSm5iMjg1ZDNNd2FrbzBVRTAwTUdob1ZVaHBTVzkwVUdSVE0zcEJlalo0TWs0dlFrRnVSbVZZDQpORFVOQ2xwTlZHNXJhVE54Ym5rdllXeFRjVmhaY1RaWWJHSnFkRGRxTlhSQk0wczRaMUJVVVhSWlVsRkNWVmQyTXpGeWJFdDZTelZUDQpTbmhaV0d4MU53MEtUM1J2TTA1SmExaEdZVlpMZVc1dE5rcFBOSEJ5UTNsdk5IVTJOMUpOZFRJMVIwaERNMmRqU0VNemQzazBhRWh3DQpjVVZoZUhKMUwxcDBNR2gwRFFwcUx6ZHRTVEJ1Y1dvd2Rua3paV1p6U21WMmVqRkNZWGRZZVRsU2RHNVZja3h6Uldoek1uQkhlWEExDQpOVnBtT0V4RU1ubEJRbFZpYWpOd1VXb05DbkpNYzNSUU1YcEVOVkJXZEhGSGRuZDBVbUZ3WVd3eU9FRXdVbXhKUkRGeGMzTTVSbmRJDQpXa3hEWWpBeFoydFBXV3c1WTFGSlpTOUNjVlY0WWcwS1dsZElVSFpxTjJGUlkweHZhbFZxYXk5bVpsVXdNbEZFUXpGdlJDdEdTa1psDQphM00xYTBZckt6VmpRbGxCU1VWd1RFeFZkelZSVUVWTWVrUXJEUXBUS3psdU1qTXdZMFkxU1ZoTVF6UXllRTFIYkVsSE5GcGpNbE55DQpRV3BYY1ZWdlkzQnJjRkIyYW5sYU4xSm9VVzFNWlc0MU9FZGxOamRFVGpRTkNuVm5TMll3VlVGMlRWaFdXV00xUTNaMVJuVTVPSGsyDQpObFJNTVhBM2FqaHlVRlpEV2tSVGJuQkpXazlHWnpOQ1JuRlRiazFEYTNwek5WVjZkZzBLYkdsTlUxWlZlVk5tZW5kMGFqWjJSbmx3DQpiRFpuUW1ReFVtazJaMlZpSzBZeVoxUmFVM1JZZDFKc0wwVnZZVzQ1Y2tSaFVXWmlNR0V4WlV3ekRRcHViRlZxTUdKMmN6ZE9VVEZHDQpOR00wWWs1WlFsaGhWbVpKZFVsaFF6UkNkbFJaWm1KR01HUjRVRk5PYkZsd0wyVTBWbFpyUmpSTk1IWXpVRFFOQ2todmMwOTFNRmgzDQpRMlJZUkcxSFpIRldUMDU0TUhSNWNYSnpSRUl5WVZwd1dscG9hRmR0YjJKdkwzaEVZemg1U0haaGRqTXpNRmhVYVVwcWFBMEtVSFZxDQpZMkpXUlRGVVdVMTFNRk55TW13d1RtdFVLMWhaWlZacFprdHNOVUZzWjJaUFRrRlhLME5VYTFrd2JFMXdZM2cyYm1GeFYzRTFRM2xwDQpEUW95WlRWSlowOHhWMjkxYTFoVGNHNXJjbU5oYjJKd2VEQklaSG8wVWtWUk9FMHlRMEp4ZG5FeGIwOUZiVTB2WjBoMlRGTmtURmR5DQpUSHBHVjFrTkNrSkVaemgwU3pocFN6UnROREpEWjA1SGJYSTROR2RPSzNCRGNWQmFaazB2UTFSb1VTOWlhMXBCZVVSTlUxVkdNMFJwDQpaMHB5ZFVsU1JrbEVSdzBLWlVoQ2JqUmpOMFpRSzA1c1VrVlFhV0pYY0M4NFUwVldPVEJIWVM5bVduUlZiVGRFVEU5emVGRTRkelpQDQpSV0U1TmpOTVpFTTVNVWN2VFVJd0RRcFhZM05aUnpkaGRWVnpaR04yUjJ4R1NtOXNNM2xKVWtoRFFVaDVVV2c0YWxNM1puUXpRa2dyDQpVbTh2ZUV0cFIxVnhWemd3V0RWT1UwTlVPVzROQ2k5b05YWlNjbXBEYVhnd2RuSlFSWFJvU1V0WU1tRldZVkEwUzFaQ1pWZFZhMVJ1DQpZbTl1UlcwemEzUm1RMWQ1WTJFMVVYRlJNbFpwY0U1aU1nMEtjMmMwY21oRmRWSnNWMWxOU0hka04wUnJRWE4wT1M5cGRqVjZOMGg0DQpaSEJYUlhCRWN6SXdSbTVVTnpsSFVWTkRWV2RZUkZZek4zSnZVRUpERFFwWVFrODRVbkJFYldJeVVrdE5UMWsyWkVwWGQxZzBVWGM1DQpWMVIzTVhZNE15OHlUbUkyVmpOeVRtSk1lamxJYldocmJHVjRXVWROVlVOak5sQU5DbkZKZEdKeU9FdDRha3B0VkU1T1ZHZ3JSMDlDDQpWbVJSZFhKSVlVOXBiSG80YURseFEybFhWWGxMYm00ek9GWllLemRrVWpjclRVbDRaMlY2VXcwS1pucHZlall6ZEZGR1owSlRjMnBXDQpibGt2Uld4RlVVWlJMeXRTYlhWTWRtOW5WMjFhZWpCRmRsbFNNV2h1ZEcxRlYxVkxRVFozT1hFd2NqbHREUXBRVDBoUVJra3ZZbG80DQpabGxrZFRadlFtbEVaSFl2TDBwbWRHMVVUV1JwVkcxNmFURnpURE5DTkhZeVYzRm9RVlpMWTFsVWFsZFVTVkppU1RZTkNteEtNRVJODQpTRFZCU2sxUWEzQjZMMEZ1WjB0bldYaGFUamd5UzFsT1NHbHVkbXBPV1d4QmFtNW5RekpsTVd4UGVFOTJZV0pKUkc5Vk56RmFNdzBLDQpSa3h5SzA0MmVYWjJjVWhRVDNOMGNtWmlkMUo1UldkMU5tc3pZelJGUlROUk5IUkxMMEpOZEZOMlJUQkZjSEkyUXk5M1UyNDRaemxWDQpka05tRFFwdlNrTjFWMjlJVkUxTFF6SmFhMUJHYzNKMmVIRjZXazVzYVd4dE4zVjNlbEpyTmtocU1FWTNZVUpTTlhCSFluTlVZMm8xDQpPQ3MxV0d4Q1ZqSU5DbUpwTUVsbWNuZzNaV3BtVG5KeGVYRlhTbTAyVTFwdWIxbG5NMmNyYVRNMVNFOU1SazFqVGtaNE1rbEdORFpODQpkR0ZvUzFkcmVXRmFOMEkyWkEwS1ZuVndTM2RDTjBSa1MyWmFSMjgwVVRod2NYSndWR1Z0VkhWNVdFOTJVRUo0WlZVeFdVRlhWamxPDQpTbHBtZW00eWFIbDVTMDlVTUVnMmNWZGhEUXBQUlVabmNteGFTVkowZUN0cmFGRXZWMDlRS3paVGFtWkNOV0Z5U2xOaE1EaGljREY2DQpiMFJaTjJ0M1JUaGhVR0UxTTFaM1FUUkZjbE5GY25ZTkNqWXlRM0l2UVdKNU9FSTNSalY2T1RaMk9ISllkV3BIY0M5VFdrOVNla0kyDQpZaTh5Y1ZSTmNtWnhXazlYYUhoNllUY3ZaVkZ3UTNKcU1VbG1lUTBLWjA4eGIxVjVhVTlFVFRoQlExUkZZMGRYY0M5M1lYaDRTVlIwDQplVFJxV1RnNVNETXZTekZMZFhOd2VsZHdaVXRPTXpkS2NERXZUMk5EVFhCRURRb3lWRGhrVW1sbWIxcEpNWFpSYlVkbmNVazFMMmt4DQpNM2sxV2xWS1IweDZhRFJJY1VvMFlVbHFlV3MyTkhScU5HRlpia3MxV0dacE1tOXpXRmdOQ2pKNk1GZHZlRXRxVEhOdVdtWnlTbUZVDQpaM0JzZFV0bmNIaGtVRlp4TDBGNk1WVm9lWGxVUkRSemJtWmhNazQyWjFOc01rOVhWRmhYUjIxU1FnMEtRMjlzWnpSemJrNUxUVGw0DQpPVlIyU2xWQ1ZEVXlOREZNV1VGeVMwUkliVWd5Y0ZJMFdEaE9ORWt5UXpaak9VeHdVMmRXUkZSWWRIWlZOMVpGRFFwR1dVUmxkU3N6DQpXbEp3YldFd1ZXRlRlVlpJU1d0VFZGRllaa3BqWTFSYWNHMUlNRTF5ZVhWemIzRnVUVm80TUc5WE5rNUdVaTlqZFdGVVRpc05Da0ZMDQpNMjUwUWtWdU5HWm9ORWxFV1ZKaFJWRlZRMjloVVZWT1NuWTBNU3R5TWxKU2EwbFRUblIxTlc4cmFtTmhUWHBtZWxZek5HVlFXVUZFDQpidzBLTmtWR1ZEUjJjRUpYV0RWVWJHVkVOVWxUY1VScWQybGtUV3BwTTNoUGNIUkpXWGhLUnpoUU4wVlFiSGRsU1hZd1lXTlZTM0Z2DQpha0owYTFJdkRRcE5NbXRHTjNsU2NHZGxiRTFKTHpKVWJYWmphRkZtYml0U056VlBWbXd4VlVoSVUwWlVUSHAyYjB0TWFHWmhObWtyDQpjalJsV21kQ2ExZGpjazBOQ2tkbFpIb3piV1F5T0hRNVRrNHZSV3B1YkVScE5ubGhUVGhFUVU4dk9UVldWbFZETlZsNFMwZGFUM1pHDQpOMmxKU2pkS1VGaElOVkJoWTBWc1lRMEtOeXM0VlZKaE5HNVFXWGRCYkVaU1dIWnlMMU52VVRORmRrZENUbWhaVTBZcmQwMXZjakpqDQpMMnRUYWpaTmNHTnJlbVZMV0dWR2VHd3hRa0ZIRFFwaWNqa3haVGhKT1hCVGNXNU1PRVF3YzNJNWNHNVlVSGxuVms5b1MzQkJjR1JLDQphM2xFVFhVMFJITm5SWFZUWjFKR2VFMW5hMHRIU1dGNWNtZ05Da0ZwV2tGNk9FSmxaakZLTVhWUU9UaEpUR1ZaZEdkb1YwMUtTbkpUDQpUa3hpY3pKUVowNHdiREZ5WmxwMmRtVkZNeXRzTTJoWlMwWkNaa2t2U1EwS1FrUjNXRkpaTlRoTmJXcHRTRTFuVFhKNlZrSkljR3RpDQpWbFZRWlVFelMycFNVbWM1Ym0xc1pISlNUVlpIVmtSR09HMUphVnBrWTNBMFZqbEpEUW8yYUhOUFlsRnpXalJFVFVWcmFYZFBZMFZtDQpka2x2TlVSYVZHdE5iSFpMYkVNdlpVdGpiV2hIYjBSelVFMWtWVEpvU2pGUmJXSjJRV1pSY2swTkNtZEJOMVJLYlU1alQzUldWRXRZDQpXa2cyYldObVZFeGlaMEZaTDNsSE5rNWFibTEwVkhOQ2FsbGtTRGR5VDJGTlZWb3pXR1UxTUc5SlNtdFJidzBLZEdodFYzQTRNRVUzDQpZVk41VlV0WFJrdFZjVGhyTjI5d1QyOUJhV1J2TXpONlNtaDNkak56YW1NeVlrVmhkVzkwV1RkS1FuVkpTME5CT0V4c0RRbzBTMDlxDQpXbFk1UWpZemFVdHhVV2c0YkZOeU9FdzBPVGN5VUhGSU1tMHdRMVJXYkhkNFZIcEZaVFp3WkhwVWRrUlNOV1pWTTBScFVERTVSVlFODQpDbG94TURZd1pHaEpkRE5ZVEd4TGRrbHJNRWxPT0VST05rcFZZVU40V2xCclIwTkxUSGxTWmxKTldIWkpVbE5ZZUN0NVMzazFia1oxDQpURzUzYlEwS1Fqa3llVmxEU25weWVYQlhhRzF0ZVU1dk1WZFVVMmN4VTFOT1JFdFhiVzFoUkcxcmVuQllWakZJZDJ4T1ZuWXJkbEpsDQpibTE1TVdObFVFMVNEUW80ZVZoek9FNVBjVXRpU21SclNHRlVXVWxyYTBWMFozTmlaRWxwUzBablQzVnFhRkYyUnpaU1duTnZTell6DQpRMUp6ZVRaSmFFbFRTWFZOV0ZRTkNucFRjVU5xWjNOS1IzQlliWE5CZUUxb1ZubExkM2h4YTB4TE5VaGpZVEU0ZFVoUVZHVm1WemgxDQpjR2xWWTJoS1RGZDNjVEJhTVcxT1NrUXhVUTBLWVU1VWRqaFFSRXR0Y2taRlRUWjVURkZZVjNaeUsxSnVlbXR1WjFoUmRUbEdhelUzDQpZVmd3TlZsaWFHc3pVMlpoZGxweE1FRlVjR2M1WVM5T0RRcEJVVVJqTkdGTlNqVkpNMmhMYTNkd2NFNHhhMFoyTVVFMGQxSXJSbkZwDQpOV3R6U2padWF6TXhOR0U1Y1NzMU9VdFZOVEZQTTI4elZIaFZSVGdOQ2s5TlFtMWthMmxLTUZSVmMzSlhNVzQzTkhscmVVNUVUbVZZDQpUalpWZVRsdFZTOHpjRmRhWmtGMmVWRnhRbTVRYmpacU4yMW1VVVJuTmtOVE53MEtVMkV6YVVkdE5WSk1XbmN4TkhWQ1JXa3ZWblpwDQpka2hFWjNRM04ycE5lbUZCU1VkdU5uVkxUVFZ1Tkd4SlpFWm1ORVIwUVZaQ1JYaHFkMUJxRFFwamIzVlliR3hJZDFSM1QxRkhZbWRTDQpRV05IWVdVNFQyOW9lR0Y0U0dWNVEweGhTRmhZUlhsVmJFbHpOVFZ3YjAwM1pVa3pXazE0U2xWeFdua05Dak5JWW1WYU56WlJRMFo2DQpZalYwTUdaT1pFTjViVk5DSzBoR2JVSnRLMVJzVDJZM09VUTNXVEo0Y214SGJXMTZhRE5KVmxkSWIxQmlPUzh5V2cwS2JGWlpTalZpDQpRMUkzU0c1cWFITlVVR3gzYzBWalkxUlRMM05PTXpkRFVWcDFSVVZpTW5GMFQwSmpXblJ3V1ZJM1lXNVhSa2x3UldWRmVYcEZEUXBYDQpZVVUzYjBkUk9UY3hOV1JhVFd0NlpuUm9RVWR0VW1KQldETnhjVE5GTms5NFZEUnpPV2xNT1RWdE1UazBXbmhvVGxKS1prdG5VemQxDQpaRmtOQ2tzdldtWndVQzloZGpWVGIyMU9RMk5sUTFScWRqWjJLemxZUldrelNqZFRVbmx0YVRKRU9VRmhiVUV2VG1weE5FTXdUME5wDQpPWHBRWjBOU013MEtRWEJwYlhKaVdFZExUalpMV1dWcU4zWmFNbmR1Tm1JMlVISTNka0YxU0VFd0sxZHJiUzg0VDBGRFJGYzVORkk1DQpMMkZ1T0VwWVQzY3pUMjg1RFFwS1NVWnpTR28zVkZKcFZYWnNTbmRIWVdJck1HeENNRlU1UjNaaVdWSTVSMjk2YkhkaFMyMHllSEI1DQpUbnBGTjJaQ01rVjJUVVV6U1UxNFJHc05Da3BKTDJ3M1NIRlZRbGRNUVVGVU1sVXhWRkZpVmtWNVRtUnJja3BzZW5WVk5FcE1jbWcwDQpVVTlGZWt4b00xcHNNVWQ1WlcxVU1ESnBLMU5VTlEwS1lVVlpXblY0TDJkNWRpOTFWM28yTVU5TFR6bE5OekJJTTBjeVdFWlBhR3hsDQpZVzFhUms0cmNIaERUSHAwY214d1VsazRNR294Um5Sek9WVXpEUW81U0ZsNk1YWkdVbmxCT0U1eFptUXZSWEJUWkRoeFRGTkZiVk5rDQpTVE5EVG5SVVpHdG5lSEJXYmxZMVlreEVVVGN2YkdkVlIwbFZOa0ZZV2pZTkNtUkxSbFJ3TkdSQmFYaHhaMGhYVTJSMlUyTnJUa0owDQpSWEJITkM5RGRpdDNabmxqVUZWdE5EbGFkVzlqVmpNemMwWnVOSE1yWXpGT1RXMUJTQTBLUVZsSFdUbENTRFpOVjFVMGJGTndNVkpoDQpRa0l2VEdsWk1ESnlMelp6UVZkVU9XSlhRVmwzY1dsaVpEVm1aMFEyWm5KUVIwSlJlVEJsTTNoSkRRcGFUakpNTWtkUFVXeHNkbk5SDQpOSGRNTTJJM1ZqbGhMMHRUTURJdlpGbzFPVTlSTmpseFpWYzBVV2xEWWpkVWNXdHFhekJ3YmpodWFUVllObVVOQ2tGc2VtMUVhME5TDQpNbE5yU0RKeE1uaFViVUZqVlZoUE9ESTBaRzFHTW5sdVRHWnpUMUJhU1d4RWRFTXJTRE5pTVZkRGJtRjFURXBYTTJwa2FBMEtWRUpEDQpkSE5ZTlhwRFl5OVNLemNyTjNsdmRXMUpTbEZqYXpsdk4wSnlMMEpxTjFod09FOUVTREYwUkZWa1NXMHdiM1pJUlRoamJYUnZiazFpDQpEUW8zT0daQmFISnhNMGdyWTFOc1VGbHhTRkZQVFRWeUwxWkxiM05qTTBjdldWWTJNREo2Y0RZMmQyWTRZazVVWXpGR1ZtRjVUR1pSDQpLMHhIYW5ZTkNtcDRUbXRTWTBGcE9GQndPSEJCV20xemNGbFdNekJXZFRWMWQxWTNUbUZ5WlZVeFJHbDFieXRETmpWUFQxTmtXR1pGDQpiVEV4WVRSVVFURkRVQTBLY1ZRNE5WbG9USEpIVW0xWGRHSjFOa0oxWmxwa1EybGtkbUZFYlRoRVFtMUpRMk5vVFdOdlVFWnBTV1UxDQpabHBQZDJwUFduazJkelowVGxsQ0RRcGpOVEJLWXk5SFpHTkxVVEZhV2paVGFrVkVabTlzTTA4NVYwTnhURlI1VFdadFdXNVZja0o0DQpialp2U0VSSGMwdEZValZZTkZaTmVHWkxUamtOQ2tKRU5rSXZTRzQ0ZVZreU4xZ3pURkZyYlZFMFZuTmxWSGd2ZFZWMFQwWTVTVVZ0DQpOekJXTUVaRk9WTk9abW96VGpKME5GRlVZMFZ6Y21kcmNBMEtLM0JHWmtWVE15dFVjMjh4VkRSTkswcEJUeloxTDJkbU5YUnFNREYzDQphMUJXTTJScVVIQjJZVnBzV1VWbk9HOU9hRzR4ZGpGclNWWXZObVpCRFFwREwwdEhUbVI0U3poUGQxTTJZbk5IYlZKbmVHOVZlR2huDQpRbkY2Y21FMWVGWmthemQwWjNwQ2VYYzJkak5YUkZveFZEZzJOMWRYZVVkbWNsUU5DazFoWTBSU1QyeFpSMUpsY0hkbFdGRTBNM0p2DQpPWFZKWkRBM0syNVpXWFZ6U0d4MWFsRkpaMEZQTDJGV1N6ZElNbVZUUzFacFpEbDRka1ZDYWcwS00yVkhZVmxKVUU1S1IxVkNSWFF3DQpiRFpSWlVadVZWQlpia3czUlRsWmJsZHdVWFJ2VWtoQmEzTXZhVzFEU2pGWlZWWnpabTV4ZDFJelpFaDJEUXB0UVRGMk1WbFpSMjlLDQpiRzVWTVZWWkt6WnpNSEUxTjNOUWVYUllhMVpFTkdFM1NUaHhObnBVVlhNeU9Vd3pWMFZWZVVZeGNXSllRMEV4ZDFBTkNtOTVaR0V5DQpXazVpZEZkcldXUlFkME5HWTFobVFrVk9UR0pKZFROMEwxQnlVR1o0VFVwT1VWZElPVlpqU0VkaFRrZERWblJXTm5nM1MwSXladzBLDQplVkpUVWtFeWNFVjJhak5JZFVsUFZHWkJUbWd2Y1RGVFMwRkJjeXRUUW10aVlVRnZhVU5vZEVJeUsyUTNjMEpwYzFoMk1ITnBPR1ZwDQpXR1pMRFFveVZreGlTV05vYjBGdlVuZFhVQzlrTkhRemNVMWtZMkUwVG5wemVHNWlNbTU2VkhCRFFXMTFVVmxTY0Vab2J6Z3dXa1ZuDQpVR2hIUjA5UmJsWU5Dazh5VTFwNmJuYzNaWEp6Um1ST1ZYcG9iSHBYU201cmNFdGthVkpOVlZaUmFsaE1ObmhJTjNsMlRDdFBSMDl6DQpTMnBMUVhJeEsya3ZkbkkzS3cwS1UwMHhPVzFpVFRjMVNsbE9kSGhZWlZWcWFHbDBiRlpCTkhCMFVXMUNWRzVwZEZCRFUxQTBSbVZoDQpTbW94VkRZMU9ISXZORWhETWxKbWMyRXdEUXAzV2pkSlRWbEVZWFpyUnpWRUwxUk1OakZTZWxaTVZWRkxhV2x5Y25WaWEyNHhVVGhIDQpabmQ0Y2pKbVVFMVBiblYxY20weVNrWndhRFE0UTNRTkNtMWlVVmx0VERGUVNHdzVPWE5xZWtOeVprNXVPSFp3V2xWUmVWVmlha016DQpTR3dyWVhneFFrVjRRVkpoYjNwdk5HZDBNM0pxWlRrellsRllSdzBLVEU1NVRtUjFObGhoZERCTlZVMWFWWG8wUzNNclFtUklZVVZxDQpSRGhYY2xkb1ZVNTBNV2sxTmtwNVdUUkViRFYwUzJoUVNVdE9XVUV6VjBWSERRcDBhRmRHUTJoc1JuaHZSek5SYms5NWFtTkxXa1oxDQpkREJ2TldkamJVMXFja3BwVW1sTFRIbHRjWFF3YmpWNFNWYzVUVTgyZDJocU56TnZWak1OQ2xGaGRIaEpVMHBYUVdaSEwyVndXblp0DQphME50U0U1VFdGcEdhRmRaYUZsME4xUnlaV3BGYWtWRFkyazNSbWxYVlVWMmMySnpaMnd6U214S05nMEtSa3BQWkVwcUsyMXFjalJPDQpkVlZoWlV4UWEzRjJiWFJpZFZGS1FtUnFlbU56UlVZNWQxaDFiMHRLWW1oblFVcEdVVlJXYVZCRU5sSnVaR2xuRFFvdlZETXlXbmg0DQpMMGRpYlZjclJTOTJjV3BTVFhwVWVYbHJWME5vWXpaUmVHWTNZM2xyWmpZMmVrNWhiVVptVW1JNGNrcHRTMFpzVjFCemJtTU5DbEphDQphM2RJVWtSR1ZsSmxPSEJqV1RNMVdHdzNMM2d6YldWclltWldSRVIzZEdoc1dVNVhjVWxUVlRGNmJVbEdNVWhZZUZKUVJ6bHFZMDVhDQpSQTBLVW5abWNHRmpaM2RyWlZKTVZFNUpibGd2UzNSb1dWQXJPWEF4V1dkWFJEaGhlbU5VWWxGclNXMVBlV2x6YjJ0amIzaEhZekpwDQpTMUYzVmk5QkRRcEtOM2xuY20xb1JGcHpNMk13WlRWRlRYRkxVVk5rTmtjdk1GbzFWM2RtTkRkYVZEaHJXRVF6VjNrNEwwOVFhbkpVDQpWVVZ1YVdweVozcENPVFVOQ2psdGMwWk5XVlZ5Unk5WFNFZEtaVkJuZVZsVFlrcFZZMEpoVUdsbVN5dHNRMmxuUW1ocllVbEVTU3RJDQpTMGc0VUU5WFdYWjRPVzlGVFhOdk13MEtabnBwUW5kelF6ZGlaamh6VTFKQk5XVjRVbXh2YjJ4WldDOW1TalJoS3pFMmFYSTNiVlZJDQpiRmRvWkcxbVoyRm5lalJTVTJoM01FWkVOV3hZRFFwbGFsWnNhakZFYzBaeWJFdGFibk5hWkU5RWN5OHpWMDFwYjNwV1IwNTJTbTR2DQpVR2RaYW1GWlIzaHViRXd5VGpCdE9HZHJWV3hOSzJFelMxb05DbnBWZVVOb0wzQTBjbHBuYmpoV1FuVlhNRVYwY0ZBMEwxbDVkWEEzDQpLM2hSTUZvMUsxQnhWa1Y1TlZsMlkwOWhTR2hVTjJOaldscHBjR3BvVmcwS1lsUlFja3g0UmtwRmVUSTNabWhQTDJwV05XVjJOeTluDQpXVGd6UVRsdVJHbHJhbkJ5YVhkaU1URm5lVTV1VlZKRWVrRlVTRTh3TjNFMFEwd3ZEUXAwTHpkTFNVbFhaV3dyWVZZeE1XeHpZWEpUDQpja1oyVldZNWNuQm9ielF6VFdGNVdGUndjbGt6VTNGRGNFcG5SVE5hZFhkWkswZFRaakJIVWxrTkNqTTJRVEo0Y2tWeE1UbHJUVWN5DQpWRVZGUTNvNVp6WnNRVGh4WlhWUWR6ZFhabmxDY0M5T2JscGxlVGN4VVU5QlFrdDZUMUYyV2pJelZGWTVkQTBLUkRWSE1HbFhWbXM0DQpPREphT1Vvdk1EaDNZbTR2ZURsSUswdzRiMkp6WVZoYWFGcDRVamd6ZVZKU2RtUjBXbGtyUlV3NFNuWkRlV3BNUldvNURRcEJjbTVJDQpia0pwY1VnelpHTnpMMDlHVEhaUGNXSjNaMVUzY0hSeWJHTkZORk5rVDA5TFlYcDFjMnB5V25WelpHRlpNalphZUVGQmFrTlFiVVFODQpDbUZTZFhWbGVFTTFRMjFxYWt4d1NtZFRORlVyTVVvMVRWTm5kek5UVmpSNFNFaHVXWEYwYm5FcldVbEtUekU0TlVVcmIyVlhjeXRqDQpjMVZDWncwS1IxbzBNV1JhVFdRNE1GaEVSV0ZDY0ZKak9YSnRiSEJoZG5kSU0wMXphemRXTlVaYVFURkNXalZVTlRjM1RGTTBMMnRpDQpjelJKU1RZek1qaHJEUXBOVkZwTlJuZ3daVEpFZVRSd2FrNXVjblpEWTFsb2MyNVVTVWgzUVV4RVZVWjFaM0ZhY0VvMk1qVTBiekI2DQpSMWxoYzBaMFRGTmhjVzR6VG04TkNsVmhNMDlqTUdkWFRWSkRUREJEYTJaTFQyRm5jMjhyVEc5V2EyNXdOazUxT0c1NFNrNVBWV1Z3DQpkRVkyU3poRmRUY3hiVFV5T0ZZelpYbGxMdzBLSzBaRVVqTldjVWt5ZGsxcFJVcFVUazlVYlZCa2EzRlRVRUpNVmk5U00zQm1aVWh0DQpWVXRUZEVoVGMxTktlWE5sYTNKM2Ewa3laak5IWkU1dURRcFpkRFJZTUc4NFpUaHJRM0ZFYTJGVE1VWkhhR3BKYkhWV09ERnllbWhoDQpWVzgyTWpnd1VucFlSbEp2T1hNeVoxVjNLMmxMTm5jeVltZFFaSEFOQ2xZeFRVeDJVQ3RqZGsxQ1FYbHBZbmN2UkVWME1WQmtVM2d4DQpjbkp5ZDNOT1RXVmFjVXRSYUU1b2NVRlJlR2d5YlRadUsybFZPRXgyVTFFNE1RMEtObE5HV0doSk1rcDNUWFZ0WkZJeFVrOWxTRTFzDQpkRVZ1YnpnMVYzVlFaRXhFU2xSWk5rMVhSWGxYTURWdE1VWTNSemhKV1hkSGJqbGtkbGRvRFFvNWNrbHFNWGMxTUhZeVdWUmllalIzDQpXRlpRWlRVeldHOVdOWGRhVERjdlMzVXJlRFpNTDBNNU5Ib3lUVkpYUkVsSGRVaEpVM0pZYW5odVZHME5DblF4VEdaWlIxaHRPSEl4DQphM0pIVDBkQlVFZDBVRGs1Y0ZkdU9GWTBka1pDWkdGYVlscGhZakV2UWk5eVEyODVZMHgwY3pkblJFdDFNbVJLUXcwS2NDOHpPR1pqDQpiRFZ5UW5WUGFrSmpUeXR4S3pGaWFHNTNORGMzYm0xTlUwRnpjaTlZZDFFM1NUQnFLM2N2WTNOUUwzTjRja2hVWkdOeE4wcFVEUXBWDQpSa2h6YlVkS2F6TkNlWE5YUkVONFprczJXak4yTm5oMFpVWnlUalV4SzB4dE1ITkRkRzlpTDFSSVMyazBiMkZvVWxKdlNuRTJWV2RGDQpPVzhOQ21veGNFTnFLMHBoVDBacU9IRXZNbmhMWldWak9VRmpUbWh5UjNwNE9IWXZUMlp1YVhweU4wMXdURUZxTlVWNVVHUkNRelJVDQpWU3Q2Vkc1bmNnMEtkemhXWVhsVGJteGxXSElyYVdOTFVsRjJWVTFQUmxFMFowcHpkMVkzTWxwUFptbEtVM0JoVmxCa1VDdFhNMFZsDQpjVzVNTTJGNWEwMWFUbTVtRFFwRFFqUk1LM0kwWjNBeFNFSjZNbXRtV0hweVpYWnJaR0p0U1dkUVJuaHdTM0V3WkZaTU9VRlRhR2xhDQpPR1prVVRod1JqbDRaVWd3WjA1MVMzRU5DblYzTmtKQk5URm1XbUZUZWprNU1DdFdORzVGVkZkcFRtVmFMMFZVYkhWQ1FuZ3ZTVFpNDQpSMGN6WkRnd2RYRjZMM0ppUTI5MGRpdHBOR1JqTlEwS2RUSXpVVXRRYjBoT1lUVmthbVoyY1ZKdFlqRm9UVlJUWVVkWFJIUTJUVnBCDQpOa1E1TjNablRESjNaVFZFTWtNNFRubHFhblJvZWsxMVMwWmtEUXBoYkZablZVODRXVWR2UkZNNFVsUnZSbk51VEZjdlNsSllOemhNDQplSFJsTTNkaU1tWlJUMVJCYUVOVlRFMVFURzU2WWtKRGEya3dSMWhVWVRnTkNtZFNiV3hpVmxOVkwwWlNTVTVaYmpnM1JpOVhXRWhXDQphRzUwWVVVMFZHTTBjakpxV2xCa00yRXpZMWhSVDBOVkwxbGlZVE5uVlVjdlNWTlRhQTBLZVhSTWJEZHlXV1JXVlhJNVJXbE1WRGRYDQpRVnBqV0c1SlMxa3ZiR2hHZURCTFdIQlVXSHA2SzBsS1pXZERTVzUxV2tWTVRFUm1Za3RCYjI5NURRcFVhbWMxTmtwdFVXdEVVSGsxDQpWQ3RaY1ZGT05FeEdZMWd2U2tvdlZTOXBiMmwxU1RaNE1tdzBiR1JUWkhnNU9YSmhhWFp6YVZJdlRHZzFhV29OQ2pOYVNWaHhVSGxVDQpTMk0yU2tJNU9WWndlRVJ4WWpKTVQyaFdaRzlKWTBGT2FGRnVTMlJrWjBWWlltOUNZa1JOVVU0elJHMHJVMUI2WlRWMVp3MEtVMUpQDQpXV0phTjNwaFEzWklabEoyTVZaelQzUnZXVk01UnpoMmFtWjZiMHg2VFZkaVMxbGpaVEp6VUhCWU5IWXdUbGRyWm1oNE1tYzNSU3RGDQpEUXB6ZFVwT1RrVnhSWEJTVUdGcGQxVlJPRzE2WTI1dksxQTFUbmhsV1RkUEt6WmxRa0YzZEhWSVIyUkdPVUZtTmtoSlVYQXJXbVJ0DQpTVlJLTURrTkNuTkdTRTlsVG1WVGFFWkdaR3h0UlRSWGFFcE9UVkZDWWtaeVVscDVTa0V2WVZNNFJYTjFVMU5KY0hVd2JVMVFWSE4zDQpOMWc0WWtWdFlVeEdadzBLWm1aT1JqaHBabE5pWkhkUFdFRk5RaXRyYzNoblpsVnpZa2xNYTBKNlEza3pUVlJCTW1aRFVHSnpkMmM1DQpiemhPWVV0dlJWRkpUSFpDV1haTERRcHVNMDlDZHpNelVIaHFSR2REVVdJNE1rTllhREJ3UlVzd1Z6TlVTVlJQWlZONVZFbFVSbWt5DQpkV3hPYmpoUFkyUjRMMlpqV21aMGIwSnVLMlFOQ25KRU5Fa3hZVzVCTnpKWGRtRldlRFpOYW5GRVYwYzVla1pxU0RKWmJFcENhblpKDQpjVnB5UmsxdUt6WmFOQzkwYzFKRlZYZERRa0ZrZFVrM2FnMEtOVTkxUzJReGFsQmhXWE5RU1V4MFpqTnRZMVUxYmxFMWNUbExhRE01DQpNa1I1ZFd0RWRGcFhOR2xTV0hwdUx6ZFdNRTkyUzNOVGVVRlBXVEJFRFFwSFpuVndVMWtyVHpaSVVFcHpaSGt4Y3pKYWFrRkZlakJtDQpkMWhJYjBWTGVHYzRZazAyUlhOT01tNWtObVJJT1V4ak5scFBaSFJIVWt0cU5sb05DbTVEUVVWUE0xTXpXRVY0Y1RoamVXVlhPSFJ1DQpNSGR3ZGxoRFRtRjZRWGxIVURoS2RDdEJTazU1UkZGa1NXWTVkVFpQTlVaaE5HUk9iM1ZUTkEwS1IyMWFXa1p5YTNZeFRHeHhjalJ5DQpTRzFOVUZoaWMxZzVXbmg1YjAxUGMzbDJSVGxqUVhsQ1QyRlVRMUZJWjJVd1lYZG5UMGRHTWpVM1ZUbHZEUXA1YVZSTmJIcFFPRXg2DQpaRUo0YWtOUmRsUnNNRWhEVGxsQ05qRldWbkZ2WVZwYWNuSjRVakZOVFVsWVdHOHZhbHBZTm5KVk5ubDBPRVZSVFcwTkNqQnBZbU5qDQpZa1YxWVZKd1dWcHRObmRoWkRORVYwWlNjRkZJY0RGNk1VUkhjRzVxYlV4eVdYWjBURnBqYVhkblFqWkRVMmRMVVhoR1JrVjBaZzBLDQpTVzB6V0V0UFNFZDJUbFZqYVRSaWVITlhOa1I1WWs1WU5WVkJlR3hQZVc5b2MyMU5aMDVUVG1ZeFJVUnNkRFJ5Y1dOM2MySjNkM05SDQpWbEpCRFFwa2RrNVdNMmhTTjFGSFdVMUZXamN4VFdoU1V6ZHBVMlIxWmxGamNTdFBWREJEVWpGQmNpOVJlSE0yZVhGU09URkZiMnhuDQplamR2TDFWalNVc05DbEV3YkM5RlptSTFUamR6WjFWS1J6Tm5aa2MzUlZGM2RtbzFlVE5PT1RsdGFuQnBWbkEwZVVGSE9XOXBabmxUDQphQzk1Y214YU5rWklkemxXZHcwS1YweGxaemxGZG5Sd05sTkRNM1pyYlhGU0wwNWtaVEJyVnprM2JqTkxZMXBDVGxkb2QxVmpOemhuDQpUakJEYlVSM2RIaGlRM1JsTlU5cVJXSjNEUW8wUVRSU00zSkplbmhyY3pWV1NETjVXVE1yUTBWRE5taFdPSGhyYkdvNFltMXBZbXRyDQpRbVp0TWtVeVNuRklhRXRaTUVwME9XWldUbXM1V200TkNqYzBXa1ExTXpGamFrTXdVVW94Y25OMmVIRTBVWFpCZFZkQ01VNDNjMDk1DQpNV0pyU1dGRkswOTBRemRXU1NzMU5sbFRMM05sUkhkTU0ySnVPQTBLWkROa05uWmlhRmw2T1U5elNXOU9ZMWhOWTJ0TWFrZDFZV1JQDQplVEZZY1hFelozRmtla3BaVFRGeVVDOUVPVXBoY2preFRtUlJUMjV4U2prd0RRb3JNamgxYlVRdmMyaENORWhrV25OSE9FZFVZMmhPDQphMlZUUVdRclZYQmxRMWcyVXpCbGVrdHlMMWxOWlhGRVRsWllaalZvTlhKMlN6aElPV2dOQ2xGalFqUnlORWQ0VFRCNk9TczJVSFZODQpURE5oVFM5SWFreFJSSGh4UzJGR2NtUkxRVzQxZVVSc2FtaHhWRFF3YUdoUVZWcFViM2hEWXpKb1ZnMEtlVXBtT0ZsUWNFNXRlVlZKDQpiamhIWkRGTWNXRTNWVUpEUkhWYVVrTmhjakZXTTFKT1dqSlpWRTVDWlRKd2JXdE9OMDVETW5sQmRrdHZTVlYyRFFwcWVtaEVhRFV6DQpRMlJDT1RRMk9WSmhSRWh3VVM4d1pFNHlhak0zU21jelVraGhTMjluVXpFM0x6QkxRemRvZVZwRlVIWjNSbko2ZFdwcVoyNE5DazV3DQpPWGx0WjFNMFEyZHdjMEpFUkZacFJWcERUME5GU0ZWM2QxZG9iRlIyZW5KSFVHSnZPRXROTTFoNEwzcDRPVVYxTUU1M1UydDVhMHBsDQplZzBLUW5GS05GaEdOMWxvY3pGMFF6TnVPVGQzYjNwNWNHeHZhRGRZVHpGclFXb3hNa3RUYWtGM1MxZHpXWFUwUmtkaFNHeHNVWFF2DQpTbWhsYVVOb0RRcDBkekEwUmxKTWJXUTNZMDR5ZW1OM1RuRXdUa2xJYkN0SlZqSkZWSFl5Y0ZKaVpqZ3hTVkZHTDBaV1RGRlNObmcxDQphbFZ2Ukd3MVpFaERlVllOQ2t4b1RsRTNjV0ozYTNkd2RuQk5haXRFUkhKV1R6VmxjMmR5ZEU1MVZrUTRla0poZUZjck5UVklSRUZyDQpSVkJ1Tm1Oa2FYVklWRkJ3VkZCRVdnMEtlRWhCTkU1WmVsbExSbkk0ZWs1REszRjNZMnhIZUVaeGVFdFJTbU01UkhkeVdUaGxUaXQ2DQpaRll2UW5rdmJGRklTMWxrTWxreVJtWlZabXBpRFFwb2FVVnVVaXRSYUVoVVpscHdkSEJPVnpGRFJqSjBTMVF5ZVZWQ2QwNUNVRU5sDQpSR3hNTDJ4clpIcFVOVEo2UkVWTmRXMWxTWFpXVTBGaE4yWU5Da3RaYVZsdFFsYzJkM1JJZVN0UFdsbDVabHB1WkdRMVZpOUJZbWMwDQpNQzg1WVV0NWRHOVlRelJQTldOWFltVXlZVlV2YUdWWE1HaGtRVXR0S3cwS1VETkZTV1JYWm5GQlNFd3JNM2gxT1hSNVNtMWtZVkl3DQplVUZOUkVKdGVWVllNRTRyYkVwalFVeExTbHBNZG01SlpXZDFiMmxDT0dKUVFVVXlEUXBDTjJGd1JqbElORU5uUTFabk1sWnVRMlIzDQpWelJDTm5waGJYa3lVSHBIVms5UFJHbDBTalYwVHpneE9IVjZaMjl6UlVwWFRXdHJaREpsWlVRTkNpdE1Ra0ZuYzBWaVpUZE1XazAyDQpSbkowZWk5UlJqbDZVV2NyT0haR2NrOXhNU3RzUVRKUVdqUlNWRWhSU0RBd2RtZHBabFV2VmpWbWMzUnBidzBLS3pGSFNsYzBTRTFIDQpOVkJFYlZZMlZuUndOV0Z1YVVGamJVVXZNV1JxUWpoUGQwZ3pWbUp6WVVOWlMzSkRjbmxtZW1aUlZFZEdkRXA1WlZCSERRcFFNSGdyDQpkM2hSV0RWTGNHUm9SbFphWm1GWWNrVmhia1l3WldkQk5VcGthMkpQZDNWbFVVMVFURXcxY0ZCUGJETlRlVFYwWWtWMWVuVm9aSGtODQpDbTQwTlVFcmJXOW9NazVyWVdaMFpDdHZRWG8xWTFRNE9IRlNUa3B4WXpKVE4wVk5ha3hxU0hwUlpuRkpVRkpaUW5Ka01FUjZNRE13DQplbGhQUmcwS1JYTjBibGx0VFVGbmEwaE9kMmxFWlVaTFEwaDVjbmR5VUVvNEx6ZGFNRmxuVDFOd1ZERktkV3hZYlZSQk1pOTJTbVpIDQpjR3AzTUc1elQxbENEUXAwWmpVM2RVdzRiRVoxTkVKSmNESTVOMU5YVTJSRWRFNVFXRmhOVkhOdWNsZEZhVzlYUnpSM2MyeEZSR3d5DQplRVpXVFhwT2N6aE1PSEZIWXpNTkNtVnBTbWxIVmpJNVJVaHdSRUpUU1U1aE9XVm1RekJJYlZKalZVNVFNRXBTZEdock5sTlFNU3RPDQpUeTl3VVZSd2FYQnVkRU5OZGxaWGNURjBWQTBLYlRWWVRGUklMMU0zTTFGM05FRnJRWFYzVjBkd1lURnNLM3BKVFhCSFFYUndiRmQ2DQpWbEE0ZEM5NGVqZFhhbTVGUlRVdmNsSTRNVko1V0U0MERRcHZSMG81VDNNeGVXTnFlVGRTV2tWWlZHbHZRVkJJTUdNcmFsRTJZbXd3DQpTSFJEZFdaQ1dXWlVWMXAyT1hnMFUwUjFlVUpWUTFSVE5HSjFkWElOQ21JNGRXdDBSbkp5ZFRjckwwazRaVTlWVmtneGIyTnhPREkxDQpRblk0UjA1eEszQkNiekV6TDJSUFQzaEpMM2xRZG5KNlExSjZTbE42ZWxsNUt3MEtiM1pQZGl0d1dtbFVUbWhsUldsNVIyUTROMk5YDQpLeXRWWWxwM05reG1TWE0zWkRSb1NFUnVWbWd4T0hOTFVHUnZaRlZpV1ZCc2RESlNWbTVXRFFwaWFuY3hPVXRITDNvdlFVWklXbkZTDQpUR1JsWkU4elVUaEhjbUpxYjNCMU5GTXdVMEpQYWxneFZuUm1lWEl2UVZWWlIxSllaWE5tU1dSNmRrY05DalpVVEV4dVNtZHRaWFZTDQpMMlpEVW1SQ2QyY3JVRFo0VjBkcFltdzVhbkJaTkRaSU1rZE9OMVZsUXpJeVYyUTNSakJZTjFjek5FWTJjMFJtTXcwS1RHSk1iWHBKDQpkRWRzVEdKUlIyNHhlbkkzYVdVNWNUQjRZV1pDY2pGc1p5OVhWVGw0U25sYVJFbGxSV0pRV0hCS1YxUXlLMkZ3UmxJdllWQndEUW8zDQpVRTV5YjBoM09GazBlamxXZVV4eGNVSXZiall4U0dGSWVqVkJUamRxZDBRNGJFRTVlVWR2YVZSWFEyTTFkbUYwYUVORVJrMHhWMFJGDQpjMGNOQ2tKWVFrcGtRelZpVjNsSVFqRXJibWgyYjJWWlMzWlBTamxTYW1wRldrZGtjMmxhVWpKbWNsVTRlWFJoYkdNelVHRnVVRXhPDQpUa0pyV1N0d2NRMEtkazA0YmtJMVNtdFdTbGxXZVhvdmIwWTNPVUoyYjJkT1NVcGxSRUo0Y0ZoeWVGZFVlR0kzY1RWM2MxbEpOME5SDQpjRXBsYkVrelJYSTJUMXBpRFFvNGNFRXlNMDUzZFZoVE5WaHpha0l4TDJaNlVVVlpZMXBSWTA1UVNGcG1VVmhHY1RkRlFVUm5XSFZ1DQpWblJMYlhoTk5XMVFWRTFEYjFsUmRVWU5DbWRaY0RCQk9HYzFOMEZNYVdZMlRHOHZOamxEV2pScFNqYzJhR3RqY1VaTVJURXlObFpVDQphVWgxT1V0UE1YbFhSbkp5UjI0Mk9FODNUSFF2WWcwS1lYbEJVSGRYUkhwek5XNHlNU3M1VDBnd1RtZHNWSGRVTUhWcFR6WlZNR1ZPDQpWVVJWWVZrcmRHOW9WMjl3TDI1allreExjRU5aTDBnd1ptMXlEUXB3VkN0R1ZsQktWMkZ2VUZaR2NUaG1MMnBYUTBWd2IwSlpWVlpUDQpPVmsxYTBOTmNGTnhRVXhwZVcxR1YzSnBTMFJ4V2tsWFluUlFlVTlRU20wTkNrZHVOMHA2TVhOQlRESmtVa1ZrWm5ZdmNXMHlVbmMxDQpZVmRNUTFkdU1YRTRkalpPYmtWUFdUa3libkJvSzJGdVZHcGpkamtyYlZSMVUwNXNNdzBLWW5wQk4zRkhOVTVXWVVncldUQm1hR2xpDQplRE53VTFKelpISlZZVGN3U25kVWMyOVJaV3h6VEdWWFlqVjFha0lyT0RoWFJFWlRhM04xV2xkM0RRcEpXVFJPVTFWVVdsbDFlbUZKDQpORzA0WmtSM0wxbE9WemRUUldKSlRXSkxhbWhQYjNka1RFcG5aRmgyU0ZKcGR6a3dSVlI0WnpsNFZrRlpiVEVOQ25WTmJtSlhTQ3RVDQpaWEJwVTIwNE9XNVlka2gzVkdWcVZ6QmhNWFJxVUhVMWMyNHZZMHhXVG1sUWMxVk1lakZMUlZGalExb3pRWEpMYVZSdk53MEtVM1JODQpNRnBCVG5FeWVVNTRaV2RGY1VOaFZsaDZOblJNTkRkRU0ycHRRbTlsVGtSaWRHSnlVelZTT1hsWVpVeFJVVUU1TDA1V1NIQndTblJuDQpEUXBYT0doaFVYbE9VV3hYU1ZnMU5YbEJlbFZLT0VkUk9GaENlVnByWVRGV1JqSkpSRWsyU1RkSWJUbG5SbTVJUVZCb01HTkdZVlUyDQpZWGhRT0ZRTkNuUjNLMFZFVFVNdk9HUlpRa3RYVVRkS1JEZGFWRkJNVTJoNWVsQlJTamxEVW5CVFRsaDZZbkExUTNSdFJVUlFXU3RxDQphMHg0V0VsS01GQnJTZzBLYURSc1JFNWhRbUpOVjFOTGQzSjFLMHRvVms1dVRHcE5jWE5uWjFZeU5ua3dja0l2YUV0cFFWZFJRWEJwDQpiRk5tUlhsalpWWjNiVVJ6ZEN0b0RRcHpVMlIxSzFKR2VuaENNVk5WVFRkd2IwTlNORTEzVWpORk5FVjZhMll3YldOVFZEaG1ZekU1DQpVU3R6VEZWMGJWSkVUWGt4UnpSQmNGTjVUaThOQ20xelMzSlRTbmtyVTAxVlVtWkdTSFo2WVZwTEwxVTJWMHRFTW01MVFqWkllSFJrDQpXREI2VUV4WVdUVjZORkpaYkhsclFUVTJURlZMZWsxdlFRMEtjMVkyVTBOSWNYRkpXVE55YUUwMVlsbEljakZTYmxKemVVVk5aeXMwDQpURWwyVm5GbmJtVlJOSFkxTmxoU2NsZzBkV3hTTUhSV2VuaExhVXhURFFwbmVtSlJWamxNUWtWdlEzVkdhWFJ1ZVcxc0wwOXhlREF6DQpOU3N3ZDBRMVNXWmtTMWRSWm5GQldGaHRaRW94WTNWcVFrUkdSbXBQZFU1eVQzRU5Da2x2UVhoM1IxaE5UbGxOYzBJMlkyVm1jR3BHDQpZMWt5ZW5oU05WcFdLM1UxTlhwbFNGWnJTVk5YYUZVMldYVlJNV0psVjJOMFJHbGpabTFhY2cwS1dWbDBkMVJFUml0dVZsaGliMFJsDQpRMWRUUmxOMWFrNVlUR1ZqY0ROc2VXTlNXamN3ZDJwU0szaHZaV3N6VFhCVWIzWktXSFJuUldKUmIzWm9EUXBPY1ROS1lXWlJhMk56DQpOSGR2VlROTVNqbFVVbkp3UjFRNU4wMWhRamM0YjFKQ2QyUnNhRWdyTmtkbU1GSTRkMFJVTUhGTk9XMUljMnRvU2pjTkNuTjNOVTVJDQpPRWxCUkhSVlQyRjNWMU4xUXpscE9GTlFZemRXWjFwWlpsUkxXRkJ2ZEhZeU1VbFFORmw2WVVKdFNXRnJWblF3UTBOVlJGWmllZzBLDQpWekZUTDBkaFR6bGplSHBHTlV0clZqQkpjalF6TldJdldsQmplV2xVZVVSTFVraEpkblpXTUhrdlIzTXhWVWxGZDI1cE0xRlpZbkJ0DQpUV0ZqRFFwdVNFbHZabGgxU2xsUk56ZzJPSE5VY0RGU1ZpdFNlSGw2VG5SQlpERnRVVVpXYWxFMFFWVTBWV0pNWVRkTE9URmhaWE5PDQpNaXRSVTFOSmRFc05DbFlyTUZSSGEwRjNhbk5LUTNreGJESTNkWE5MWmk5clpHUTVPR2RTYjJoVGJsVlljbk50U25KVlZtVkdSazFDDQphWGhuZFdKS1ZGZDRWaXN5V2cwS2R6TnRZWEZPUmpaYVRHOTVLMVZHVEZnM2VYSmhORlJxY2xobU1uUjNUVTF2TW5KcGEwdDRlR1JUDQpjbUZGTVdKc1kyeHdjbE56TjJSblVuWTVEUXBGTkVKU1oxRm9hQzl6UWt4dFUyRmFhM2h6VUVWa2VFVjFORXBrZVdSVFFsZ3dNbFIxDQpaVk5OT1RSR1NtNTNLemx2VFRsRk1reG5OaXRYYTBjTkNsSlFlRGMwV0dwNFlsTnRVRGRVZDFwbmFEbG5hWGx1UmsxemEzRlJhRFp0DQpRbmhTUkdaS2JYZGFSblExUWtNeVZEa3JRVkpZZFRFelFUWmhaQTBLVGpSUFFrZ3pZalV4Wm5Gb1pHVmplRlJYTm1kaFVuVXZObWREDQpUVTB6VEZOb1F6UkNOV1ZXU1UxYWNEUm5VWFU1WVZoWFozUkVTM1pYSzJaUERRbzJUVk50VGpoU00zVlZVelpIZVROUFRuQk9SbmN6DQpSSEZVUmtSUWEyVjBaRmN6YURBdmJtWlpkRUZ1SzFGRlEzaHJhV2x3THpkTWQyZGxTMnNOQ2tveE1ITXdWbkJJUjFWb1FrTXhNMWxMDQpVbG8yZDI1MlkyRkpjM1JTTlhwb2RVczJkV2xMYjBrcmRXNXlUbVp6YzI5Rk56QTFValZLVG5aS1VnMEtjMVpqWjJvMVpFODVRbVF5DQpUVmhpYW5JMFpXUjRlVmxCVVN0MFZucExNa2QzV0Zkc2R6TTBkVmRMWVRWSlZEUkpTRXhYVjFCUU5GcEpiVmt6RFFwV1pFMVpaRUpDDQpSbWRHUnk5ck1tUnhjblIzVEVoSk9EZENiWEJTVVRoeFJFRjVjRlIzYWxSeFMyUkxaalpaWlVzNGFHeFVOMFJoTmxsa2Mzb05DbGQ0DQpSa3g2V21SclFVdHliMnN6ZFRSRldHWlBPWE55ZGpaU2QydEJUVVF2TTJSWlNsUTJUbXRxTDFSMVJFZE1Ta1ZTZFhrMFMyRXJlV2N3DQpjQTBLTTBaalZVSmFPWGQxUzNKeWJFcGxObkZHVlZSSFNHcE5XSEJSYkhGbmVFTldUVkU1Tm1GNVEyVm9iMEV2Y2pBclJURkxTSFZYDQpSMjlYTkhoQkRRcE5hSGx5ZVdKbU5WUmpkSGt3T1RkeU4xSTVOMjl0ZEZFNGVVZEhlbGRtYjNGMFRGZDJjekJxVnpScVRHcHhObGhhDQpZemx3VlV4RVMzWkVWM2tOQ21GbmNrUmxTMGd5VUdkeU0yMHZXREJuY0VRdk5XNXNjbTVEYzJKT1FWTlNURTVIWmpSaFJUaEZaaXRzDQpWa3gzWlUxRGJETk9SM0p4ZHpRemNBMEtLM2cwWjJSMlZrOHZXR3B2TDJ4WllrSlJZbVZUU0dJM1ltUjNjSEZ6YjNVeE4weElja3hrDQpNWFJHU0dRNGNUVXhhMVJFVGtGRlRHSk1XalpuRFFwR09HOTZNV2RuUkZaaVJYbDFSekowWTFGcVF5dFhiRFpXZVhVNGRrcFlkVXMyDQpjbHAxUmtka1pqQktNM2hhWjJsVlRsQmFTM012VW5FelFtc05DbVV4TlZSUFNsRmlSMk50UVVwbU9FUjFhRVV3Y2tKUFZUWTNTME5wDQpiV1ZEWkRRNFRVbHBkSE5FT1RkVldtWjRkVnBrTUdGVU5rUnRkazh3ZEEwS05tRlpWMjAyUms4MFkyMUlVbWxsVkc5NFYyMHJOMUE0DQpPVFJNVDNBekwwRmlhRWhRY0hwd2RuUjBhRGxRYW5OWVNqQm9VV2hVYjFCMWJXRmhEUW81VkVNNWEySnZTWFp1UTFab2NUVkNWVUZHDQpTVkIyZWpSdmJtbElkMk5IWmpFd1UxWnRWR0U1VjFOdk9EbEZhMlozVkZWMllYUklNVGxXUkZVTkNrTTRkVGwxVkdOUWIxaDBWRk5IDQpiMk5MU205dmJTOHpZMFpaTkdsWlkxaEJaSGxsUTBSTGRuUjRTSHBrZFU5ak1ISTRZV2hRU2pFMGIzSkhTQTBLVjI5a1FrZFNMMUZYDQpNelZMYjBwS0swNUhkRVl3UVRkeVRuUmtNVUpwUlhKVmRHRkZTRlZhVUROVmEyODViSGxSVlROSlkxcFdOSFJMV1RGakRRbzFPRGRaDQpkSEZtTkRsT2RtMDBVbmt2T1RSamQxTjZNVVUzY2xkNWMwWndZbUpKU1ZkWVdqVTBjbFo0ZWxCTVMxcGFTa1kxU21OWFF5OHJNMUVODQpDazF2T1dGS1JFZGtVak51TlM5M0wwTkJkbkpXU0ZscU5FVlZOVlJOT1ZobmExVTJjRmMwVXpKR2IxZzJWRmgwTDFWcFkwRXlkbE55DQpiMmtyWmcwS2EwOHZlVXBJUzFWTmFEaFJjbk41WXpaNlIyRnNNMlJXWkVwblEzRjRlbUZzYVdOd2MxVkhaR0ZzUnpNcmRtaHZaMVpqDQpXalUwZGxBeFNIVllEUW80UlhwWVJIRjVlbEU1VVhsd05qQmhVVGR3V1U1a1VtSnFjMWM1UXpaTGIweGtWREF5VUZRM1VtTlpZU3N4DQpTV1JsYURGTlFtUmhhbVpoZEZvTkNsSkdjWE5JZFdWcWJTc3ZVMGx0VXpaWFNuVTJha05DWW0xbllVcE5TM0JGUm1weVpFMVBNa3BLDQpaVXhPZDNwTGRsUkZNVEp0TDBWVGFtMUNSZzBLUmxScFYzQlZWRFZtYmtGR01YcHhhREZzZFdndlFtSlhUREk0VGtSemVEWmtVVUpODQpUa3MzV0RrNVpGVktiR1p4Y0NzMGEyZENla1pSVldjeERRcFBRVFpUVG1FNGJGQldRa0Y0VWxWS2NHOUNaQzl5VkRoNmN6RkRObUp1DQpXR3R3VDNsMVVsaEhOMjE1T1dWNk9HMUlkMkU0Y1dObGJrSnVkemdOQ2xOS2JHTlNRMnRTVmtoeFkwTkJlazgzVVVkV1ptcDBVMjA0DQphbnBNUTJGQlIzTjNTMHRHVDBabFVreDBhSGh0WWtGTGQzUmhTVWN4UlZSclJBMEtUVlJhVGpKVFZrODJhVTVsVmtoT1owaEtXak5TDQpVakpIY0M5dE1XbFFSMmxIV0doamRFOU9RV0pVYm1KYVpuZ3lkazlCTTNoeVNXOUxiRlpZRFFwTWJXb3hZa0Z0YTFJd1pXcE1kbk5hDQpaMnRHTkU5dmFWWlRaREJHU0cxQ1MzZHBjQ3RYTjBKeVoxRlFSbTlITnl0Q1NFTXlSVXR4YVRCcFdFRU5DbUpaTWpscVlXUjBNelZKDQplWHBQTWsxeldtSXhNSEZSTTAxaE5uWjRXVnByYUc1NVFqWjFXVmRYU0dWd1VqWlZObFJFVFVOQ2JYaFVZVnBZYWcwS1dIVndVblJEDQpWSEJWZUZSMlVtRTBiM2R0Y1ZsS1kxQjNVRVV2WnpSd00wWTFjR1ZYVUVWTU1tTlVLMWsxYVU5TmQybGlOakZtWVcxa2FubG5EUXBSDQpTa1J1ZEV0YU1XMDFkSFE1VTJ0aWJVVnJSMkpPUzBaMmNHdEJSMDVtV25sVUswNW1PSGxuVDBKUWF6Z3pXamhuUVhwWFJETlRibUpIDQpPVEVOQ2tSek5uSkpSM1U0U2pWRk5FWXJjbHBIVEVJNVVqVldOMjVTYlRJMFpIUldhbTVJVUhwUWRHUkphMjU0VjA1b09WWXdPR2hQDQphVGxuWm13NVNBMEtWVGd4ZDJwUWNFTnRTRWRSVkRGb1pYcEZOek5DVlZabmNWQTFVbWMzUVdVelRWQlRVbEJVZGxBeVZVOU9SbkZTDQpVM05pVDI5TFNEVlFUSHA2RFFwSVJYaFdibGN5VERObFdqTkRXR2hoVVdSNlpXOTBaMkZKTVZOQlRpOVJaVGxZZEhCcVVXcHNjVFJtDQpVemxMTkhCdFlXSmhiRlZLT1RkSFkzSU5DbGd5YUVWSFlrMXBiV2hPWTFOdmF6bGlXa04zZHpKbGVrUllUWGhyTUd4Wk9EbGpNMDV1DQpTbE4yZUhRNU0yaHhWRmw0YW05YVdsQjZjbnBQTkEwS2FsUTRZVGQzZFVKMU16TjFibWhhUVZadFJGTlliMUF6VnpWNU0xWnNWbTk1DQpNME5ZS3psS2RHdDVTMGQyYkhGUmFrUkZVbGh1YVVKNFlXTTJEUXBrTlhOS1JYUktkblJOWjNsTmNuQmxVRlI0TVZaTWR6bHFSREY0DQpORTFpVFc5dk5XZG5WR0UxVTBwaVozSXhPRGhrYWtwVVZFdFhiMGxZWlhJTkNqZ3pjVWRYTWpsSk1FZE1UVWcxZURGT1Z6ZEJlVTR6DQpiemw1ZW1oTVZGbG9NRVZuZHpKRk5WRXpWMUpVWVRoQlprcExlVkpPY25wUFRHdE5OQTBLVVdFNVIydGlTSFkyU0ZFM0syMUxkRVJ6DQpSbFJKUVROemIxRk5Va2hGU0ZOVldXeFdlblExTjJGak1FWkdielJXTVRSM2FtbHNRelpOWjNSakRRcGxWbUpKU1hsSVFuSjBUSHBwDQpkV052VFZCd1VtcHpiR2RUU0RsWmFsQjBhMjlIYW1sWVVFaGpZVFpHTUhSbVMweFhZVmxPVDFWNWVqVnJSRTBOQ25WS1VHTm5abXMwDQpNU3MwTTBSUGQySTRNWFZyWTA0MVdIVTBiRkJIUWpJMGRWTlJlWHBZTTI5bEt6SkxVVWt6TUVOaFMyUXlPWEZvZUM4elNBMEtWV04yDQpkWGhyTkU5clZUWXdTMkpVU1VaSFIyUlJlamxNYVVkWWRIVlJURmxuZUdGcVJFRm1ORFU1U25sSmVGbFlNbmhXUkZwclJVYzBZWFppDQpEUW8xU0hSTGQwVlFUMmQxYTJ4MVYxY3dia2gyWTNFMVNEVlhlVXh4UW5WMmNIWkxibmhRTUZkcVpXaEthbGRxYTBoRmREQkRiV1ZZDQpiVFZUTVdjTkNqTnBZWFpUSzFwSlpXaGxNRXhsU3pCTVZrWllNalpRYmpBdksyUm1aMVJVV25wSVRITnNlVmxEYTI1NlZGQXZhbEF6DQpaRGQxTkdzelMxQXpUZzBLU21Zd2JEZzBZVFExUm0xVU5sSmtNbXhtVWxRM2VrVmxZekJyTnk5R1oyNDJaV3RzUmtWbU9VWlpURGRwDQpjRk5VZVRsd1ZHVlJNMmQwVm5VMkRRbzBhMWxUTTJKSlVIZHRZamx2TDI4NGNXNUpjbmM1WjBOR1VUSXdhU3RoWVhjeGFuWkhWRVkzDQpVRXBNV20xdlpWQkdSSFZyVlM5dlZVUnZjM01OQ21sa05qUmFjMUl2WjBsbmFWVnpSV2Q0T0M5U2FIRm5hMlZRUldJM1pHa3pVbEJtDQpiVWNyY0VwR1ptSjJkemxKVFZoTlVFeHRZMnRsVTNORGF3MEtlVXhKYVdSelNtSnZaRzFXTDNGSGJGSkpaVUZFTlc1TGFTdFRiazlFDQpiWGhKVlRkMlJHWnBUM2tyYjI1WllXWkxiRTAwYm1samFWUkNRa1JDRFFwaVJHWk1XbEp0Um5KdFRGQkhSbGR5VVd4cGFrY3JWVE5EDQpjMnhTV2xscVYwMW5aR3B4UVhveGVVOUphRWQ0U21WeFZVZ3lPRmxCVFZaSGExUU5DbWMxTm5OVWVYSmhOM1J6Um1KSmIyVjFOemx2DQpNMlV6ZEV4d1VqbHRkemRqZGsxbk1rWndjR2gxTVVwRVUzaGtUMU52VEVKcVZIcDRNRU5VWXcwS1dFaHVlR295YlhwdVNGSk9OME5FDQpjMWx4UW5oTWIzSktOazF6UmpsMVoyOUVkMGhLWWpCQ1pERnVablJoYm5oM2VYcFhhMDFwYkhOTFNqSjBEUXB6ZUdOdFdGUTNXVVZGDQpRbkJhUm1sRVRYQk5LelkxYlM5TGIxbDRTbGRSTkRJNVFqVndRMms1UWpCNlpVaG1NbTVKU21SSlIzUnJkQ3RxWjNRTkNrRkhiRUpGDQpORk5XV0dwRlNrZEpNRzF0T1d4SFFuWnNOM0ZOYlRGNVFuSm1OSEJEYkRocFNGZGllblZ2Y0Vvd1JYRnhRelJtVm5ZeWMzVnBkZzBLDQpRMEZ5ZFhkWWVYZFpWblpPTkRCMllXWlZSRXRLUVhWTmNrcElWMDF0VkRsbE1UY3hTSGhYYVVwMU9WRlFaVVJXU1dSbGFsVXhkVnBFDQpkbE4yRFFwbVdVdE9jWHBFYjI1TlpHb3dVV1JuVm5BMUwyWkZha1JoWkZGVVpVcEJORU51VG5WTk5FWndUMjFuUnpSUE5sQTFhR05tDQpSbXd3YTBzclZ6RU5Da2huZERsT1J6ZHhTekF3VUZKU2RIZDVXbEZtVW5Kbk9VaGhUVlZqTm10cVZtbFFaemRrVWtONGExRm9SblI2DQpRemROUW5kVFdsTjNZMXA2V0EwS1FWY3hZVGt2TW1GTVRHVkdjRGh4TWpCTWNUbE5OMjlTWlRobU5VaDNlRmhzVTI5VVZqbGthbGt3DQpZbk5OU0RaVGRUTkZkMWhQYzB0amREZGhEUW92YzNsTFVqVkdPRWg2TDFaRmJuazJZVXh0WTNkSE5EVkxPWGxXU1VoTU1tSklSRFIwDQpkREJETDJSck9YQjNPVWxGZVVVMFpGVXpTR0pJUm5rTkNtODNXVEZxVUdGQ1ZqRkpSV2t2VkdSc1FscHVUMUY1ZDBOMmFXZDNNMVZyDQpSMjVLZW1OS01sUnJWbXBFWm5kVFZtbzFPR2RwYVdSS01VUXdUZzBLVVd3eGIyZGFOemRGYWtGYVNVVTRNU3Q2TjJwbk5uRTJNRTVtDQpiVk5vUWpoSGJYbFBZbkZLVm5WQ1JHRkVTa2xNUld0RmRreE1WRlpIVkUxbURRcDBPV2hVZHpOUFYwOUxSblZQY1RReE0yZGhkRWRwDQpWMVJQVHk5V1dIWkRObFZ2Y0dnMVR6RlFhWFZZZWpaVWNrWlNRbkpxY1RJMFNrTm5VV1VOQ2tkMWFURk1lbVpFYzA0MWRIZHlWWFo1DQpTMWx6YUZrMk9XZG9jQzl4VlVFMVExTjBiREp4YmtGcFJrTkNNak01Vm5OSlkwOHdWRkl3WW5KMGVRMEtkekZYZFRsVGMxRXdNWGhzDQpUbVZFUjA0cmFsQjFSRzFZWVVWSmVscFNUMHhoTURVNWVIWXlNVUpIYVU1VlFrTkdPRFpXWlVrMGR6QlphbUZvRFFvdmFYRlpTV3hNDQpjMmRsWTFCUVJVaHpialJHVVVoM1JsbFNUMmxUY2tsTE9XaGFkRmhYWkVWQlYwZHBkMnBNYnpKd1UwbHdWbWRwVG1kNGNGZ05Dall6DQpSamRPZVVGak1IWkllRXc0VGtneWJqRTRkRk15VVVVdmJ6TkJWVmhDTjFCd1prMUNTR3d6VlZScVRrZFBWMjF6VDFKb2VUWnBWSGREDQpVdzBLZUdsdFNFUXlZalpFWXpKemFtWnNabFJPVFdSdVVIVnZhMjVWZGpsVFdESkdiRVV5TVdnMVVFdHlPWG92T0U1amVrOUhaVmhYDQpaek01VXpKekRRcFhLMGRaU2pKc01qZEhTRlJqUjJ4VWVsZEtPVXB5Y0VGRVVXbEVXVzFEV0doSlIybEhNV1JXWWpsQ1pITkRUV3BTDQpNalZzVlRZck9USndXRThOQ2paWGREUXJMM1ZNY1hscllUQTFiM1I2YlZGTWVGVkNSamxrZFVacE0wcEZVbVZVZURGSGJtODFiV0VyDQpTR3hITDJSSmVWaFdSRVp3YjJKVVFnMEtUMXAySzFoM1VXVlFXakJ3TmpSaFNqbFFXRFJEYzFoaU16TnVhWHBpTDBGSFRFVm1WMmcyDQpObE40TTNvNGNYbEZhMWRIT0dwNGVITm5Xa3BORFFwQmIySTNOM05SV0ZOdWRXSnlNRVZpWnpkd2MwNVNXa1JEVldOc2NGbHhTVmRFDQpkR1J2VVdSVWQyUkhjblZSVERKWmNtUTJSVVZwYzBzeVJIZ05DbVJMVGpoTVVpOHhaelJJUTNSWlIwVlRURE5FZERCcUwwUkhSREZrDQpUMGhIWlhobFYweFJSMm8xT0dsdmVrRjZXR1J3WlVGeGFEZG9kazVpVncwS1lVRXhXakpJVVM5a0sxWkhhRWh0WkdOUmVHcG1UR1p6DQpUSEZRZFd0c1JVdDZSVWN4WVZaV1VGZEtNVGQzVWtWbFkyUXhXa1pFYmpGUVVGSTNEUXA0YTJ0eFpEZDNZMll3WVVoU2JtSnVTazFSDQpWa1J0UjBrekwwaFVaMUJQZGtwUVNrNUVNa3Q0WjNCa1lsRkNUemhsTDJGTmF6UnVWbFptY2tFTkNuQmFlV2RJUVdWdlZ6UjRVblUzDQpUVEpOVVRsT1lVWkhabXhGZWxWTE5HTjZRbVZuWWpsR2RYUnlUQ3MxVVZRNGMzTk1ZalFyZEc5R2RGQmxiUTBLTUVnNFNVWlBTbVI1DQpkVEpqYWtaQk1qbDJXWFZ5TVZoVlZtUlNVMFJ3U2pNd2RHYzVaME1yTjIxRVYya3hNWFJaZGtkR2FUUm5lbFZxTjJKa0RRcHZTVkphDQpMMlo0Vlc1alNHSnZWV2MxZDNWa09YZzVOV3RXY0dSVWNVSmtjbFJzYldrMFdESlhla1pHY1ZVM1EzSlNhbmRYV2tSeE5rRkpSWFFODQpDbWt4U0ZKcGR6QjJPRUp5U2sxaWRsbFVjM2RaZFdONVZIUjBSR0ZIWkdadmIwSjJkMDlNUW01WmRtWnVSeXR3ZWsxR1JsUlBiMjgxDQpOa3RYZUEwS1drVmlXSEZ4V0d0REwybHBRamR4ZEZNellTOWhOM0ppWkU1NU9XdEVXbGxRUkRKYU5VSlpjbVZYVHk5dGRsaExOR1pQDQpWa1JRY214WVZuSnREUXBSWjBOdGFrdERhRGc0VVZFdllYY3dZVXRQYmtScVkweDZNV3BhYmtwdGRtbEdXRlJaVGt0SGMwZGxUbTlVDQpObWhoUzIxSlYydDJTMGhGZDJFTkNuSkdabTVLTkV4cWFESnJRVFZKVEZNeU9UTTJSM1YxWWl0d2QxRTRjbFYyY21GU04wSkpRbFk1DQplVGhuTWl0U01qbHhVMVJ0YVVSRVFVOVRXUTBLUjNsUWNHTnVTak4yTWtkeGQzWjVla0pSYzJJNE5HaHFWREkxV1ZGS1ZqSk9VM1Y2DQpjRVpXV0hRdlMzRXpVR3ByY2tSellrZzROMVZwVFVKdkRRcFROa0Z1Um1WelEzRnFVeThyUzJoTGJVZE5kbFJNWjB0M2NtdDRhMWhWDQpXRFJ5UldFM0x6bFpjbEJyVDNaTFRVMXVhRE0yT0RCeWVtSkpUSFFOQ21SQ1JXSkNXV1JZVDFKbVQzbFhMemQ0TUhOT1dFTkpaMm80DQpXRFYzU0RSSE0yODRjbmxsTkVSTVZreFBZVkJMWjNCNmIxWkZaRmwyTVd0ck1nMEtjV1ZyT1hWSk56ZzJlazAxZGxZdldVRTNSMGswDQpZakYxU0dKSlJtWkllbUpQTmpsek5HMXFjbE5TSzA1blZuSTRiRGxVVDFOUmR6ME5DajFSVlVSTkRRb3RMUzB0TFVWT1JDQlFSMUFnDQpUVVZUVTBGSFJTMHRMUzB0RFFvPQ0KLS0tLS0tc2luaWthZWwtPz1fMS0xNTc0MjkwMTg5NTk3MC43NjMyMzMxODk2ODY5MTcxLS0NCg==" + "labelIds": ["SENT"] } } diff --git a/test/source/mock/google/exported-messages/message-export-16f431a0b9056562.json b/test/source/mock/google/exported-messages/message-export-16f431a0b9056562.json new file mode 100644 index 00000000000..878d03cb134 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-16f431a0b9056562.json @@ -0,0 +1,138 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "16f431a0b9056562", + "threadId": "16f431a0b9056562", + "labelIds": [ + "Label_17", + "IMPORTANT", + "STARRED", + "CATEGORY_PERSONAL", + "Label_15" + ], + "snippet": "", + "payload": { + "partId": "", + "mimeType": "multipart/encrypted", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "APjAAAVMuPOPVQcpHvoy2szKblT6tIIFsIYUPLUU+RfBHmZoOeGvZ9fm Ta0F87t7nephJLVeq/PsS0Tn93MIcMo=" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "Subject", + "value": "Encrypted Plain Text ISO-2022-JP (Enigmail)" + }, + { + "name": "Openpgp", + "value": "preference=signencrypt" + }, + { + "name": "Autocrypt", + "value": "addr=michael.flowcrypt2@gmail.com; keydata= mQINBFz7l+kBEAC7DOpjvJ3wILWhQFEWfDWnjXZLEfieiLQ6NZX8ej3IGUGapIf71J99cQAF akDkX1NF2BVNRxTqjzQ4wx6st4zxAcwTFKXmVjIDU6XMLVFAEl1eP5VybY0dvv7uYQN8Vchf QpbLzOfCz6Oc2X+JNnIIaKKEcae46hgfV+eU9ktDVhQgb1OXH/ny/8GDdwQUjwysOuAR9364 9lnxiibZJNmd7qfxMmjN1Lwz5yGaoPHHn+8it+oyMx+z36Zt+v2He9sRHtPGIEY2rdDszdER Wv1ftjHYg1O+q/irAP3xzZ578fZKlaTz205zOVQhlkWIyXA1Wuj7yjjPrOe4QF6hcJ4jGoN6 YvgVWxxvqwdNAKBxTQPLyqbrAa1nH/svnuoX4mczngW5npBm4+PSBbLo3ADBu1boGhGl1QaE vIG7L+Gvb9Iw3ZyDKSertB0ZQZ6IE782k/D0sSbT8mniY5CrGO0oNaGvqrFuaOErNhGQ6fH0 GOU44WVvYiVXdh3CyFQ90P0hpmlcNpShCNEaA94+ne7BXmMJnvAl9cP98giAmQlXx4cGy+JB cyCs5LdtvFml5/D99pd8oinCQWWAvjZI6diQDNrkw2kQVHqaCBerV21eB/eee3aIMzvCurcq TDDJa1CEoHX3INV4aivq4/6Ys6Z4i4tilD0wicKzezu9ENFcmQARAQABtC9NaWNoYWVsIFZv bHluZXRzIDxtaWNoYWVsLmZsb3djcnlwdDJAZ21haWwuY29tPokCNQQQAQgAHwUCXPuX6QYL CQcIAwIEFQgKAgMWAgECGQECGwMCHgEACgkQAJIVTI1IIzVqUA//UNgj6py7juui0EwPOwNF IC9p40qaDvjqfNVdfmcr/39odm8yzdx/0eZTRIGZDWC3BBM5gSFF9ZNGcVFTMe0N3OZZPxGm Y9XN79jobeVvE0WoLEZEHI9IY86HLAC8yc/SeiQsbKp6ZiJyDuY4gUQ07yq4Bc/HfgTyITsi aoFvWXEHcLuw1ZOimCpQg1+XqGwWhAnNhXGFe6tvw41uehafPEN+8Lj/NqMrFQ5qVOslXUUv vkpfNvAm7LBVIY79YAe5su1XMuKcrxW/7nZBKa3mbFYcnjtbW+LJqcEfAl4NNDND1ho7Guls P2JFxlxy+YqXJ6oG88Hxb5mdlVyWSkuGG+BY75D1fgenv4ntZoumCdCaDIlKFOwfCF7EToZX tedSyzs0+DRfiVg9Yp8w3IIxFn+KhN3x12NXvkNm+ZOC+I7sac/bvX7KJ3ThUf/C1QysbpmS wfmlSqk9SjthbdlrWZ20OG5yvIiCS1Bixjo2lTJLA6QSqQmcMwjd5rQrut5GkTHqxnQQb42u eO+n/GV4c6x0QT1hfKV7thE3U7XPvzUK5E8Ti9CLkDd6KE4hAct2jhlE7zYHrSbkJnWIUInr QefPQ0EG2qJzdZXniBXj2Orwk2UVsertkLD3y6Iwv7Xk9pp3zXWOPKxFK3LbnfLwmIQCd3VQ 14uh/hR3aRZfN/25Ag0EXPuX6QEQAK7/8UKmcuTNHz+mPfoOdMkxgdzikx9zgwASubc2Nhq0 +b+P4yiWOJgbmULLXnpVEH3I+XyqgcUi42wZ3KWx04Wbg1dlsSiMN/9ojdXfhn+K2V5QnrUR lgZrz2xLCcMNgbVpdsLv8tnwb1rIQapq/b12RJKU9ZBwX/5W7za9UAjwibWgrVsFCUR5omlO e7Zg1z+37DmIIUGwnDN7nHH+LOyZxu2STdKx7EZQ7glqi/WnE85doRidARrM9lPibGJlxLQ0 XnTrgPkKd/A+D6aidTS+NUSK+HSLOJzOuWnz9MHExYuQG/f2WCNVabAYNnIl9fJEcCduz/SR LbzxH8iL25H3ptonWajhkv/vFzfzzAFhXMJNehFR6QuZFlBQA078SuPb57ZYgXBA8KP9uN2x 2/Td+O7vTuYAsnyHwhZyCFtLtMP5jyt+ObR8wWW1OrVUVxOxvW4zcMBdCft07C03aIoOsvwA Fie/eJhte2czdtGPN8IlUZM5ZtKop4YephIxWd4yXqPbtQNuCQlzYRaLO7A6v1lLkKSxIESb XbMd5ez86JohqFbSLnxE3O8+WhLcYEa8v6tPsI1HfxkUGYexWJ9QBnFKtW5pjMMoJv17s8Wt sekjXmGhsje452Ma7IHfnEcrm4p/GO9AFvP06+fkZvjPb2rtxkwmG2oMUptVoO43ABEBAAGJ Ah8EGAEIAAkFAlz7l+kCGwwACgkQAJIVTI1IIzVOgQ//QT5Spj15y10bhSCJXc5amoRUG/yj ljrPLkR++9YiwsUvcZgKesMKgKp/cqOPmptD5C66c9oG1FyvHclYujki/SKhpnruRKSnvDW/ lpZnYo1QnNx1Khxu4XTcjtycAKfijBVuuR/maToR9DP9n4/5seH5TeLIGJg+YUczL4HI+kJm 8iHanmPxZQR69Cr1xDB9FwliLl9BaTFbs0lWOguEkqwl84EACuGQTLOGI4u1EN/9RgAx8JX6 JqA5l1rplC4N8HPgJ6zBp7ydzdSofoxGctSATJVmoweeWwL585GdsE0Fs+cWVSb8/tqFXGGR /oB95rb5d169vF7vbcb+h6ZidsPZqqnz85O2EgI5LkusyCG+GbKIiawkB56QA3NtT7ZotC2L 6FVzb00YezkLNu/ZtGq6vVk7qzBw4z+bu6xUWEJYTbnVa1Kaop3cu4mVl8pfEXQAd7WchgdM ULln2cdmoxNi63r7dUjEIv6QIQysCsf7EjxFzkvlw4V4fYrodWkisuamd1BqkWLlHneKaqx3 nzV35omhvvVNQyA9gqMAkxadJhD4PxS7KvPGNejQsmhME4OoI8yeg/iOGR/OTpMhk/rrQWtF 2wrCBExh2EKOkRCx0xVvyOjjStFEKc7SkuY5Nr5Fe365elDkXSr7LmEcjdR1fhFV7cG4TLMe x6aRXsA=" + }, + { + "name": "Date", + "value": "Thu, 26 Dec 2019 18:46:14 +0200" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Content-Type", + "value": "multipart/encrypted; protocol=\"application/pgp-encrypted\"; boundary=\"jn0WXJHqHVQT9hrvug28B8ufD3cTpWZ0t\"" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "application/pgp-encrypted", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "application/pgp-encrypted" + }, + { + "name": "Content-Description", + "value": "PGP/MIME version identification" + } + ], + "body": { + "attachmentId": "ANGjdJ-9nYcG6Lig4If4SpiBbo-riJdNnaw3QUxtqkQn-0gd9HkbKfg81mTNAPr3kwOPFraccuH_8RXzJGKzqAXIC_t_O4hvt9Ou5s08EzxF_45Iq0laqjJr_LCn-6TH-_lJ3fbqpSb9a6mp5IbcwKfsWFa8h7T7RNQIJcUv-N-7zaHWkrE_Xm2oeu6LiJuZVNxdqr-my8Uwb4HjNiuZmlqREd0umhZ2_UyZVec-vMsmRohZQqFVnUODxsZW2OJgUWQ4IoDKOdv2dqLV-Osn_GiVN34SDDiKtam8WTHxQnjGB9VguML5T6doZW7i4IwHfIZTvKUIjtDlpRjCwghS0O1mCcmwQzcSOSdIUjb4SIo7EGjTUx6EmYGbyp9TmGo", + "size": 12 + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "encrypted.asc", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream; name=\"encrypted.asc\"" + }, + { + "name": "Content-Description", + "value": "OpenPGP encrypted message" + }, + { + "name": "Content-Disposition", + "value": "inline; filename=\"encrypted.asc\"" + } + ], + "body": { + "attachmentId": "ANGjdJ9lJupG_5HtgB0e7ov4Id63J0OieJIaru78PsE26ACBS72qINR266EXKBpDAh1IlZh6lyvy82c6CH_zNNCMR4IHo8FShQzj8h-YpxDXI02eSoUoA9AlG6-bga4KCRR1YsGCZdh2ODiyFzazkE_qUb6QI1K4EGgANeK5dSqxh9imW3SiDZpOmkVuW0F_ovLx27kCIbabOxF5z4F3lVuljeHNVOkUGeNAzRxqpbMFNqElmTWwi2zP_MeL_uYF-8he1h6N4tNyILNU70p_PYxpeygCPU0qoywhDqRL489l80zEhB_vIVvvDj9zSRwAGer-Jty-yUBkdrIwO3efS6zT8qUNBO59k0agDGCNFjTX6WU4mK9w5BGTjJfuEAI", + "size": 2059 + } + } + ] + }, + "sizeEstimate": 10880, + "historyId": "1405889", + "internalDate": "1577378774000" + }, + "attachments": { + "ANGjdJ-9nYcG6Lig4If4SpiBbo-riJdNnaw3QUxtqkQn-0gd9HkbKfg81mTNAPr3kwOPFraccuH_8RXzJGKzqAXIC_t_O4hvt9Ou5s08EzxF_45Iq0laqjJr_LCn-6TH-_lJ3fbqpSb9a6mp5IbcwKfsWFa8h7T7RNQIJcUv-N-7zaHWkrE_Xm2oeu6LiJuZVNxdqr-my8Uwb4HjNiuZmlqREd0umhZ2_UyZVec-vMsmRohZQqFVnUODxsZW2OJgUWQ4IoDKOdv2dqLV-Osn_GiVN34SDDiKtam8WTHxQnjGB9VguML5T6doZW7i4IwHfIZTvKUIjtDlpRjCwghS0O1mCcmwQzcSOSdIUjb4SIo7EGjTUx6EmYGbyp9TmGo": { + "data": "VmVyc2lvbjogMQ0K", + "size": 12 + }, + "ANGjdJ9lJupG_5HtgB0e7ov4Id63J0OieJIaru78PsE26ACBS72qINR266EXKBpDAh1IlZh6lyvy82c6CH_zNNCMR4IHo8FShQzj8h-YpxDXI02eSoUoA9AlG6-bga4KCRR1YsGCZdh2ODiyFzazkE_qUb6QI1K4EGgANeK5dSqxh9imW3SiDZpOmkVuW0F_ovLx27kCIbabOxF5z4F3lVuljeHNVOkUGeNAzRxqpbMFNqElmTWwi2zP_MeL_uYF-8he1h6N4tNyILNU70p_PYxpeygCPU0qoywhDqRL489l80zEhB_vIVvvDj9zSRwAGer-Jty-yUBkdrIwO3efS6zT8qUNBO59k0agDGCNFjTX6WU4mK9w5BGTjJfuEAI": { + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCmhRSU1BMHRhTC96bUxaVUJBUS8vZW1iRkdWUFJ1VmZpVXVqaExlc1FhNmE0c2JwL1BPUWNBc3krK082dEQvVkENCndyUXRQaEplbmlZVkZlT3MrMzdNV3kxUGtPVW42QUF2Z2FzSHRsTUNWbnRoeGF2RzFvbkltQ0pXeUMwTmRnWW4NCmhySU45YVBtT1k3VUdoVnpwVS9HVHhFMVdISkhHTU1HU2htS2J0K0pUaHRBdm11ZnVESzFEU2hvM2tjakdFczkNCndwWTBEVTArOUk3eEVtb2JnUXFLNGp5ekxCTE54NGFIbDJxdXJLU21qZ2htazFaTVc0b2x1Y2tyRG1tUTNBV1QNClovcTdibmJQMUdETkpWOGN4UjdlZDRrNkhDemtyWCtCeEwzMDhFOHNvTHRnODdvY2MxOFFvSkFJUkFIVTBreDUNCkpsUzkrZmgvak53S2FuWkpqQ1d2NmhxWkt6OWlVb2NSWkQ5aVBxaDlkaGpzS2FscWtSYXh1UE0yZUprWlkrOTENCmpHOHRzSFlUTGVZMzNBNGFVcGRBNkZwTlI4VXl6OEFndit4OC9hRnA4R3hTTkl1VXVtZjZiU0lrMk91ZHQvYTYNCnJXdlpPK00rVUs1M2E0azRpYnhya3Y0enNFOENiaWpqQ1A4QnZVckEzNzAyM0dFV2tPSEl5TW9GRnkwbzA2VzENCjU2d1RQMmJMbUtidWplRVMrZGt6anJyMXI5WDZvREJ3cG9QQUJLU0FqSUtGUUtjeFd2aE1nejRXTzN3NjFnM0YNCkU4VTBSbHg0bEI0Q2UxSTBxenU4UzRoa2FaN3NZY0tKLzIxMXB6c2FmMEJmeFpRZHJmeXU1a3NlMjc1WWdUVUENCmJPYm5vVzJzQVdnOGZYOUp3dUw5SlZBcm5KKzZBT1Fqdk5HOWZyL3VNNHRoVi96d3FCVVdmUTBzYXNEamp4U0YNCkFnd0RxbjBNRzkrVUh5d0JELzliTXJITmsvcWlyeHBmSVJhOXZaY1pzc1h2N0E2MVhVWnkySVZ1bTkrcDljNFcNCnN3ZDIza1FPZkMvODJGeDc1Q3dNUSt6emRQNys1dHFlTmZtMy80dmZPYkxDbXN6ZjErK2ozblZ4RUVYOHNXcEMNCm1nSG9iRDN1WlB3Z1NodmdjeTZaSGtmeitCcnhxcVRKSVo2eEQwM1Znem1OZzJjdUFIRDFZVlVLYlRIR1ljS00NCkNZMGIrMVZHNmx2NGY3OHhpQjB2OGF3L2FQVHZ0eDByWTJnMFlaSGFFMEpYVDU5Y01OVE1PUk5pRThoOGd1TEINCmxmNmhjd2N0Uk4rc0p3NW9XL3NhWHBnRkpTelZiUXJ3cDBhMWI2RnR6cXYrcXlKTDIreWF5ODNSYVBYK1I3TFINCkp5OWpQcndCYnp3Q1ZiSkJCU2ZlUTB6WGtlTkFPc284M3JFMTNVanhQc2wra1UwYWp4eTU1Sy9QL2NMTzZLS3MNCkt0Rk43VUdvMmpHZWxwcURvR1U1RndPb0dlRWFZVytJbnJacnl5Vi9BMmJqdzZabWZiaDBHTXpsczI1ZksvOU8NCk9KcC9EMHlxRW1ua1U2ME82ZUR3d3d4WTdWTnFtdHVPVFo0ejhQSWFWOUxXdWZ0Vk9lT0c5OSs5ZzYyODBDS0YNCllZSEF4Z2I1NTl2NzBWNTBiaytaOTFyZEExU254U3E5d09rVXUySzFCbWtUZHFFTzVqeFdmMDRNR3J2Uk9aVUENCmRJS1ErUFlpYm5SbytTT2JCVW40T3RsZmhlbDF0Sjl3V1dqSkxwR0oxWm0zRmFvQ1ZIL01ubnZoRjQ4UTVKTlINClNEbnFUZzR3V2Q1MVRva2NuejJQb1ByeFJOM2phY0k0ZDBHWmlBdHNtQjI4bWNLamRCNVVZb1hFeTJNYXpOTEENCnlBSHpDSFJ0T0o3ZU9jU3R3bHR3bmJoNjcvUkNLOU9DZWdhaVNPTUFjc0VjaVZYVXBUK2hWbDhvTWw2SXZKRGsNCkZxMUN3T0w4dDNPajNXMmlnUGttMkVlakhsMWRrejJKWFBIamZIcXQyNHRUdFdSYTN4dW90b1N2TUF5K3RmS1QNCkN3ZzY3blFhbi8xM2hsM2VGMFhYTENEKythb3RHU2FoVWVQc2daVTc5b2VkWTJ2bWNvZlVmNzQzc1ovTjZhTVANCmdFTHp3eUxtN0x6Y0ZMamVva2hOVURZcEJnckg1K0ZjRlpxcGlUUWhJTE9OU3Zlbm5jUDRrM0ZEakM4N0RHNUoNCnlJY2tCTjFLZVUyMTl2YVlIRWttU21VM2VnZkVZUk13Mkh6bkZBYWlNRUFuRG9HczBaVHFOT3g3NWt0WkxwZlMNCjc3OUFQU1REbVMvaHNYWG83RDgvbXlZV081Uk14RnpHTDdTSWNYa29zcWErVFMzRko1MTk4ZXBIMHhMTnJEaE0NCjFsTU8yWlU1cWIyVE5BK1d2U3ZpaXdXc1oreWo2a0QxcnpydkVnKytxMWI2N3Mzb29nUDA4d3dIY2ZYK1VpTkQNCnZkR2VWZDJZRlBYMGtzemh0ZkpERVlBa0o4RVJlNVJLUXFlTlhkazhYTVlxMmlycDNBVkJUQkRrZ1RnTURQU1UNCkNJM2c4OVMzZWxkVA0KPVA0TzgNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg", + "size": 2059 + } + }, + "raw": { + "id": "16f431a0b9056562", + "threadId": "16f431a0b9056562", + "labelIds": [ + "Label_17", + "IMPORTANT", + "STARRED", + "CATEGORY_PERSONAL", + "Label_15" + ], + "snippet": "", + "sizeEstimate": 10880, + "raw": "RGVsaXZlcmVkLVRvOiBmbG93Y3J5cHQuY29tcGF0aWJpbGl0eUBnbWFpbC5jb20NClJlY2VpdmVkOiBieSAyMDAyOmFjODoxOTUzOjA6MDowOjA6MCB3aXRoIFNNVFAgaWQgZzE5Y3NwMTA2NzIxMDRxdGs7DQogICAgICAgIFRodSwgMjYgRGVjIDIwMTkgMDg6NDY6MTggLTA4MDAgKFBTVCkNClgtUmVjZWl2ZWQ6IGJ5IDIwMDI6YTJlOjg2YzQ6OiB3aXRoIFNNVFAgaWQgbjRtcjI2MTk4MDc4bGpqLjk3LjE1NzczNzg3NzgxMDk7DQogICAgICAgIFRodSwgMjYgRGVjIDIwMTkgMDg6NDY6MTggLTA4MDAgKFBTVCkNCkFSQy1TZWFsOiBpPTE7IGE9cnNhLXNoYTI1NjsgdD0xNTc3Mzc4Nzc4OyBjdj1ub25lOw0KICAgICAgICBkPWdvb2dsZS5jb207IHM9YXJjLTIwMTYwODE2Ow0KICAgICAgICBiPXFrelRjS08yS2xyeHZQd2UzY215Q1Z3RWlHbXk2VGp4RU1yazlkSGVHOEFrUTVBWXh4WER6NVlpbjlZanE4cGp2Sg0KICAgICAgICAgU2pTWEZObVJEM2FkYWlqQXd2QUI3MWJGNThLWEtLaVJpak82azFoSlZMSHRGNU1nMVEwYklaVGMwNWc2NUk1TGhEWmcNCiAgICAgICAgIGltQ3NEbStEcllnOVBycHN5eXYyNTN0RHIzRXNmdEhIa3BJbWJxVjBtTHgrTmFxbEVyZUtPUlEraW9tdWRWd09tZ2FVDQogICAgICAgICBCc0ltM3YrU1ViQ3B4M2t5VytIMEpxUlBUTXhMTjl5a2FDUldJc3E0dVdtc2dXazRpQlQxRjI5VERlT3JxNTZScWg3cQ0KICAgICAgICAgN2RNWW5kNkdvOGFtUWZCUU5aUHZFWnRJb0hJT1lKWmwxMCt0RGdod2YxQ1I0dGx6dFR3QW12UEFPZE9vWWtVU1BnWDINCiAgICAgICAgIFlpbkE9PQ0KQVJDLU1lc3NhZ2UtU2lnbmF0dXJlOiBpPTE7IGE9cnNhLXNoYTI1NjsgYz1yZWxheGVkL3JlbGF4ZWQ7IGQ9Z29vZ2xlLmNvbTsgcz1hcmMtMjAxNjA4MTY7DQogICAgICAgIGg9bWltZS12ZXJzaW9uOnVzZXItYWdlbnQ6ZGF0ZTptZXNzYWdlLWlkOmF1dG9jcnlwdDpvcGVucGdwOnN1YmplY3QNCiAgICAgICAgIDpmcm9tOnRvOmRraW0tc2lnbmF0dXJlOw0KICAgICAgICBiaD1XWG0vQlRFZGF6bDNydTVpcUdqd1VFTW1wMEFnNThZdGRyTGFubHpOdzVnPTsNCiAgICAgICAgYj15Q2k2VmdBNHIvd0wyUHQ1Y0ZCTjdnR1liWTZ0cys2N1lUOXlKYUFyeDBLV1JhVjNxVlNHQlpFUXd0STF6WWFlcGgNCiAgICAgICAgIEk5eEJNSGZ1S29QUVA2cU5xUUFrcmk5ZEYyb0piRVBrdzVzNEpMWXEvcWR2SHoxTjRDWVhGN24wQ1Y3SjJYZnQ4czJBDQogICAgICAgICBGVGl2alFqMDA2KzRFaFVTSTFRSXZYbCs0OXc4OWt0eFpJb0xBbXFHN09kc0lFR3RwdElubmlwMkFiOVJzOGJiVmdqbw0KICAgICAgICAgeTVIRDNxM25aMjRKYkRyOHYrTk9LeHZRSXVBQzNtVkVhWVhmSW1zQlhHZlJQSmhMdEFmQ25STENXNk5DY25LNHlDQSsNCiAgICAgICAgIGRxSWVLcFY0dWNxVXU0bmkra2h3MXU2ejQwWnFKVVlvOEFHSGxZMmk2NWZHOUJYdkFtdmtXUjNtcytQN0tpRnYzUWFzDQogICAgICAgICBDbGF3PT0NCkFSQy1BdXRoZW50aWNhdGlvbi1SZXN1bHRzOiBpPTE7IG14Lmdvb2dsZS5jb207DQogICAgICAgZGtpbT1wYXNzIGhlYWRlci5pPUBnbWFpbC5jb20gaGVhZGVyLnM9MjAxNjEwMjUgaGVhZGVyLmI9U1duWkY1QVA7DQogICAgICAgc3BmPXBhc3MgKGdvb2dsZS5jb206IGRvbWFpbiBvZiBtaWNoYWVsLmZsb3djcnlwdDJAZ21haWwuY29tIGRlc2lnbmF0ZXMgMjA5Ljg1LjIyMC40MSBhcyBwZXJtaXR0ZWQgc2VuZGVyKSBzbXRwLm1haWxmcm9tPW1pY2hhZWwuZmxvd2NyeXB0MkBnbWFpbC5jb207DQogICAgICAgZG1hcmM9cGFzcyAocD1OT05FIHNwPVFVQVJBTlRJTkUgZGlzPU5PTkUpIGhlYWRlci5mcm9tPWdtYWlsLmNvbQ0KUmV0dXJuLVBhdGg6IDxtaWNoYWVsLmZsb3djcnlwdDJAZ21haWwuY29tPg0KUmVjZWl2ZWQ6IGZyb20gbWFpbC1zb3ItZjQxLmdvb2dsZS5jb20gKG1haWwtc29yLWY0MS5nb29nbGUuY29tLiBbMjA5Ljg1LjIyMC40MV0pDQogICAgICAgIGJ5IG14Lmdvb2dsZS5jb20gd2l0aCBTTVRQUyBpZCBjNHNvcjczNzMyMTlsZmYuNDkuMjAxOS4xMi4yNi4wOC40Ni4xNw0KICAgICAgICBmb3IgPGZsb3djcnlwdC5jb21wYXRpYmlsaXR5QGdtYWlsLmNvbT4NCiAgICAgICAgKEdvb2dsZSBUcmFuc3BvcnQgU2VjdXJpdHkpOw0KICAgICAgICBUaHUsIDI2IERlYyAyMDE5IDA4OjQ2OjE4IC0wODAwIChQU1QpDQpSZWNlaXZlZC1TUEY6IHBhc3MgKGdvb2dsZS5jb206IGRvbWFpbiBvZiBtaWNoYWVsLmZsb3djcnlwdDJAZ21haWwuY29tIGRlc2lnbmF0ZXMgMjA5Ljg1LjIyMC40MSBhcyBwZXJtaXR0ZWQgc2VuZGVyKSBjbGllbnQtaXA9MjA5Ljg1LjIyMC40MTsNCkF1dGhlbnRpY2F0aW9uLVJlc3VsdHM6IG14Lmdvb2dsZS5jb207DQogICAgICAgZGtpbT1wYXNzIGhlYWRlci5pPUBnbWFpbC5jb20gaGVhZGVyLnM9MjAxNjEwMjUgaGVhZGVyLmI9U1duWkY1QVA7DQogICAgICAgc3BmPXBhc3MgKGdvb2dsZS5jb206IGRvbWFpbiBvZiBtaWNoYWVsLmZsb3djcnlwdDJAZ21haWwuY29tIGRlc2lnbmF0ZXMgMjA5Ljg1LjIyMC40MSBhcyBwZXJtaXR0ZWQgc2VuZGVyKSBzbXRwLm1haWxmcm9tPW1pY2hhZWwuZmxvd2NyeXB0MkBnbWFpbC5jb207DQogICAgICAgZG1hcmM9cGFzcyAocD1OT05FIHNwPVFVQVJBTlRJTkUgZGlzPU5PTkUpIGhlYWRlci5mcm9tPWdtYWlsLmNvbQ0KREtJTS1TaWduYXR1cmU6IHY9MTsgYT1yc2Etc2hhMjU2OyBjPXJlbGF4ZWQvcmVsYXhlZDsNCiAgICAgICAgZD1nbWFpbC5jb207IHM9MjAxNjEwMjU7DQogICAgICAgIGg9dG86ZnJvbTpzdWJqZWN0Om9wZW5wZ3A6YXV0b2NyeXB0Om1lc3NhZ2UtaWQ6ZGF0ZTp1c2VyLWFnZW50DQogICAgICAgICA6bWltZS12ZXJzaW9uOw0KICAgICAgICBiaD1XWG0vQlRFZGF6bDNydTVpcUdqd1VFTW1wMEFnNThZdGRyTGFubHpOdzVnPTsNCiAgICAgICAgYj1TV25aRjVBUDdFRWN6M1YvckNmVWZSSVR4d3JmRzVuaktwWDBuK24wblhaQWRkc0NxN3phWmhFMUhVN1FFaXFtVXANCiAgICAgICAgIDhDZmQwNld6cm9vVnBQUGUyWW9tdUtQY0xQSWZLREdBTlFIS1FKL0N1aU5QN2NBcFNaQ05IbW5TTTVKQXpaRmVkQ21JDQogICAgICAgICBZbkRtcGlhTHpMaHZpeVc0bkFoNTY3bVo0WW1PMzY0ZmNoblgxL2NDakdRMEowSjB4dkVhQndEM1FyTTR4Rjg3Z0pHZQ0KICAgICAgICAgSGhTdnVxVlhndStYOWRZcERSM0FUemlIZUlVNkxic1JDVzN2aUNjbC9IR2tOVjRyUHIydW1QUFpxNEtVZG9PWTVhVlQNCiAgICAgICAgICswNCsvNEFpVXlTa1JON1MyMDNvOTZuTVkyd2ZOS1QzaGUvUlhQVDRJWG5ZR0RMRk5iYTE0ZFFhdDhMa3hnN0l2UjVZDQogICAgICAgICB0RXN3PT0NClgtR29vZ2xlLURLSU0tU2lnbmF0dXJlOiB2PTE7IGE9cnNhLXNoYTI1NjsgYz1yZWxheGVkL3JlbGF4ZWQ7DQogICAgICAgIGQ9MWUxMDAubmV0OyBzPTIwMTYxMDI1Ow0KICAgICAgICBoPXgtZ20tbWVzc2FnZS1zdGF0ZTp0bzpmcm9tOnN1YmplY3Q6b3BlbnBncDphdXRvY3J5cHQ6bWVzc2FnZS1pZA0KICAgICAgICAgOmRhdGU6dXNlci1hZ2VudDptaW1lLXZlcnNpb247DQogICAgICAgIGJoPVdYbS9CVEVkYXpsM3J1NWlxR2p3VUVNbXAwQWc1OFl0ZHJMYW5sek53NWc9Ow0KICAgICAgICBiPU5VNlZqRWh2M1J5RkRtVnVSN1dGeWtwcmpLWWcvRkZQYVZ0M3pJUDlobHM1U3h6RzdkRkVKTEVxTTZUQnNNQXZqcQ0KICAgICAgICAgM1hGVU5PNFVPdWtRQTFQYzM5SnJXNVAxaVowVGgveVNtbmpCMFJxMWRjdzU2ajlxcDFiMDhmQmszbW5TT0Y0ZzcxTVQNCiAgICAgICAgIExNOTJhUHAwZ3lua2RiUElUZkZhMmQ5STIyak13bUlvRVpCNkZNeVdrR3kwdU9SNWRmTXd4YVV3VUlVc09vb21lbnpODQogICAgICAgICAwY3FWbWpqUjE2SUFCMkdDYnEvbmIzYjcyajdZRWE2Ly9Hb1ZpbzRVQkJIWG9ZWGxtQXY3Tk9Ma3c0YlFJcCswYVpHRg0KICAgICAgICAgcVBucVU5VEd2cGFKVjRIOUVPSFVOTTlkNlhZYjZyRFJ0STg2ZFdSRURocGxFK01oMDhwUjdEZXNsS3g1R0dITXdEejENCiAgICAgICAgIGpYWVE9PQ0KWC1HbS1NZXNzYWdlLVN0YXRlOiBBUGpBQUFWTXVQT1BWUWNwSHZveTJzektibFQ2dElJRnNJWVVQTFVVK1JmQkhtWm9PZUd2WjlmbQ0KCVRhMEY4N3Q3bmVwaEpMVmVxL1BzUzBUbjkzTUljTW89DQpYLUdvb2dsZS1TbXRwLVNvdXJjZTogQVBYdllxeWdzNitlMXBvcHhjYnFIYkIzdEh2cktmMUlXTi9GNzNYcE9Ncm9wR09pdDlzRVI4cE14Yll2RFg1b2xzRzkwTEpMUjNvVDF3PT0NClgtUmVjZWl2ZWQ6IGJ5IDIwMDI6YTE5OjNmMTY6OiB3aXRoIFNNVFAgaWQgbTIybXIyNTU1OTcwN2xmYS4xMTYuMTU3NzM3ODc3NzQxMjsNCiAgICAgICAgVGh1LCAyNiBEZWMgMjAxOSAwODo0NjoxNyAtMDgwMCAoUFNUKQ0KUmV0dXJuLVBhdGg6IDxtaWNoYWVsLmZsb3djcnlwdDJAZ21haWwuY29tPg0KUmVjZWl2ZWQ6IGZyb20gWzE5Mi4xNjguODguMjJdICgyMy0xMjMtMjA3LTgyLmlwLnVrcnRlbC5uZXQuIFs4Mi4yMDcuMTIzLjIzXSkNCiAgICAgICAgYnkgc210cC5nbWFpbC5jb20gd2l0aCBFU01UUFNBIGlkIDE5MnNtMTMzNTEzMzVsZmguMjguMjAxOS4xMi4yNi4wOC40Ni4xNg0KICAgICAgICBmb3IgPGZsb3djcnlwdC5jb21wYXRpYmlsaXR5QGdtYWlsLmNvbT4NCiAgICAgICAgKHZlcnNpb249VExTMV8yIGNpcGhlcj1FQ0RIRS1SU0EtQUVTMTI4LUdDTS1TSEEyNTYgYml0cz0xMjgvMTI4KTsNCiAgICAgICAgVGh1LCAyNiBEZWMgMjAxOSAwODo0NjoxNiAtMDgwMCAoUFNUKQ0KVG86IGZsb3djcnlwdC5jb21wYXRpYmlsaXR5QGdtYWlsLmNvbQ0KRnJvbTogbWljaGFlbCA8bWljaGFlbC5mbG93Y3J5cHQyQGdtYWlsLmNvbT4NClN1YmplY3Q6IEVuY3J5cHRlZCBQbGFpbiBUZXh0IElTTy0yMDIyLUpQIChFbmlnbWFpbCkNCk9wZW5wZ3A6IHByZWZlcmVuY2U9c2lnbmVuY3J5cHQNCkF1dG9jcnlwdDogYWRkcj1taWNoYWVsLmZsb3djcnlwdDJAZ21haWwuY29tOyBrZXlkYXRhPQ0KIG1RSU5CRno3bCtrQkVBQzdET3Bqdkozd0lMV2hRRkVXZkRXbmpYWkxFZmllaUxRNk5aWDhlajNJR1VHYXBJZjcxSjk5Y1FBRg0KIGFrRGtYMU5GMkJWTlJ4VHFqelE0d3g2c3Q0enhBY3dURktYbVZqSURVNlhNTFZGQUVsMWVQNVZ5YlkwZHZ2N3VZUU44VmNoZg0KIFFwYkx6T2ZDejZPYzJYK0pObklJYUtLRWNhZTQ2aGdmVitlVTlrdERWaFFnYjFPWEgvbnkvOEdEZHdRVWp3eXNPdUFSOTM2NA0KIDlsbnhpaWJaSk5tZDdxZnhNbWpOMUx3ejV5R2FvUEhIbis4aXQrb3lNeCt6MzZadCt2MkhlOXNSSHRQR0lFWTJyZERzemRFUg0KIFd2MWZ0akhZZzFPK3EvaXJBUDN4elo1NzhmWktsYVR6MjA1ek9WUWhsa1dJeVhBMVd1ajd5ampQck9lNFFGNmhjSjRqR29ONg0KIFl2Z1ZXeHh2cXdkTkFLQnhUUVBMeXFickFhMW5IL3N2bnVvWDRtY3puZ1c1bnBCbTQrUFNCYkxvM0FEQnUxYm9HaEdsMVFhRQ0KIHZJRzdMK0d2YjlJdzNaeURLU2VydEIwWlFaNklFNzgyay9EMHNTYlQ4bW5pWTVDckdPMG9OYUd2cXJGdWFPRXJOaEdRNmZIMA0KIEdPVTQ0V1Z2WWlWWGRoM0N5RlE5MFAwaHBtbGNOcFNoQ05FYUE5NCtuZTdCWG1NSm52QWw5Y1A5OGdpQW1RbFh4NGNHeStKQg0KIGN5Q3M1TGR0dkZtbDUvRDk5cGQ4b2luQ1FXV0F2alpJNmRpUUROcmt3MmtRVkhxYUNCZXJWMjFlQi9lZWUzYUlNenZDdXJjcQ0KIFREREphMUNFb0hYM0lOVjRhaXZxNC82WXM2WjRpNHRpbEQwd2ljS3plenU5RU5GY21RQVJBUUFCdEM5TmFXTm9ZV1ZzSUZadg0KIGJIbHVaWFJ6SUR4dGFXTm9ZV1ZzTG1ac2IzZGpjbmx3ZERKQVoyMWhhV3d1WTI5dFBva0NOUVFRQVFnQUh3VUNYUHVYNlFZTA0KIENRY0lBd0lFRlFnS0FnTVdBZ0VDR1FFQ0d3TUNIZ0VBQ2drUUFKSVZUSTFJSXpWcVVBLy9VTmdqNnB5N2p1dWkwRXdQT3dORg0KIElDOXA0MHFhRHZqcWZOVmRmbWNyLzM5b2RtOHl6ZHgvMGVaVFJJR1pEV0MzQkJNNWdTRkY5Wk5HY1ZGVE1lME4zT1paUHhHbQ0KIFk5WE43OWpvYmVWdkUwV29MRVpFSEk5SVk4NkhMQUM4eWMvU2VpUXNiS3A2WmlKeUR1WTRnVVEwN3lxNEJjL0hmZ1R5SVRzaQ0KIGFvRnZXWEVIY0x1dzFaT2ltQ3BRZzErWHFHd1doQW5OaFhHRmU2dHZ3NDF1ZWhhZlBFTis4TGovTnFNckZRNXFWT3NsWFVVdg0KIHZrcGZOdkFtN0xCVklZNzlZQWU1c3UxWE11S2NyeFcvN25aQkthM21iRlljbmp0YlcrTEpxY0VmQWw0Tk5ETkQxaG83R3Vscw0KIFAySkZ4bHh5K1lxWEo2b0c4OEh4YjVtZGxWeVdTa3VHRytCWTc1RDFmZ2VudjRudFpvdW1DZENhRElsS0ZPd2ZDRjdFVG9aWA0KIHRlZFN5enMwK0RSZmlWZzlZcDh3M0lJeEZuK0toTjN4MTJOWHZrTm0rWk9DK0k3c2FjL2J2WDdLSjNUaFVmL0MxUXlzYnBtUw0KIHdmbWxTcWs5U2p0aGJkbHJXWjIwT0c1eXZJaUNTMUJpeGpvMmxUSkxBNlFTcVFtY013amQ1clFydXQ1R2tUSHF4blFRYjQydQ0KIGVPK24vR1Y0YzZ4MFFUMWhmS1Y3dGhFM1U3WFB2elVLNUU4VGk5Q0xrRGQ2S0U0aEFjdDJqaGxFN3pZSHJTYmtKbldJVUlucg0KIFFlZlBRMEVHMnFKemRaWG5pQlhqMk9yd2syVVZzZXJ0a0xEM3k2SXd2N1hrOXBwM3pYV09QS3hGSzNMYm5mTHdtSVFDZDNWUQ0KIDE0dWgvaFIzYVJaZk4vMjVBZzBFWFB1WDZRRVFBSzcvOFVLbWN1VE5IeittUGZvT2RNa3hnZHppa3g5emd3QVN1YmMyTmhxMA0KICtiK1A0eWlXT0pnYm1VTExYbnBWRUgzSStYeXFnY1VpNDJ3WjNLV3gwNFdiZzFkbHNTaU1OLzlvamRYZmhuK0syVjVRbnJVUg0KIGxnWnJ6MnhMQ2NNTmdiVnBkc0x2OHRud2IxcklRYXBxL2IxMlJKS1U5WkJ3WC81Vzd6YTlVQWp3aWJXZ3JWc0ZDVVI1b21sTw0KIGU3WmcxeiszN0RtSUlVR3duRE43bkhIK0xPeVp4dTJTVGRLeDdFWlE3Z2xxaS9XbkU4NWRvUmlkQVJyTTlsUGliR0pseExRMA0KIFhuVHJnUGtLZC9BK0Q2YWlkVFMrTlVTSytIU0xPSnpPdVduejlNSEV4WXVRRy9mMldDTlZhYkFZTm5JbDlmSkVjQ2R1ei9TUg0KIExienhIOGlMMjVIM3B0b25XYWpoa3YvdkZ6Znp6QUZoWE1KTmVoRlI2UXVaRmxCUUEwNzhTdVBiNTdaWWdYQkE4S1A5dU4yeA0KIDIvVGQrTzd2VHVZQXNueUh3aFp5Q0Z0THRNUDVqeXQrT2JSOHdXVzFPclZVVnhPeHZXNHpjTUJkQ2Z0MDdDMDNhSW9Pc3Z3QQ0KIEZpZS9lSmh0ZTJjemR0R1BOOElsVVpNNVp0S29wNFllcGhJeFdkNHlYcVBidFFOdUNRbHpZUmFMTzdBNnYxbExrS1N4SUVTYg0KIFhiTWQ1ZXo4NkpvaHFGYlNMbnhFM084K1doTGNZRWE4djZ0UHNJMUhmeGtVR1lleFdKOVFCbkZLdFc1cGpNTW9KdjE3czhXdA0KIHNla2pYbUdoc2plNDUyTWE3SUhmbkVjcm00cC9HTzlBRnZQMDYrZmtadmpQYjJydHhrd21HMm9NVXB0Vm9PNDNBQkVCQUFHSg0KIEFoOEVHQUVJQUFrRkFsejdsK2tDR3d3QUNna1FBSklWVEkxSUl6Vk9nUS8vUVQ1U3BqMTV5MTBiaFNDSlhjNWFtb1JVRy95ag0KIGxqclBMa1IrKzlZaXdzVXZjWmdLZXNNS2dLcC9jcU9QbXB0RDVDNjZjOW9HMUZ5dkhjbFl1amtpL1NLaHBucnVSS1NudkRXLw0KIGxwWm5ZbzFRbk54MUtoeHU0WFRjanR5Y0FLZmlqQlZ1dVIvbWFUb1I5RFA5bjQvNXNlSDVUZUxJR0pnK1lVY3pMNEhJK2tKbQ0KIDhpSGFubVB4WlFSNjlDcjF4REI5RndsaUxsOUJhVEZiczBsV09ndUVrcXdsODRFQUN1R1FUTE9HSTR1MUVOLzlSZ0F4OEpYNg0KIEpxQTVsMXJwbEM0TjhIUGdKNnpCcDd5ZHpkU29mb3hHY3RTQVRKVm1vd2VlV3dMNTg1R2RzRTBGcytjV1ZTYjgvdHFGWEdHUg0KIC9vQjk1cmI1ZDE2OXZGN3ZiY2IraDZaaWRzUFpxcW56ODVPMkVnSTVMa3VzeUNHK0diS0lpYXdrQjU2UUEzTnRUN1pvdEMyTA0KIDZGVnpiMDBZZXprTE51L1p0R3E2dlZrN3F6Qnc0eitidTZ4VVdFSllUYm5WYTFLYW9wM2N1NG1WbDhwZkVYUUFkN1djaGdkTQ0KIFVMbG4yY2Rtb3hOaTYzcjdkVWpFSXY2UUlReXNDc2Y3RWp4Rnprdmx3NFY0Zllyb2RXa2lzdWFtZDFCcWtXTGxIbmVLYXF4Mw0KIG56VjM1b21odnZWTlF5QTlncU1Ba3hhZEpoRDRQeFM3S3ZQR05lalFzbWhNRTRPb0k4eWVnL2lPR1IvT1RwTWhrL3JyUVd0Rg0KIDJ3ckNCRXhoMkVLT2tSQ3gweFZ2eU9qalN0RkVLYzdTa3VZNU5yNUZlMzY1ZWxEa1hTcjdMbUVjamRSMWZoRlY3Y0c0VExNZQ0KIHg2YVJYc0E9DQpNZXNzYWdlLUlEOiA8NzMwODg1YzctYTFlMi02MGVkLTg2OTctNjg4YzQwM2JmY2Q4QGdtYWlsLmNvbT4NCkRhdGU6IFRodSwgMjYgRGVjIDIwMTkgMTg6NDY6MTQgKzAyMDANClVzZXItQWdlbnQ6IE1vemlsbGEvNS4wIChYMTE7IExpbnV4IHg4Nl82NDsgcnY6NjAuMCkgR2Vja28vMjAxMDAxMDENCiBUaHVuZGVyYmlyZC82MC45LjANCk1JTUUtVmVyc2lvbjogMS4wDQpDb250ZW50LVR5cGU6IG11bHRpcGFydC9lbmNyeXB0ZWQ7DQogcHJvdG9jb2w9ImFwcGxpY2F0aW9uL3BncC1lbmNyeXB0ZWQiOw0KIGJvdW5kYXJ5PSJqbjBXWEpIcUhWUVQ5aHJ2dWcyOEI4dWZEM2NUcFdaMHQiDQoNClRoaXMgaXMgYW4gT3BlblBHUC9NSU1FIGVuY3J5cHRlZCBtZXNzYWdlIChSRkMgNDg4MCBhbmQgMzE1NikNCi0tam4wV1hKSHFIVlFUOWhydnVnMjhCOHVmRDNjVHBXWjB0DQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3BncC1lbmNyeXB0ZWQNCkNvbnRlbnQtRGVzY3JpcHRpb246IFBHUC9NSU1FIHZlcnNpb24gaWRlbnRpZmljYXRpb24NCg0KVmVyc2lvbjogMQ0KDQotLWpuMFdYSkhxSFZRVDlocnZ1ZzI4Qjh1ZkQzY1RwV1owdA0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW07IG5hbWU9ImVuY3J5cHRlZC5hc2MiDQpDb250ZW50LURlc2NyaXB0aW9uOiBPcGVuUEdQIGVuY3J5cHRlZCBtZXNzYWdlDQpDb250ZW50LURpc3Bvc2l0aW9uOiBpbmxpbmU7IGZpbGVuYW1lPSJlbmNyeXB0ZWQuYXNjIg0KDQotLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS0NCg0KaFFJTUEwdGFML3ptTFpVQkFRLy9lbWJGR1ZQUnVWZmlVdWpoTGVzUWE2YTRzYnAvUE9RY0FzeSsrTzZ0RC9WQQ0Kd3JRdFBoSmVuaVlWRmVPcyszN01XeTFQa09VbjZBQXZnYXNIdGxNQ1ZudGh4YXZHMW9uSW1DSld5QzBOZGdZbg0KaHJJTjlhUG1PWTdVR2hWenBVL0dUeEUxV0hKSEdNTUdTaG1LYnQrSlRodEF2bXVmdURLMURTaG8za2NqR0VzOQ0Kd3BZMERVMCs5STd4RW1vYmdRcUs0anl6TEJMTng0YUhsMnF1cktTbWpnaG1rMVpNVzRvbHVja3JEbW1RM0FXVA0KWi9xN2JuYlAxR0ROSlY4Y3hSN2VkNGs2SEN6a3JYK0J4TDMwOEU4c29MdGc4N29jYzE4UW9KQUlSQUhVMGt4NQ0KSmxTOStmaC9qTndLYW5aSmpDV3Y2aHFaS3o5aVVvY1JaRDlpUHFoOWRoanNLYWxxa1JheHVQTTJlSmtaWSs5MQ0Kakc4dHNIWVRMZVkzM0E0YVVwZEE2RnBOUjhVeXo4QWd2K3g4L2FGcDhHeFNOSXVVdW1mNmJTSWsyT3VkdC9hNg0Kcld2Wk8rTStVSzUzYTRrNGlieHJrdjR6c0U4Q2JpampDUDhCdlVyQTM3MDIzR0VXa09ISXlNb0ZGeTBvMDZXMQ0KNTZ3VFAyYkxtS2J1amVFUytka3pqcnIxcjlYNm9EQndwb1BBQktTQWpJS0ZRS2N4V3ZoTWd6NFdPM3c2MWczRg0KRThVMFJseDRsQjRDZTFJMHF6dThTNGhrYVo3c1ljS0ovMjExcHpzYWYwQmZ4WlFkcmZ5dTVrc2UyNzVZZ1RVQQ0KYk9ibm9XMnNBV2c4Zlg5Snd1TDlKVkFybkorNkFPUWp2Tkc5ZnIvdU00dGhWL3p3cUJVV2ZRMHNhc0RqanhTRg0KQWd3RHFuME1HOStVSHl3QkQvOWJNckhOay9xaXJ4cGZJUmE5dlpjWnNzWHY3QTYxWFVaeTJJVnVtOStwOWM0Vw0Kc3dkMjNrUU9mQy84MkZ4NzVDd01RK3p6ZFA3KzV0cWVOZm0zLzR2Zk9iTENtc3pmMSsrajNuVnhFRVg4c1dwQw0KbWdIb2JEM3VaUHdnU2h2Z2N5NlpIa2Z6K0JyeHFxVEpJWjZ4RDAzVmd6bU5nMmN1QUhEMVlWVUtiVEhHWWNLTQ0KQ1kwYisxVkc2bHY0Zjc4eGlCMHY4YXcvYVBUdnR4MHJZMmcwWVpIYUUwSlhUNTljTU5UTU9STmlFOGg4Z3VMQg0KbGY2aGN3Y3RSTitzSnc1b1cvc2FYcGdGSlN6VmJRcndwMGExYjZGdHpxditxeUpMMit5YXk4M1JhUFgrUjdMUg0KSnk5alByd0JiendDVmJKQkJTZmVRMHpYa2VOQU9zbzgzckUxM1VqeFBzbCtrVTBhanh5NTVLL1AvY0xPNktLcw0KS3RGTjdVR28yakdlbHBxRG9HVTVGd09vR2VFYVlXK0luclpyeXlWL0EyYmp3NlptZmJoMEdNemxzMjVmSy85Tw0KT0pwL0QweXFFbW5rVTYwTzZlRHd3d3hZN1ZOcW10dU9UWjR6OFBJYVY5TFd1ZnRWT2VPRzk5KzlnNjI4MENLRg0KWVlIQXhnYjU1OXY3MFY1MGJrK1o5MXJkQTFTbnhTcTl3T2tVdTJLMUJta1RkcUVPNWp4V2YwNE1HcnZST1pVQQ0KZElLUStQWWliblJvK1NPYkJVbjRPdGxmaGVsMXRKOXdXV2pKTHBHSjFabTNGYW9DVkgvTW5udmhGNDhRNUpOUg0KU0RucVRnNHdXZDUxVG9rY256MlBvUHJ4Uk4zamFjSTRkMEdaaUF0c21CMjhtY0tqZEI1VVlvWEV5Mk1hek5MQQ0KeUFIekNIUnRPSjdlT2NTdHdsdHduYmg2Ny9SQ0s5T0NlZ2FpU09NQWNzRWNpVlhVcFQraFZsOG9NbDZJdkpEaw0KRnExQ3dPTDh0M09qM1cyaWdQa20yRWVqSGwxZGt6MkpYUEhqZkhxdDI0dFR0V1JhM3h1b3RvU3ZNQXkrdGZLVA0KQ3dnNjduUWFuLzEzaGwzZUYwWFhMQ0QrK2FvdEdTYWhVZVBzZ1pVNzlvZWRZMnZtY29mVWY3NDNzWi9ONmFNUA0KZ0VMend5TG03THpjRkxqZW9raE5VRFlwQmdySDUrRmNGWnFwaVRRaElMT05TdmVubmNQNGszRkRqQzg3REc1Sg0KeUlja0JOMUtlVTIxOXZhWUhFa21TbVUzZWdmRVlSTXcySHpuRkFhaU1FQW5Eb0dzMFpUcU5PeDc1a3RaTHBmUw0KNzc5QVBTVERtUy9oc1hYbzdEOC9teVlXTzVSTXhGekdMN1NJY1hrb3NxYStUUzNGSjUxOThlcEgweExOckRoTQ0KMWxNTzJaVTVxYjJUTkErV3ZTdmlpd1dzWit5ajZrRDFyenJ2RWcrK3ExYjY3czNvb2dQMDh3d0hjZlgrVWlORA0KdmRHZVZkMllGUFgwa3N6aHRmSkRFWUFrSjhFUmU1UktRcWVOWGRrOFhNWXEyaXJwM0FWQlRCRGtnVGdNRFBTVQ0KQ0kzZzg5UzNlbGRUDQo9UDRPOA0KLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQ0KDQotLWpuMFdYSkhxSFZRVDlocnZ1ZzI4Qjh1ZkQzY1RwV1owdC0tDQo=", + "historyId": "1405889", + "internalDate": "1577378774000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-16f66f1da9d50d05.json b/test/source/mock/google/exported-messages/message-export-16f66f1da9d50d05.json new file mode 100644 index 00000000000..199df8b0635 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-16f66f1da9d50d05.json @@ -0,0 +1,136 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "16f66f1da9d50d05", + "threadId": "16f66f1da9d50d05", + "labelIds": [ + "IMPORTANT", + "STARRED", + "CATEGORY_PERSONAL", + "Label_12" + ], + "snippet": "", + "payload": { + "partId": "", + "mimeType": "multipart/encrypted", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "APjAAAXdsAjPOBidLuhLC2z83Q695hzN4Md1IQuuKGiGKOJwveCtLqQ7 ugKhTSO6lLNGEFPtYzcJl/kjupx6stw=" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "Subject", + "value": "ISO-2022-JP, PGP/Mime" + }, + { + "name": "Openpgp", + "value": "preference=signencrypt" + }, + { + "name": "Autocrypt", + "value": "addr=michael.flowcrypt2@gmail.com; keydata= mQINBFz7l+kBEAC7DOpjvJ3wILWhQFEWfDWnjXZLEfieiLQ6NZX8ej3IGUGapIf71J99cQAF akDkX1NF2BVNRxTqjzQ4wx6st4zxAcwTFKXmVjIDU6XMLVFAEl1eP5VybY0dvv7uYQN8Vchf QpbLzOfCz6Oc2X+JNnIIaKKEcae46hgfV+eU9ktDVhQgb1OXH/ny/8GDdwQUjwysOuAR9364 9lnxiibZJNmd7qfxMmjN1Lwz5yGaoPHHn+8it+oyMx+z36Zt+v2He9sRHtPGIEY2rdDszdER Wv1ftjHYg1O+q/irAP3xzZ578fZKlaTz205zOVQhlkWIyXA1Wuj7yjjPrOe4QF6hcJ4jGoN6 YvgVWxxvqwdNAKBxTQPLyqbrAa1nH/svnuoX4mczngW5npBm4+PSBbLo3ADBu1boGhGl1QaE vIG7L+Gvb9Iw3ZyDKSertB0ZQZ6IE782k/D0sSbT8mniY5CrGO0oNaGvqrFuaOErNhGQ6fH0 GOU44WVvYiVXdh3CyFQ90P0hpmlcNpShCNEaA94+ne7BXmMJnvAl9cP98giAmQlXx4cGy+JB cyCs5LdtvFml5/D99pd8oinCQWWAvjZI6diQDNrkw2kQVHqaCBerV21eB/eee3aIMzvCurcq TDDJa1CEoHX3INV4aivq4/6Ys6Z4i4tilD0wicKzezu9ENFcmQARAQABtC9NaWNoYWVsIFZv bHluZXRzIDxtaWNoYWVsLmZsb3djcnlwdDJAZ21haWwuY29tPokCNQQQAQgAHwUCXPuX6QYL CQcIAwIEFQgKAgMWAgECGQECGwMCHgEACgkQAJIVTI1IIzVqUA//UNgj6py7juui0EwPOwNF IC9p40qaDvjqfNVdfmcr/39odm8yzdx/0eZTRIGZDWC3BBM5gSFF9ZNGcVFTMe0N3OZZPxGm Y9XN79jobeVvE0WoLEZEHI9IY86HLAC8yc/SeiQsbKp6ZiJyDuY4gUQ07yq4Bc/HfgTyITsi aoFvWXEHcLuw1ZOimCpQg1+XqGwWhAnNhXGFe6tvw41uehafPEN+8Lj/NqMrFQ5qVOslXUUv vkpfNvAm7LBVIY79YAe5su1XMuKcrxW/7nZBKa3mbFYcnjtbW+LJqcEfAl4NNDND1ho7Guls P2JFxlxy+YqXJ6oG88Hxb5mdlVyWSkuGG+BY75D1fgenv4ntZoumCdCaDIlKFOwfCF7EToZX tedSyzs0+DRfiVg9Yp8w3IIxFn+KhN3x12NXvkNm+ZOC+I7sac/bvX7KJ3ThUf/C1QysbpmS wfmlSqk9SjthbdlrWZ20OG5yvIiCS1Bixjo2lTJLA6QSqQmcMwjd5rQrut5GkTHqxnQQb42u eO+n/GV4c6x0QT1hfKV7thE3U7XPvzUK5E8Ti9CLkDd6KE4hAct2jhlE7zYHrSbkJnWIUInr QefPQ0EG2qJzdZXniBXj2Orwk2UVsertkLD3y6Iwv7Xk9pp3zXWOPKxFK3LbnfLwmIQCd3VQ 14uh/hR3aRZfN/25Ag0EXPuX6QEQAK7/8UKmcuTNHz+mPfoOdMkxgdzikx9zgwASubc2Nhq0 +b+P4yiWOJgbmULLXnpVEH3I+XyqgcUi42wZ3KWx04Wbg1dlsSiMN/9ojdXfhn+K2V5QnrUR lgZrz2xLCcMNgbVpdsLv8tnwb1rIQapq/b12RJKU9ZBwX/5W7za9UAjwibWgrVsFCUR5omlO e7Zg1z+37DmIIUGwnDN7nHH+LOyZxu2STdKx7EZQ7glqi/WnE85doRidARrM9lPibGJlxLQ0 XnTrgPkKd/A+D6aidTS+NUSK+HSLOJzOuWnz9MHExYuQG/f2WCNVabAYNnIl9fJEcCduz/SR LbzxH8iL25H3ptonWajhkv/vFzfzzAFhXMJNehFR6QuZFlBQA078SuPb57ZYgXBA8KP9uN2x 2/Td+O7vTuYAsnyHwhZyCFtLtMP5jyt+ObR8wWW1OrVUVxOxvW4zcMBdCft07C03aIoOsvwA Fie/eJhte2czdtGPN8IlUZM5ZtKop4YephIxWd4yXqPbtQNuCQlzYRaLO7A6v1lLkKSxIESb XbMd5ez86JohqFbSLnxE3O8+WhLcYEa8v6tPsI1HfxkUGYexWJ9QBnFKtW5pjMMoJv17s8Wt sekjXmGhsje452Ma7IHfnEcrm4p/GO9AFvP06+fkZvjPb2rtxkwmG2oMUptVoO43ABEBAAGJ Ah8EGAEIAAkFAlz7l+kCGwwACgkQAJIVTI1IIzVOgQ//QT5Spj15y10bhSCJXc5amoRUG/yj ljrPLkR++9YiwsUvcZgKesMKgKp/cqOPmptD5C66c9oG1FyvHclYujki/SKhpnruRKSnvDW/ lpZnYo1QnNx1Khxu4XTcjtycAKfijBVuuR/maToR9DP9n4/5seH5TeLIGJg+YUczL4HI+kJm 8iHanmPxZQR69Cr1xDB9FwliLl9BaTFbs0lWOguEkqwl84EACuGQTLOGI4u1EN/9RgAx8JX6 JqA5l1rplC4N8HPgJ6zBp7ydzdSofoxGctSATJVmoweeWwL585GdsE0Fs+cWVSb8/tqFXGGR /oB95rb5d169vF7vbcb+h6ZidsPZqqnz85O2EgI5LkusyCG+GbKIiawkB56QA3NtT7ZotC2L 6FVzb00YezkLNu/ZtGq6vVk7qzBw4z+bu6xUWEJYTbnVa1Kaop3cu4mVl8pfEXQAd7WchgdM ULln2cdmoxNi63r7dUjEIv6QIQysCsf7EjxFzkvlw4V4fYrodWkisuamd1BqkWLlHneKaqx3 nzV35omhvvVNQyA9gqMAkxadJhD4PxS7KvPGNejQsmhME4OoI8yeg/iOGR/OTpMhk/rrQWtF 2wrCBExh2EKOkRCx0xVvyOjjStFEKc7SkuY5Nr5Fe365elDkXSr7LmEcjdR1fhFV7cG4TLMe x6aRXsA=" + }, + { + "name": "Date", + "value": "Thu, 2 Jan 2020 17:48:40 +0200" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Content-Type", + "value": "multipart/encrypted; protocol=\"application/pgp-encrypted\"; boundary=\"zAAof6AQi3Kw0jH3WNdRvGF30kCCq1qjt\"" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "application/pgp-encrypted", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "application/pgp-encrypted" + }, + { + "name": "Content-Description", + "value": "PGP/MIME version identification" + } + ], + "body": { + "attachmentId": "ANGjdJ-c7s05r91FzBL7wxqkxZBrXiSb0l0sEjxD2w-BJUi8hh3o-923E_8mJvKyv3EJUY0diTffMjMUtmyXooJ-CwOWyYdGzVMIu1ib_O-i_dfE8NY8Z-855qUomEJ0cOP_WYyCBA4s0WPo-TeH2vUiWyjOO293C4a-sBVB8wd-smwywns-i1yEHo3NKPVsq7XXiigKfk9c_gaJto37wXUu_agG25ZYC4WsInkt33KBTbD70tDVPcYA6hd4NIkynag3caFUKWUNHyHEK3oGMGcSvJngAxvAtYmb0RdAajNsWhitQotCrWNFeRJNwVKoWG1KCxth33F21vztibcHKD2rrDwvTMlz8wsLrFtD4CH_lM6yvfrlJWTf9NFbgq8", + "size": 12 + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "encrypted.asc", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream; name=\"encrypted.asc\"" + }, + { + "name": "Content-Description", + "value": "OpenPGP encrypted message" + }, + { + "name": "Content-Disposition", + "value": "inline; filename=\"encrypted.asc\"" + } + ], + "body": { + "attachmentId": "ANGjdJ_EpFVdTxzU9ZSdKpmGLZ9o4RHipy3-JGfeDRa7TOvVUMnrUTUN1nXwfgFfoVTLOgbXPJmxiD-83hBkhOG6jSx2NRt5A_dOGP4vPbgDx6_41R8DxUgQS8I-SJMvWTQJBCaddPwiXJLyO74s5TnynGrOn38F2furwWahX8qGy27aHcYMOFmZVMZw59NR_Zq5AW7GDWGC_S8h1bveKhbBU7haJFTXHwWt0OIpUsOaNkBsjde56weqQ60i6hqANUTc4x1ku8NpePI2fYPwSOu-A7h0P0mU5gykRujr70yWjxnfz-tGQZvP4cDB94uiHj50A3UT8xe_x0vMLo1VQgdPaWc7PExTQNCTveRNz8Ih3FH9WexQ-gTDaOpOfDs", + "size": 2833 + } + } + ] + }, + "sizeEstimate": 11634, + "historyId": "1405869", + "internalDate": "1577980120000" + }, + "attachments": { + "ANGjdJ-c7s05r91FzBL7wxqkxZBrXiSb0l0sEjxD2w-BJUi8hh3o-923E_8mJvKyv3EJUY0diTffMjMUtmyXooJ-CwOWyYdGzVMIu1ib_O-i_dfE8NY8Z-855qUomEJ0cOP_WYyCBA4s0WPo-TeH2vUiWyjOO293C4a-sBVB8wd-smwywns-i1yEHo3NKPVsq7XXiigKfk9c_gaJto37wXUu_agG25ZYC4WsInkt33KBTbD70tDVPcYA6hd4NIkynag3caFUKWUNHyHEK3oGMGcSvJngAxvAtYmb0RdAajNsWhitQotCrWNFeRJNwVKoWG1KCxth33F21vztibcHKD2rrDwvTMlz8wsLrFtD4CH_lM6yvfrlJWTf9NFbgq8": { + "data": "VmVyc2lvbjogMQ0K", + "size": 12 + }, + "ANGjdJ_EpFVdTxzU9ZSdKpmGLZ9o4RHipy3-JGfeDRa7TOvVUMnrUTUN1nXwfgFfoVTLOgbXPJmxiD-83hBkhOG6jSx2NRt5A_dOGP4vPbgDx6_41R8DxUgQS8I-SJMvWTQJBCaddPwiXJLyO74s5TnynGrOn38F2furwWahX8qGy27aHcYMOFmZVMZw59NR_Zq5AW7GDWGC_S8h1bveKhbBU7haJFTXHwWt0OIpUsOaNkBsjde56weqQ60i6hqANUTc4x1ku8NpePI2fYPwSOu-A7h0P0mU5gykRujr70yWjxnfz-tGQZvP4cDB94uiHj50A3UT8xe_x0vMLo1VQgdPaWc7PExTQNCTveRNz8Ih3FH9WexQ-gTDaOpOfDs": { + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCmhRSU1BMHRhTC96bUxaVUJBUS8rSmdwbWtnc2NKRUI5dUFpRlQ2VGJlWnNCcUQvclJESW5hYjlPZXZyUkJXT1oNCndRN1V4UzRPa004TTFqb2ZsRWd0UDFaak5rQ0N1T0c1UlhSM0paRmtVZVFidnRNYzRtcHgrT09qWWJ3SHdOTkUNCjA1d2JjSUhuMzgwYXhOUFdNWXFlOC9pQ0s5d0ZXaE1Ed3RwRGZKMFB6TEtBaG5qRmh5bU1Xam1YQjJhdmVqYVMNCmlhS1FSZWxtVWlOdDVUazZGQXU4VW5PQWJyNyt1THZGQnp6anlFTEwzcEd6REJMa2F3aFVUMlFaMm5xckMxTnMNCko4SEVYbmwwVEJJNVQ5cmxLNWk2WVFpMmkyNlNXazhRa00wb3Y1T1dWSzFxSVNmMTVWSGVQNXVMWGNoM01mSHUNCkVmUUV1Ym8zNzhKYmthOVFNbzEvRS84dWJsR1FSZU1wc3Zicld0bzlIcWZQU1hVR2UzaFVRY0lSaTNuS3VRQngNCm5iTVdvbm5ORTdVRWhCRnl0TEwydytNbUJEbGtlUGE3ekRuZ09qUXdMcFlOVnZyeEpuQ2prNlNrY3JuK3gyMEQNCllrR3ppRXVicWhxdU1STHhKaHQ0VVRMdVJTTEk4ajFOdElSWjVROUJpKzFrclNKejUyN2NicS9JRkJVK0VtTlYNCmZDY1IxblliRjUvaHlUd0I3YVpReXhDVmxSV0tsWWZ3djQrN3E5Y2o1d0NCdUxDWTdaS3VjRWJ6b2RlaFJjRXQNCjRDOFR4ZzJLa0Q3LzgrVHQ2MEtjcWp2eUR0UWtRWU5TYXVidWdzRzJCQW1KcFlSVTZLRlZHRGxwTmU2Z0dFUUkNCmhuVlFxNVVhWjl6MERjZXZFMjVYcjdmZzJtTE43eUhSUlNhdXZPR2xNblA5OGQzZ0RsdVFsYnZBems1cU9NcUYNCkFnd0RxbjBNRzkrVUh5d0JEL3NIRjU4b2d4SzNrQWJJVGpBNDUzVTE1S2tSNGJBcWNIMzQzbVBmalBPUFR5QWINCjNJTW9ZYlFWOVNiSHVwdGF2NnQ5cmh0ckdFa05WdW5MUUxyR1lOYndyUXgyNTN5cWdOK2RSWUQ4bW4xMDF5Sk0NCkZjTjNSNlBEQ3hBTDRoVzBjWGpTc3BhcWUxbXg4VTdweitMbjFEckM0WDhPOUhIZ01yUHZVbDE4VWMxNGZBa3cNClptK3drNXZ6Vll4SHA4V3NRWGI5eHBlMWltbGV3N2pQdUhaa05TQTRrNllEb0duL3dwTjNtRU9LRTNCWXE2Um8NCmhuVGFhcEllK0pJenNhL0gwSFhLY0QwenRGZVJVRXl5amQrZEUzdmRKWWVoWnJFUUlqc00wb2NxYm41dGNmMVcNCjlEUDBPWEd5bFRmTmJCTVQ2UFE0TjVnZnlRRGV4dDlaM1FPVDBjM0hjbVVZSEpkODY1alI1blhIR3pzR1crVXINCmQwWjZBYUNzU0NQOFdQVU5peEx6Z0NkQjdFUTZaNVBCNGV0ajkrRm1LWXZFYkZpYU9yOWhyWTQ4bnkraU9KanENCnMwZHVkaGdaa0U4WHBBOWpjSmFHbk00VVpkRm5zc2lUeWRscWFGV1l3alZrOGQ0Q3NqcnNUeCtKTlJXT1NWSHkNCjlXQmJVRlFjMWVIMDFydjFzZkw0NjdFeXpoaDkyU0NmSG9vSE45bEx0RjJtRGg0M1pRdTBSZVc4YUJkN1J6SGMNCktKQzhFMHdjc2x6THFmRit4N3JoMFZ0NTRZM2kwUFM5SDlSRFdBVHNzQ3gwVjN5U3dibnhxbWU2eklhNXFLVU4NCmtiU3FrdWNtelpLbmFrc2I0NlMwekp5T0IrUVYvOG50WUVybUxzWDFwR0Z2UEZCbTArR1EveVFncFVpSmh0THANCkFXOGpLQ0ZNeVFCSGhCS3lHMGs4RG45ZjVtTzhyRTB4Rzk4Mm0rbkd3bE1LSnVubitpaXl6NTYxVi8yZWJiNWUNClJQQ2oxMlJVQUl6S2ljUHFSYVBDYVhoRXlEMzB5MXJEQ0hPN3ZwQ0IxQ2duYlZmUmNQdlRPT3VVbEdsck1ZV2ENClpsQXlyYzVSa0FpU0NMVUphYjlaVGYvL1QzNGRtUDFwMGJtSU4zTW53dTNYc2JFZFpub1F4cVBTbDBVeWZxaUwNCjRlNXVHZTJaYS9yeHlrTTlDdUcwZjh2dEZXc29OaEprVHVnZFpqZktVWmRueWZkc21aaE5iS2xKY3VCN3BydmINCjBHbDAvM2ZObnM2cXYrK1IvRUdOSGJaaFN4dy9xWlhHQndHYTBZN2h3d3NBMVE2T2JYZ25aQTFURHFGVWhGazYNCi9jRGE4RmxSRDFqajlyS3lldXd3THJ5UnkvTGhvcTFMTC9XVitPaVVCLy9TbGRHYUhrcVh2OStDSk5obU53RVUNCmlDNW1aWXloR0dic1ZjQnh1UWlnaWx5TXBEUUpKZmNVaXFmTjhLTCtOOElDcG51UEdnYU1ROTdTTGVIcTJNbW0NCmVoY0Vad1ZRWkdsQ25RSk5LbWhicXF4SkI3V21kQlJLVERpQnhFNXF6NXIzZ3JCLzV2K01ieU02RzZNeUFua1ANCkEvVUtYMFFVWnNQRFI0MVhWV2haUFREby8vWjZhSUtKd2xnQjNFOXZhazJKa0Q0L3BkZ3p5QU0yOEhPVFV5Si8NClNmQlZMZCsvanhISVZsbTFJYUxVQXp2SmpHME5GbFh2RDdQa3pzNXBYbVVmLy9iVGRGWE5BM3VoN1ZCU0dRTWwNCmthZXl1ZW1Rd2lXMlJheTR0WWJVcS9GQ3psKzg4NjJKQlk5OHczOG5hdHJBKytXTUxISW94MHJoTUlHL3ZveUsNClUxKzJLS2dFRDQxNE1zQzMwOWpuK1A2V0NaR0t0MzRCWFNmRHAvUmJnd1AzWDBRSXhTWU94dG1YOGZqS2xWUFINCjlGUG1rd0Z2SVlzRTE0TVNCMTZ5MnZ4U0V0OEpGS29HaFhSdVZ4bEdvWXV1WnJwRVJmaHlubmt3U0xrdzB6bG4NCk1OVVVpaHc5QWVQaXZpNkgwcXkrN0RwVXkrNDFDVzhueGt4L2RlUGNkYkFxODRZNzFGeWZNN2diTHUwNEVQWjANCmhUenpnU0xEU1d2TGM3dldSR2JxSTFlclFoZmFkUXdpVXpNZDBZQXlJbVdtbm0wMDNkeGZSTk5DMG9DWURFOFYNCjNRR0ZxT21yNEFxY2JNR0lXQkdpUDBMYWptZWhKRXYrOEdrSWt1RHdRUnRrZ2FBa0h3RE1pZ3VqRnRyYXFHRW4NCm1kdVltWUJXODhZRHNYRDlKdjI0ZDRQdDJDZTdQNGxjNERFQVUzdnFVTVpGZEl3SGFuaktTTnI4TzZhWFhkMGUNCndyRmpjNzF0VVROR0Ywc3VOaSs3NG9sMHJsUzFzZVFOaWlqdWxFVzUzbmdLOHo1YnJOU2QxTjU2SC93Y1l4ODENCnFTeWVxbkdZSHBoTmJwd2hCVHFIa1VSQmx3eWd4STIrQ3VNU1I5Nmo0OWtvOUFaWkhZbDZEQkFxSExLWVdIR2kNCnZxdnBHLysrRkZ5MEFNU3hqcy8vQ2U1bFRTM3kzc2tmbmVhWjlzZ0g3bytVWENKN09wK210TGRIR2puNg0KPUdBT1MNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg", + "size": 2833 + } + }, + "raw": { + "id": "16f66f1da9d50d05", + "threadId": "16f66f1da9d50d05", + "labelIds": [ + "IMPORTANT", + "STARRED", + "CATEGORY_PERSONAL", + "Label_12" + ], + "snippet": "", + "sizeEstimate": 11634, + "raw": "RGVsaXZlcmVkLVRvOiBmbG93Y3J5cHQuY29tcGF0aWJpbGl0eUBnbWFpbC5jb20NClJlY2VpdmVkOiBieSAyMDAyOmFjODoxOTUzOjA6MDowOjA6MCB3aXRoIFNNVFAgaWQgZzE5Y3NwMTg2MzEyNzFxdGs7DQogICAgICAgIFRodSwgMiBKYW4gMjAyMCAwNzo0ODo0NCAtMDgwMCAoUFNUKQ0KWC1SZWNlaXZlZDogYnkgMjAwMjphMmU6MmMwNDo6IHdpdGggU01UUCBpZCBzNG1yNTA2NTc3ODdsanMuMzUuMTU3Nzk4MDEyNDAyNTsNCiAgICAgICAgVGh1LCAwMiBKYW4gMjAyMCAwNzo0ODo0NCAtMDgwMCAoUFNUKQ0KQVJDLVNlYWw6IGk9MTsgYT1yc2Etc2hhMjU2OyB0PTE1Nzc5ODAxMjQ7IGN2PW5vbmU7DQogICAgICAgIGQ9Z29vZ2xlLmNvbTsgcz1hcmMtMjAxNjA4MTY7DQogICAgICAgIGI9WlVOYmVXNkVFRUI0VVFpQkI1RnJLN215VERPNHdyKzZ6cWNMYmFtQSsrMzNTbnQ1NVhKc1JCbmRDdU5qdGgxeFpJDQogICAgICAgICBnU0pmMDVzd0ZKV2M0R3lnZjY4UlhPT1U2V1dPc1RhZVUyVEsrMHJNeDdzcWFDODc2RVltbXdQakU0UUMxQ3Q5UjloYQ0KICAgICAgICAgekRLZUJ5Q1F1WWlXRlpTdHhXYzMvTitKbmdGaERvVHp1emUvNVNEdDVRMVM2eXZNV0pTRmduYkNlTzAyWUxQNG5PcEoNCiAgICAgICAgIGdHMHpMbU5FUVlqQ0h0QU5DZDFab3kxdDg5eE15dEtlKzRwVjNGU3JDSUhiY1c2UnhVWmcxSU5ZNHhaU0U0QTJxRXcrDQogICAgICAgICBKQjBWMjV5c1hCYTlEYStsd0d0ZHUwTm9rdDBxejRldUZUMmxQd081ek01QzZYMFRzSktWM3NNUVF5SDdIay95N0xFeg0KICAgICAgICAgb0ZyZz09DQpBUkMtTWVzc2FnZS1TaWduYXR1cmU6IGk9MTsgYT1yc2Etc2hhMjU2OyBjPXJlbGF4ZWQvcmVsYXhlZDsgZD1nb29nbGUuY29tOyBzPWFyYy0yMDE2MDgxNjsNCiAgICAgICAgaD1taW1lLXZlcnNpb246dXNlci1hZ2VudDpkYXRlOm1lc3NhZ2UtaWQ6YXV0b2NyeXB0Om9wZW5wZ3A6c3ViamVjdA0KICAgICAgICAgOmZyb206dG86ZGtpbS1zaWduYXR1cmU7DQogICAgICAgIGJoPVZwc0taYjdRU3NWWTc4d3pZdkpLU2d1YzNZTXlPaGFzeWNtWVVaTnRQVjg9Ow0KICAgICAgICBiPXpXS21hRWlFOHY3SWtUTUxTQldMUlRQQ2czQk1qeVdpN2YycDVtL1NTRDhsU01aUkRvUDM5QVlGREwyeHlINTlvSw0KICAgICAgICAgUVE5TkwvWXZ1cVcrWlpyaGlLVm1yQ3VSY0pJUVluSTJ0QVcvckE3cEtvdUc3Wmx3dEJJUlVUY1hQSzYvYmxNRTZqaWwNCiAgICAgICAgIEZ2SEp2eVpPMElPN0E0OTVOdWxDUVBYM2VyaEhrRkc5ZFdpUFZqM1NyZ0JGdnNiU3F3QjgzTlp5WW5zeG91cytzanYvDQogICAgICAgICBzaHlkWDE2a2h5cCtzY2NrNVZ3dVozWU4vMWtXSXVyRnlUUEpxSTdzRFpuOUZIN3RhZmJteUxnWERKSzJCRFFMcjE2SQ0KICAgICAgICAgYXVNb2grbUtZaDJyN3g4OGhFMUJvVmNYSGU4bk1kYzBTWkQ4OEFGVVQrdnJQWDRhd1dWWi9TSmRkWDJqTEt4SlgwV3MNCiAgICAgICAgIGNGemc9PQ0KQVJDLUF1dGhlbnRpY2F0aW9uLVJlc3VsdHM6IGk9MTsgbXguZ29vZ2xlLmNvbTsNCiAgICAgICBka2ltPXBhc3MgaGVhZGVyLmk9QGdtYWlsLmNvbSBoZWFkZXIucz0yMDE2MTAyNSBoZWFkZXIuYj0iVHBtems5L1YiOw0KICAgICAgIHNwZj1wYXNzIChnb29nbGUuY29tOiBkb21haW4gb2YgbWljaGFlbC5mbG93Y3J5cHQyQGdtYWlsLmNvbSBkZXNpZ25hdGVzIDIwOS44NS4yMjAuNDEgYXMgcGVybWl0dGVkIHNlbmRlcikgc210cC5tYWlsZnJvbT1taWNoYWVsLmZsb3djcnlwdDJAZ21haWwuY29tOw0KICAgICAgIGRtYXJjPXBhc3MgKHA9Tk9ORSBzcD1RVUFSQU5USU5FIGRpcz1OT05FKSBoZWFkZXIuZnJvbT1nbWFpbC5jb20NClJldHVybi1QYXRoOiA8bWljaGFlbC5mbG93Y3J5cHQyQGdtYWlsLmNvbT4NClJlY2VpdmVkOiBmcm9tIG1haWwtc29yLWY0MS5nb29nbGUuY29tIChtYWlsLXNvci1mNDEuZ29vZ2xlLmNvbS4gWzIwOS44NS4yMjAuNDFdKQ0KICAgICAgICBieSBteC5nb29nbGUuY29tIHdpdGggU01UUFMgaWQgbDE3c29yMTE2MzA5MTJsZmouOC4yMDIwLjAxLjAyLjA3LjQ4LjQzDQogICAgICAgIGZvciA8Zmxvd2NyeXB0LmNvbXBhdGliaWxpdHlAZ21haWwuY29tPg0KICAgICAgICAoR29vZ2xlIFRyYW5zcG9ydCBTZWN1cml0eSk7DQogICAgICAgIFRodSwgMDIgSmFuIDIwMjAgMDc6NDg6NDQgLTA4MDAgKFBTVCkNClJlY2VpdmVkLVNQRjogcGFzcyAoZ29vZ2xlLmNvbTogZG9tYWluIG9mIG1pY2hhZWwuZmxvd2NyeXB0MkBnbWFpbC5jb20gZGVzaWduYXRlcyAyMDkuODUuMjIwLjQxIGFzIHBlcm1pdHRlZCBzZW5kZXIpIGNsaWVudC1pcD0yMDkuODUuMjIwLjQxOw0KQXV0aGVudGljYXRpb24tUmVzdWx0czogbXguZ29vZ2xlLmNvbTsNCiAgICAgICBka2ltPXBhc3MgaGVhZGVyLmk9QGdtYWlsLmNvbSBoZWFkZXIucz0yMDE2MTAyNSBoZWFkZXIuYj0iVHBtems5L1YiOw0KICAgICAgIHNwZj1wYXNzIChnb29nbGUuY29tOiBkb21haW4gb2YgbWljaGFlbC5mbG93Y3J5cHQyQGdtYWlsLmNvbSBkZXNpZ25hdGVzIDIwOS44NS4yMjAuNDEgYXMgcGVybWl0dGVkIHNlbmRlcikgc210cC5tYWlsZnJvbT1taWNoYWVsLmZsb3djcnlwdDJAZ21haWwuY29tOw0KICAgICAgIGRtYXJjPXBhc3MgKHA9Tk9ORSBzcD1RVUFSQU5USU5FIGRpcz1OT05FKSBoZWFkZXIuZnJvbT1nbWFpbC5jb20NCkRLSU0tU2lnbmF0dXJlOiB2PTE7IGE9cnNhLXNoYTI1NjsgYz1yZWxheGVkL3JlbGF4ZWQ7DQogICAgICAgIGQ9Z21haWwuY29tOyBzPTIwMTYxMDI1Ow0KICAgICAgICBoPXRvOmZyb206c3ViamVjdDpvcGVucGdwOmF1dG9jcnlwdDptZXNzYWdlLWlkOmRhdGU6dXNlci1hZ2VudA0KICAgICAgICAgOm1pbWUtdmVyc2lvbjsNCiAgICAgICAgYmg9VnBzS1piN1FTc1ZZNzh3ell2SktTZ3VjM1lNeU9oYXN5Y21ZVVpOdFBWOD07DQogICAgICAgIGI9VHBtems5L1YrNklsZDhGUHlIN3FWM0c5bEZPc3grd01kM0RtYk84UzJjZjdKYkQxdWlHTmJsWGk0bmVRc3IvL1FpDQogICAgICAgICBzK0RmcTJnRjN3alN5aW1xMVMyWnhtWTZlZWNhekFnT1RTbnliZVZHMUd4VkFPZ3RCRXNYL2pXTjdsTnlsOTl4aVBlbA0KICAgICAgICAgSEg1NWQrdVBRSER0L1I5Z3RaL0lHdjVjN29rUkJnMVB2RndmanhOT1hVaERjNlRHdERYZzVwa3UxRHVLY1R0MUptSVANCiAgICAgICAgIG9xSmZ5QjNOODhlRGpSZzhEdlhKSDhsSDBTbUg4dEl2VW9Kbm9FbGFHTHA3UHpUUlpWY0JWT3JwNm5yKytqTXB2M08yDQogICAgICAgICBEUzM4Vi8wZkdKdGpqblRTTEZIMU80Zi9jbXVzeUJCMWlzYXhYNnpMc0J4Q096QldMZlMzM0d3UHpYRWdySS8vZUJaeg0KICAgICAgICAgbHlVUT09DQpYLUdvb2dsZS1ES0lNLVNpZ25hdHVyZTogdj0xOyBhPXJzYS1zaGEyNTY7IGM9cmVsYXhlZC9yZWxheGVkOw0KICAgICAgICBkPTFlMTAwLm5ldDsgcz0yMDE2MTAyNTsNCiAgICAgICAgaD14LWdtLW1lc3NhZ2Utc3RhdGU6dG86ZnJvbTpzdWJqZWN0Om9wZW5wZ3A6YXV0b2NyeXB0Om1lc3NhZ2UtaWQNCiAgICAgICAgIDpkYXRlOnVzZXItYWdlbnQ6bWltZS12ZXJzaW9uOw0KICAgICAgICBiaD1WcHNLWmI3UVNzVlk3OHd6WXZKS1NndWMzWU15T2hhc3ljbVlVWk50UFY4PTsNCiAgICAgICAgYj1CMjY0TjVLOCtOb2dkLzJYbWxaNEFYb2J5Z2pPVTJSTm01aE1JRFZJSE1aVGZkNWhEZWg2cmJkRUovNm9WVVFYTkwNCiAgICAgICAgIDhIRWRnYmROamtUN2x5b2xIUW55M2w2dUJiLzN0MFBWWmVUWW15bEVMOG84bjY1T1JtSW00bUF3MGw2SjA3dHR5bnBuDQogICAgICAgICA1RnBKYm5UakZoQU52SUtJdjdiREpKaEducnduQmhjYm8vL1dYLzc1UzdlazluWTR0eWpkWHBTSVNHdEhRY1VLZHdMeg0KICAgICAgICAgSnQwWWlIMHRaSHZ3WjE2V2dFUVlCV25XUHlrOFRaem01a3pYMVBEVmk5N1RzclpHcXgrVTNWSHFsdUdrM2Q4UWNHVFgNCiAgICAgICAgIE5TYWxVVXM1TGdqS0ZlN0lOSnJsSXdSRnZ4ZnFjZ21tRXI1bGxSQmN0RElkdk9YT01DSGxmUSt4UzN0a2puQjR1ZFpnDQogICAgICAgICB5dXN3PT0NClgtR20tTWVzc2FnZS1TdGF0ZTogQVBqQUFBWGRzQWpQT0JpZEx1aExDMno4M1E2OTVoek40TWQxSVF1dUtHaUdLT0p3dmVDdExxUTcNCgl1Z0toVFNPNmxMTkdFRlB0WXpjSmwva2p1cHg2c3R3PQ0KWC1Hb29nbGUtU210cC1Tb3VyY2U6IEFQWHZZcXlOSWhoUHJaOVdyOHdZVkFUYnBFSmw0OG0ra0tyajhzWHd5eDVranVRajA2T1VDZm4vK0dpaFJwN2FiQTE0djgweEFxOUpYZz09DQpYLVJlY2VpdmVkOiBieSAyMDAyOmFjMjo1NjA1Ojogd2l0aCBTTVRQIGlkIHY1bXI0ODUzODQxM2xmZC4xMzYuMTU3Nzk4MDEyMzI2ODsNCiAgICAgICAgVGh1LCAwMiBKYW4gMjAyMCAwNzo0ODo0MyAtMDgwMCAoUFNUKQ0KUmV0dXJuLVBhdGg6IDxtaWNoYWVsLmZsb3djcnlwdDJAZ21haWwuY29tPg0KUmVjZWl2ZWQ6IGZyb20gWzE5Mi4xNjguODguMjJdICgyMy0xMjMtMjA3LTgyLmlwLnVrcnRlbC5uZXQuIFs4Mi4yMDcuMTIzLjIzXSkNCiAgICAgICAgYnkgc210cC5nbWFpbC5jb20gd2l0aCBFU01UUFNBIGlkIHc5c20yMjkwNDQxMWxqaC4xMDYuMjAyMC4wMS4wMi4wNy40OC40MQ0KICAgICAgICBmb3IgPGZsb3djcnlwdC5jb21wYXRpYmlsaXR5QGdtYWlsLmNvbT4NCiAgICAgICAgKHZlcnNpb249VExTMV8yIGNpcGhlcj1FQ0RIRS1SU0EtQUVTMTI4LUdDTS1TSEEyNTYgYml0cz0xMjgvMTI4KTsNCiAgICAgICAgVGh1LCAwMiBKYW4gMjAyMCAwNzo0ODo0MiAtMDgwMCAoUFNUKQ0KVG86IGZsb3djcnlwdC5jb21wYXRpYmlsaXR5QGdtYWlsLmNvbQ0KRnJvbTogbWljaGFlbCA8bWljaGFlbC5mbG93Y3J5cHQyQGdtYWlsLmNvbT4NClN1YmplY3Q6IElTTy0yMDIyLUpQLCBQR1AvTWltZQ0KT3BlbnBncDogcHJlZmVyZW5jZT1zaWduZW5jcnlwdA0KQXV0b2NyeXB0OiBhZGRyPW1pY2hhZWwuZmxvd2NyeXB0MkBnbWFpbC5jb207IGtleWRhdGE9DQogbVFJTkJGejdsK2tCRUFDN0RPcGp2SjN3SUxXaFFGRVdmRFdualhaTEVmaWVpTFE2TlpYOGVqM0lHVUdhcElmNzFKOTljUUFGDQogYWtEa1gxTkYyQlZOUnhUcWp6UTR3eDZzdDR6eEFjd1RGS1htVmpJRFU2WE1MVkZBRWwxZVA1VnliWTBkdnY3dVlRTjhWY2hmDQogUXBiTHpPZkN6Nk9jMlgrSk5uSUlhS0tFY2FlNDZoZ2ZWK2VVOWt0RFZoUWdiMU9YSC9ueS84R0Rkd1FVand5c091QVI5MzY0DQogOWxueGlpYlpKTm1kN3FmeE1tak4xTHd6NXlHYW9QSEhuKzhpdCtveU14K3ozNlp0K3YySGU5c1JIdFBHSUVZMnJkRHN6ZEVSDQogV3YxZnRqSFlnMU8rcS9pckFQM3h6WjU3OGZaS2xhVHoyMDV6T1ZRaGxrV0l5WEExV3VqN3lqalByT2U0UUY2aGNKNGpHb042DQogWXZnVld4eHZxd2ROQUtCeFRRUEx5cWJyQWExbkgvc3ZudW9YNG1jem5nVzVucEJtNCtQU0JiTG8zQURCdTFib0doR2wxUWFFDQogdklHN0wrR3ZiOUl3M1p5REtTZXJ0QjBaUVo2SUU3ODJrL0Qwc1NiVDhtbmlZNUNyR08wb05hR3ZxckZ1YU9Fck5oR1E2ZkgwDQogR09VNDRXVnZZaVZYZGgzQ3lGUTkwUDBocG1sY05wU2hDTkVhQTk0K25lN0JYbU1KbnZBbDljUDk4Z2lBbVFsWHg0Y0d5K0pCDQogY3lDczVMZHR2Rm1sNS9EOTlwZDhvaW5DUVdXQXZqWkk2ZGlRRE5ya3cya1FWSHFhQ0JlclYyMWVCL2VlZTNhSU16dkN1cmNxDQogVERESmExQ0VvSFgzSU5WNGFpdnE0LzZZczZaNGk0dGlsRDB3aWNLemV6dTlFTkZjbVFBUkFRQUJ0QzlOYVdOb1lXVnNJRlp2DQogYkhsdVpYUnpJRHh0YVdOb1lXVnNMbVpzYjNkamNubHdkREpBWjIxaGFXd3VZMjl0UG9rQ05RUVFBUWdBSHdVQ1hQdVg2UVlMDQogQ1FjSUF3SUVGUWdLQWdNV0FnRUNHUUVDR3dNQ0hnRUFDZ2tRQUpJVlRJMUlJelZxVUEvL1VOZ2o2cHk3anV1aTBFd1BPd05GDQogSUM5cDQwcWFEdmpxZk5WZGZtY3IvMzlvZG04eXpkeC8wZVpUUklHWkRXQzNCQk01Z1NGRjlaTkdjVkZUTWUwTjNPWlpQeEdtDQogWTlYTjc5am9iZVZ2RTBXb0xFWkVISTlJWTg2SExBQzh5Yy9TZWlRc2JLcDZaaUp5RHVZNGdVUTA3eXE0QmMvSGZnVHlJVHNpDQogYW9GdldYRUhjTHV3MVpPaW1DcFFnMStYcUd3V2hBbk5oWEdGZTZ0dnc0MXVlaGFmUEVOKzhMai9OcU1yRlE1cVZPc2xYVVV2DQogdmtwZk52QW03TEJWSVk3OVlBZTVzdTFYTXVLY3J4Vy83blpCS2EzbWJGWWNuanRiVytMSnFjRWZBbDROTkRORDFobzdHdWxzDQogUDJKRnhseHkrWXFYSjZvRzg4SHhiNW1kbFZ5V1NrdUdHK0JZNzVEMWZnZW52NG50Wm91bUNkQ2FESWxLRk93ZkNGN0VUb1pYDQogdGVkU3l6czArRFJmaVZnOVlwOHczSUl4Rm4rS2hOM3gxMk5YdmtObStaT0MrSTdzYWMvYnZYN0tKM1RoVWYvQzFReXNicG1TDQogd2ZtbFNxazlTanRoYmRscldaMjBPRzV5dklpQ1MxQml4am8ybFRKTEE2UVNxUW1jTXdqZDVyUXJ1dDVHa1RIcXhuUVFiNDJ1DQogZU8rbi9HVjRjNngwUVQxaGZLVjd0aEUzVTdYUHZ6VUs1RThUaTlDTGtEZDZLRTRoQWN0MmpobEU3ellIclNia0puV0lVSW5yDQogUWVmUFEwRUcycUp6ZFpYbmlCWGoyT3J3azJVVnNlcnRrTEQzeTZJd3Y3WGs5cHAzelhXT1BLeEZLM0xibmZMd21JUUNkM1ZRDQogMTR1aC9oUjNhUlpmTi8yNUFnMEVYUHVYNlFFUUFLNy84VUttY3VUTkh6K21QZm9PZE1reGdkemlreDl6Z3dBU3ViYzJOaHEwDQogK2IrUDR5aVdPSmdibVVMTFhucFZFSDNJK1h5cWdjVWk0MndaM0tXeDA0V2JnMWRsc1NpTU4vOW9qZFhmaG4rSzJWNVFuclVSDQogbGdacnoyeExDY01OZ2JWcGRzTHY4dG53YjFySVFhcHEvYjEyUkpLVTlaQndYLzVXN3phOVVBandpYldnclZzRkNVUjVvbWxPDQogZTdaZzF6KzM3RG1JSVVHd25ETjduSEgrTE95Wnh1MlNUZEt4N0VaUTdnbHFpL1duRTg1ZG9SaWRBUnJNOWxQaWJHSmx4TFEwDQogWG5UcmdQa0tkL0ErRDZhaWRUUytOVVNLK0hTTE9Kek91V256OU1IRXhZdVFHL2YyV0NOVmFiQVlObklsOWZKRWNDZHV6L1NSDQogTGJ6eEg4aUwyNUgzcHRvbldhamhrdi92RnpmenpBRmhYTUpOZWhGUjZRdVpGbEJRQTA3OFN1UGI1N1pZZ1hCQThLUDl1TjJ4DQogMi9UZCtPN3ZUdVlBc255SHdoWnlDRnRMdE1QNWp5dCtPYlI4d1dXMU9yVlVWeE94dlc0emNNQmRDZnQwN0MwM2FJb09zdndBDQogRmllL2VKaHRlMmN6ZHRHUE44SWxVWk01WnRLb3A0WWVwaEl4V2Q0eVhxUGJ0UU51Q1FsellSYUxPN0E2djFsTGtLU3hJRVNiDQogWGJNZDVlejg2Sm9ocUZiU0xueEUzTzgrV2hMY1lFYTh2NnRQc0kxSGZ4a1VHWWV4V0o5UUJuRkt0VzVwak1Nb0p2MTdzOFd0DQogc2VralhtR2hzamU0NTJNYTdJSGZuRWNybTRwL0dPOUFGdlAwNitma1p2alBiMnJ0eGt3bUcyb01VcHRWb080M0FCRUJBQUdKDQogQWg4RUdBRUlBQWtGQWx6N2wra0NHd3dBQ2drUUFKSVZUSTFJSXpWT2dRLy9RVDVTcGoxNXkxMGJoU0NKWGM1YW1vUlVHL3lqDQogbGpyUExrUisrOVlpd3NVdmNaZ0tlc01LZ0twL2NxT1BtcHRENUM2NmM5b0cxRnl2SGNsWXVqa2kvU0tocG5ydVJLU252RFcvDQogbHBabllvMVFuTngxS2h4dTRYVGNqdHljQUtmaWpCVnV1Ui9tYVRvUjlEUDluNC81c2VINVRlTElHSmcrWVVjekw0SEkra0ptDQogOGlIYW5tUHhaUVI2OUNyMXhEQjlGd2xpTGw5QmFURmJzMGxXT2d1RWtxd2w4NEVBQ3VHUVRMT0dJNHUxRU4vOVJnQXg4Slg2DQogSnFBNWwxcnBsQzROOEhQZ0o2ekJwN3lkemRTb2ZveEdjdFNBVEpWbW93ZWVXd0w1ODVHZHNFMEZzK2NXVlNiOC90cUZYR0dSDQogL29COTVyYjVkMTY5dkY3dmJjYitoNlppZHNQWnFxbno4NU8yRWdJNUxrdXN5Q0crR2JLSWlhd2tCNTZRQTNOdFQ3Wm90QzJMDQogNkZWemIwMFllemtMTnUvWnRHcTZ2Vms3cXpCdzR6K2J1NnhVV0VKWVRiblZhMUthb3AzY3U0bVZsOHBmRVhRQWQ3V2NoZ2RNDQogVUxsbjJjZG1veE5pNjNyN2RVakVJdjZRSVF5c0NzZjdFanhGemt2bHc0VjRmWXJvZFdraXN1YW1kMUJxa1dMbEhuZUthcXgzDQogbnpWMzVvbWh2dlZOUXlBOWdxTUFreGFkSmhENFB4UzdLdlBHTmVqUXNtaE1FNE9vSTh5ZWcvaU9HUi9PVHBNaGsvcnJRV3RGDQogMndyQ0JFeGgyRUtPa1JDeDB4VnZ5T2pqU3RGRUtjN1NrdVk1TnI1RmUzNjVlbERrWFNyN0xtRWNqZFIxZmhGVjdjRzRUTE1lDQogeDZhUlhzQT0NCk1lc3NhZ2UtSUQ6IDxiMzc3ZDc0MC1kYTZiLWIxNTEtYTcyMC1iNDhkMmU5Y2I2OTdAZ21haWwuY29tPg0KRGF0ZTogVGh1LCAyIEphbiAyMDIwIDE3OjQ4OjQwICswMjAwDQpVc2VyLUFnZW50OiBNb3ppbGxhLzUuMCAoWDExOyBMaW51eCB4ODZfNjQ7IHJ2OjYwLjApIEdlY2tvLzIwMTAwMTAxDQogVGh1bmRlcmJpcmQvNjAuOS4wDQpNSU1FLVZlcnNpb246IDEuMA0KQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvZW5jcnlwdGVkOw0KIHByb3RvY29sPSJhcHBsaWNhdGlvbi9wZ3AtZW5jcnlwdGVkIjsNCiBib3VuZGFyeT0iekFBb2Y2QVFpM0t3MGpIM1dOZFJ2R0YzMGtDQ3ExcWp0Ig0KDQpUaGlzIGlzIGFuIE9wZW5QR1AvTUlNRSBlbmNyeXB0ZWQgbWVzc2FnZSAoUkZDIDQ4ODAgYW5kIDMxNTYpDQotLXpBQW9mNkFRaTNLdzBqSDNXTmRSdkdGMzBrQ0NxMXFqdA0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9wZ3AtZW5jcnlwdGVkDQpDb250ZW50LURlc2NyaXB0aW9uOiBQR1AvTUlNRSB2ZXJzaW9uIGlkZW50aWZpY2F0aW9uDQoNClZlcnNpb246IDENCg0KLS16QUFvZjZBUWkzS3cwakgzV05kUnZHRjMwa0NDcTFxanQNCkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtOyBuYW1lPSJlbmNyeXB0ZWQuYXNjIg0KQ29udGVudC1EZXNjcmlwdGlvbjogT3BlblBHUCBlbmNyeXB0ZWQgbWVzc2FnZQ0KQ29udGVudC1EaXNwb3NpdGlvbjogaW5saW5lOyBmaWxlbmFtZT0iZW5jcnlwdGVkLmFzYyINCg0KLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCmhRSU1BMHRhTC96bUxaVUJBUS8rSmdwbWtnc2NKRUI5dUFpRlQ2VGJlWnNCcUQvclJESW5hYjlPZXZyUkJXT1oNCndRN1V4UzRPa004TTFqb2ZsRWd0UDFaak5rQ0N1T0c1UlhSM0paRmtVZVFidnRNYzRtcHgrT09qWWJ3SHdOTkUNCjA1d2JjSUhuMzgwYXhOUFdNWXFlOC9pQ0s5d0ZXaE1Ed3RwRGZKMFB6TEtBaG5qRmh5bU1Xam1YQjJhdmVqYVMNCmlhS1FSZWxtVWlOdDVUazZGQXU4VW5PQWJyNyt1THZGQnp6anlFTEwzcEd6REJMa2F3aFVUMlFaMm5xckMxTnMNCko4SEVYbmwwVEJJNVQ5cmxLNWk2WVFpMmkyNlNXazhRa00wb3Y1T1dWSzFxSVNmMTVWSGVQNXVMWGNoM01mSHUNCkVmUUV1Ym8zNzhKYmthOVFNbzEvRS84dWJsR1FSZU1wc3Zicld0bzlIcWZQU1hVR2UzaFVRY0lSaTNuS3VRQngNCm5iTVdvbm5ORTdVRWhCRnl0TEwydytNbUJEbGtlUGE3ekRuZ09qUXdMcFlOVnZyeEpuQ2prNlNrY3JuK3gyMEQNCllrR3ppRXVicWhxdU1STHhKaHQ0VVRMdVJTTEk4ajFOdElSWjVROUJpKzFrclNKejUyN2NicS9JRkJVK0VtTlYNCmZDY1IxblliRjUvaHlUd0I3YVpReXhDVmxSV0tsWWZ3djQrN3E5Y2o1d0NCdUxDWTdaS3VjRWJ6b2RlaFJjRXQNCjRDOFR4ZzJLa0Q3LzgrVHQ2MEtjcWp2eUR0UWtRWU5TYXVidWdzRzJCQW1KcFlSVTZLRlZHRGxwTmU2Z0dFUUkNCmhuVlFxNVVhWjl6MERjZXZFMjVYcjdmZzJtTE43eUhSUlNhdXZPR2xNblA5OGQzZ0RsdVFsYnZBems1cU9NcUYNCkFnd0RxbjBNRzkrVUh5d0JEL3NIRjU4b2d4SzNrQWJJVGpBNDUzVTE1S2tSNGJBcWNIMzQzbVBmalBPUFR5QWINCjNJTW9ZYlFWOVNiSHVwdGF2NnQ5cmh0ckdFa05WdW5MUUxyR1lOYndyUXgyNTN5cWdOK2RSWUQ4bW4xMDF5Sk0NCkZjTjNSNlBEQ3hBTDRoVzBjWGpTc3BhcWUxbXg4VTdweitMbjFEckM0WDhPOUhIZ01yUHZVbDE4VWMxNGZBa3cNClptK3drNXZ6Vll4SHA4V3NRWGI5eHBlMWltbGV3N2pQdUhaa05TQTRrNllEb0duL3dwTjNtRU9LRTNCWXE2Um8NCmhuVGFhcEllK0pJenNhL0gwSFhLY0QwenRGZVJVRXl5amQrZEUzdmRKWWVoWnJFUUlqc00wb2NxYm41dGNmMVcNCjlEUDBPWEd5bFRmTmJCTVQ2UFE0TjVnZnlRRGV4dDlaM1FPVDBjM0hjbVVZSEpkODY1alI1blhIR3pzR1crVXINCmQwWjZBYUNzU0NQOFdQVU5peEx6Z0NkQjdFUTZaNVBCNGV0ajkrRm1LWXZFYkZpYU9yOWhyWTQ4bnkraU9KanENCnMwZHVkaGdaa0U4WHBBOWpjSmFHbk00VVpkRm5zc2lUeWRscWFGV1l3alZrOGQ0Q3NqcnNUeCtKTlJXT1NWSHkNCjlXQmJVRlFjMWVIMDFydjFzZkw0NjdFeXpoaDkyU0NmSG9vSE45bEx0RjJtRGg0M1pRdTBSZVc4YUJkN1J6SGMNCktKQzhFMHdjc2x6THFmRit4N3JoMFZ0NTRZM2kwUFM5SDlSRFdBVHNzQ3gwVjN5U3dibnhxbWU2eklhNXFLVU4NCmtiU3FrdWNtelpLbmFrc2I0NlMwekp5T0IrUVYvOG50WUVybUxzWDFwR0Z2UEZCbTArR1EveVFncFVpSmh0THANCkFXOGpLQ0ZNeVFCSGhCS3lHMGs4RG45ZjVtTzhyRTB4Rzk4Mm0rbkd3bE1LSnVubitpaXl6NTYxVi8yZWJiNWUNClJQQ2oxMlJVQUl6S2ljUHFSYVBDYVhoRXlEMzB5MXJEQ0hPN3ZwQ0IxQ2duYlZmUmNQdlRPT3VVbEdsck1ZV2ENClpsQXlyYzVSa0FpU0NMVUphYjlaVGYvL1QzNGRtUDFwMGJtSU4zTW53dTNYc2JFZFpub1F4cVBTbDBVeWZxaUwNCjRlNXVHZTJaYS9yeHlrTTlDdUcwZjh2dEZXc29OaEprVHVnZFpqZktVWmRueWZkc21aaE5iS2xKY3VCN3BydmINCjBHbDAvM2ZObnM2cXYrK1IvRUdOSGJaaFN4dy9xWlhHQndHYTBZN2h3d3NBMVE2T2JYZ25aQTFURHFGVWhGazYNCi9jRGE4RmxSRDFqajlyS3lldXd3THJ5UnkvTGhvcTFMTC9XVitPaVVCLy9TbGRHYUhrcVh2OStDSk5obU53RVUNCmlDNW1aWXloR0dic1ZjQnh1UWlnaWx5TXBEUUpKZmNVaXFmTjhLTCtOOElDcG51UEdnYU1ROTdTTGVIcTJNbW0NCmVoY0Vad1ZRWkdsQ25RSk5LbWhicXF4SkI3V21kQlJLVERpQnhFNXF6NXIzZ3JCLzV2K01ieU02RzZNeUFua1ANCkEvVUtYMFFVWnNQRFI0MVhWV2haUFREby8vWjZhSUtKd2xnQjNFOXZhazJKa0Q0L3BkZ3p5QU0yOEhPVFV5Si8NClNmQlZMZCsvanhISVZsbTFJYUxVQXp2SmpHME5GbFh2RDdQa3pzNXBYbVVmLy9iVGRGWE5BM3VoN1ZCU0dRTWwNCmthZXl1ZW1Rd2lXMlJheTR0WWJVcS9GQ3psKzg4NjJKQlk5OHczOG5hdHJBKytXTUxISW94MHJoTUlHL3ZveUsNClUxKzJLS2dFRDQxNE1zQzMwOWpuK1A2V0NaR0t0MzRCWFNmRHAvUmJnd1AzWDBRSXhTWU94dG1YOGZqS2xWUFINCjlGUG1rd0Z2SVlzRTE0TVNCMTZ5MnZ4U0V0OEpGS29HaFhSdVZ4bEdvWXV1WnJwRVJmaHlubmt3U0xrdzB6bG4NCk1OVVVpaHc5QWVQaXZpNkgwcXkrN0RwVXkrNDFDVzhueGt4L2RlUGNkYkFxODRZNzFGeWZNN2diTHUwNEVQWjANCmhUenpnU0xEU1d2TGM3dldSR2JxSTFlclFoZmFkUXdpVXpNZDBZQXlJbVdtbm0wMDNkeGZSTk5DMG9DWURFOFYNCjNRR0ZxT21yNEFxY2JNR0lXQkdpUDBMYWptZWhKRXYrOEdrSWt1RHdRUnRrZ2FBa0h3RE1pZ3VqRnRyYXFHRW4NCm1kdVltWUJXODhZRHNYRDlKdjI0ZDRQdDJDZTdQNGxjNERFQVUzdnFVTVpGZEl3SGFuaktTTnI4TzZhWFhkMGUNCndyRmpjNzF0VVROR0Ywc3VOaSs3NG9sMHJsUzFzZVFOaWlqdWxFVzUzbmdLOHo1YnJOU2QxTjU2SC93Y1l4ODENCnFTeWVxbkdZSHBoTmJwd2hCVHFIa1VSQmx3eWd4STIrQ3VNU1I5Nmo0OWtvOUFaWkhZbDZEQkFxSExLWVdIR2kNCnZxdnBHLysrRkZ5MEFNU3hqcy8vQ2U1bFRTM3kzc2tmbmVhWjlzZ0g3bytVWENKN09wK210TGRIR2puNg0KPUdBT1MNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg0KLS16QUFvZjZBUWkzS3cwakgzV05kUnZHRjMwa0NDcTFxanQtLQ0K", + "historyId": "1405869", + "internalDate": "1577980120000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-16ff09b1baca2051.json b/test/source/mock/google/exported-messages/message-export-16ff09b1baca2051.json new file mode 100644 index 00000000000..7fc8723494d --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-16ff09b1baca2051.json @@ -0,0 +1,134 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "16ff09b1baca2051", + "threadId": "16ff09b1baca2051", + "labelIds": [ + "IMPORTANT", + "STARRED", + "CATEGORY_PERSONAL", + "Label_8913178789750967510" + ], + "snippet": "", + "payload": { + "partId": "", + "mimeType": "multipart/encrypted", + "filename": "", + "headers": [ + { + "name": "X-Gm-Message-State", + "value": "APjAAAXc2Oakugn0C1wr5b228i6WIc85JK6I32KrV+H0YT3IA82bdNv+ ZkpOfZYN8hv/ulNLYgjHMWWVFNL/wyM=" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "References", + "value": "<1580289291228-c657eac3-e90d4c75-aeb60c41@gmail.com>" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "X-Pep-Version", + "value": "2.0" + }, + { + "name": "Date", + "value": "Wed, 29 Jan 2020 20:21:30 +1100" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.4.1" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "In-Reply-To", + "value": "<1580289291228-c657eac3-e90d4c75-aeb60c41@gmail.com>" + }, + { + "name": "Subject", + "value": "p≡p" + }, + { + "name": "X-Pep-Version", + "value": "2.0" + }, + { + "name": "Content-Type", + "value": "multipart/encrypted; boundary=\"508b4bf627c9138e40bb096a2f0b837f\"; protocol=\"application/pgp-encrypted\"" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "application/pgp-encrypted", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "application/pgp-encrypted" + } + ], + "body": { + "attachmentId": "ANGjdJ-t4z_rM_ipvCfEPnmjX-sy5iNW19GTbJSj9mEhLY6UxAswF4QDRCcdVehYqECo30MEMEYdNtq-FQJe-MMwvOjBDJXiQFRH04_SY28pg7Zfe2GM5MfgmDuxgb8qtAKEeIacESyIjPDkSXhTiHu23amNAR8R7Atv7hhnrp1texBq3hHEnGXfFgl-tWI1aeFXqz8DHSmWWRNQTx6eHBrq9S9HD_gNEPxXbmtuzTy4WLPcnlAbdcrfqgWuKCDXw_QxekhqPwX-lqmR2uDDS4GWyXc9odUt_3aZb5NHkbqByDSyLSp3T4ydmjIyBLYGJP-RT_UrsnqTKVI52eZhuXQiQmAOKiVOFySs_Z3S723WEzXqiIC4G_waliIU5ps", + "size": 10 + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "msg.asc", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream" + }, + { + "name": "Content-Transfer-Encoding", + "value": "7bit" + }, + { + "name": "Content-Disposition", + "value": "inline; filename=\"msg.asc\"" + } + ], + "body": { + "attachmentId": "ANGjdJ-pAfqIJg-y3Fk7lFzhr3PrQwBkEmnwizfqBCl_SvMb5bmxU7wib3104Mouj6fNxw8LFSlQyKP5J7wkETD9cKR-G5I1Gp8j0oRbhP2f-1Z0mD7zSyDuZVQ6-aY1mcfslQDTBKWz4k_xl-FXSBtujSIgcv3GzeQ1-t8c0j5VnQj0AmIPQ4KvqxtuLXolGVJroD1ubAZO6GppsMQnbpRliQv4HPKZooLAs3W7lT7tWh14FUOjt5o_vf25HpVET8YP9BaXUDyMUxySHW6KiysvTXHm87xw-GVylrlaLZ5moL3FFEEsEwV7peWINSuCpWseUbpd2NKk3WRvdAwLKkZp2o3XkoG81EuMUF1xiS6JOCDSGPVIGf8yptVo66M", + "size": 4167 + } + } + ] + }, + "sizeEstimate": 9733, + "historyId": "1406373", + "internalDate": "1580289690000" + }, + "attachments": { + "ANGjdJ-t4z_rM_ipvCfEPnmjX-sy5iNW19GTbJSj9mEhLY6UxAswF4QDRCcdVehYqECo30MEMEYdNtq-FQJe-MMwvOjBDJXiQFRH04_SY28pg7Zfe2GM5MfgmDuxgb8qtAKEeIacESyIjPDkSXhTiHu23amNAR8R7Atv7hhnrp1texBq3hHEnGXfFgl-tWI1aeFXqz8DHSmWWRNQTx6eHBrq9S9HD_gNEPxXbmtuzTy4WLPcnlAbdcrfqgWuKCDXw_QxekhqPwX-lqmR2uDDS4GWyXc9odUt_3aZb5NHkbqByDSyLSp3T4ydmjIyBLYGJP-RT_UrsnqTKVI52eZhuXQiQmAOKiVOFySs_Z3S723WEzXqiIC4G_waliIU5ps": { + "data": "VmVyc2lvbjogMQ", + "size": 10 + }, + "ANGjdJ-pAfqIJg-y3Fk7lFzhr3PrQwBkEmnwizfqBCl_SvMb5bmxU7wib3104Mouj6fNxw8LFSlQyKP5J7wkETD9cKR-G5I1Gp8j0oRbhP2f-1Z0mD7zSyDuZVQ6-aY1mcfslQDTBKWz4k_xl-FXSBtujSIgcv3GzeQ1-t8c0j5VnQj0AmIPQ4KvqxtuLXolGVJroD1ubAZO6GppsMQnbpRliQv4HPKZooLAs3W7lT7tWh14FUOjt5o_vf25HpVET8YP9BaXUDyMUxySHW6KiysvTXHm87xw-GVylrlaLZ5moL3FFEEsEwV7peWINSuCpWseUbpd2NKk3WRvdAwLKkZp2o3XkoG81EuMUF1xiS6JOCDSGPVIGf8yptVo66M": { + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCmhRRU1BMUhOU1UrenpqUUZBUWY5R0ZISXRuVUQ1QS8yQWJiaDFxd2RVZHNsOGkvaHNnUHdoT05lczJGSUt4VGcNCnNLOVFiWlNFQldoNEdQM3BQQWFNODROdldFSS9aRlBSNk95L1lFT2Frek82ODFvMm1rN21uZjZkb0duQXk1UDQNClVxT29SQ1l1TXh6aXlvb01zV213TnFRTGRhenYzYjVDa3BUMXVRakdqdzlubys0MDM4ZzJVWmR5Vnc0dzltL24NCks2NU9IZzU0NFBjUjN2dUxaVGlWK3VqUWl3RHNVZGRYWWNiRU91MmpaajMrd1Q2UVozVW9Bbmk0VkhRZ1NqQmoNCmFWQmdWSHBHbkJ2VGlNZi9WM3JFQjBidFBiQkgySTRwRTBaRWtsWEJDTDJzTUx6K0dQUW9nbzNGQ1RjVCtCcUwNCkxKNUFGRm0vaFhCTllnNFpYUmwrZ09oU2k5TnN3UGJReVdRMk9lSmREb1VDREFOTFdpLzg1aTJWQVFFUC9BNS8NClFxYTI2cWNwMXllTS9HQk5NWDdOZWFabzBSckNxdkJVaG83WTdud3V3ZE14cHlOOW1uRHpjSFBkZ3hlNDFPWjUNCm1LREQrZ2psN1JIQ2xFWkJGcFN4aGM3cGk0d0lpb2RsSVorR28zZzkvN1o3WEM3ZXJld25jNkJIU1RyRTVBSmENClcvcnl4c1JEcnI5RnpSMVAzYUhxc3NHWGZENEo3KzNCRkFTem5RS1BQYVM4ZStCajJpYjZaZEtDeVFMUkZIWmENCjE4UlpQRjZQcHJRNG90eStwcUI4SnY4WVRGQ1dRYVlRWWZWSkxnTzZwcXdaelJlT3djU3draXBJcmFNb0JTVm4NCnNxQWV1cDRCeU9WWVdtQWh4dk41SlA2MjFjSFBKYlJjUmdYcUM1K1J2U1c4SDBseE5WbGE3WDc1NVBoSDByZXQNCktqNEhSMW8xUEFKdVB0ZGgwSk1nMExTTGl1T2FIamZnMXc1UnRHRTdaeUQxQ2JuRjNFZkxSbVJUWTNjTFJkVlYNCkpCdktqNDFsU2QwRVN0bkd4QzJZYVJUYzUwZHp3RThaRi92VHpRYkhjNDY5QVl2Q09qRUNRVzRrWU5ndXNVaWENCmlwN2wweTJMWXRtN1MvV2tOS0NEb0ZGN2dWR05PZ3RJTTRuUmxtUHFwNEQydEFHcjM1MjNSZHpsUmE4a1FvcG8NCnFBSG1MclM3KzhIR0VTZ3psNDUyUGkyY3JtM0o4d09UbTNTeVpPRjJFZzdjeXZiQzc1dE5EV3pLNWl4czg4MVgNClNLTkEydGk1NkpZZDNNZzZRaStzcWRnSkxMdFhic0cwSkIxKzdHY0JFVmxkbUZCZDFWQWxNOGN3SnQ2Vk5iL3INCkRYNFNkNVhwRjlXeVFiUXVNOU5wMFFpMDRVQ3JzbnBsRzZaYWVKeFEwdXNCcjhpOVdLZ3I2RVpnOUN0Tk1EMmkNClJ0eDZ3c2pxYko5OG9NRnNEd0dUNHhhdUltVmVqOGZpWml5aUw0YUpXYjlSd0xUd2hOT2pkK2d2OUNjdzF6YUYNCkFiLzNFQ2MvNGsvUWd2UHpXbDBlcG9teVpNTmZZbnc2S1MvTGZZQVJ4SkMzY2tTRnhyZXZQQ2ZYMTk1MjhXVUMNCmRaODhiWEFqMUoya3RkRGVnTU5sYWx0ZGV2Z3o2dVArMWRBL0lZcnIxNjlBdU96MHFzR2h1WFlTcm9hMWtFaHMNCnZ2WUIvcFI1NWdtZS81VG91S0g4YmF3MXJLOHRDSHRuOE4vVWQwcGpyYzJQMTY5TFJ0NlNZb1ZxdnZ1ZVlLZGgNCjlycys4S01kcWx2enQ5OVFqOU9jYmpSSURlNFRhb0tjT2FTRmwyVWh1TURXVkhrZ0hEb0VmNEo1UHhiKzEySFcNCktheGtLQUlFWjdyT0M1elM3Rk8zUmZ4UnRRa1hROVRTWkdRbDFsUlk3OElKdURBOUpCeVVLcG1kN0x1Q01MSkwNCmpFNGI2bUZ4MmxLQ0JGd29EVnlQb3JyL2tNdmFBOGlkWVYvYmo0Z21pcWFWTUVMakw1OGxPbWUvTFJGRmtWNEYNClBYaWZYU2VaRzNvZDliekN3Ti9iai9WdjFJbFZMNXRtaDAvMEZYaW5VTTFMdklxNHdrNTZLdUR4Q0VNN0xjVHoNCkR5QnpSdCtXM3FHaUVlcTRnNk9LYitaTDZpenhCUVRWOVFXK0JGZTFvSEJ5dzlISWI0SFN0b2kyZzRwdFVEd3YNClYwYnZKcUJHWWZzVGthci9Vdy9tNXg2Q2NXMGhxZDBwZnpxVE1JYWg4N3ROcENnODdYVGwwRitDdDBaYm9ueTkNCnpLOUVtZXc0T0I4UWJWdWE0RWhRbGsxbEZUdzNrUXpzbVJLcHVGclBhYzR2REk4amx0eklmejYrQ3pOTkU4NW0NCkRNaVpVa1lTZ3Z1djZDUlYyZzFyYUFrVkd4L05ka0RkcmM3d3ZNMDk1QTNuYmZxblRiTFlaOTE2MldScm9DdUsNClc0MjhtenBaMkFCTHJSS1l3R3BFN2lTL0luWGp5aHJTb1dSV1hhSGJVcXB6OUpTK3VMaEtPdFd1b255OFQxdG0NCkdlekd2cVpHbnViY3VHa1JGZ2pFTER4c2daRzlHSjI5cjU2VVozSW1zTVhxMTQ4Qjl0NjN5VzhWYWZWUitKdnoNCnl3dXNhNUZnQU82OW5MRTM4ZUFXOFlwT2dSeTRzd2tvd0M1U28yT1dmQW9abFRWeFpwanBVU0RUd1hhNFVhZ3MNCnJuYWZ3WXRuVStSNGZGdDlGSW9jNlR5M0h2bXdWR0RWK2ZjTVBydnpBZkx1UGdqTlhQUzdsQjVCdVoyZm9QUVANCjE1OFdEKytRb28ydkRlVEU4SE9WcFpCYWs1OTVxSi9BMjdrTUpySFBxS0xjRTl0VldwbEoxNi9EVlg0Y2VDcy8NCkowdmlCdGFQQTE5SUhuQm1rS3lLdlgzVTVpWG5MbHdObHh3RWRBQ09OV2JEM1kvd2NwQUJ3emVRYURKbUZub1INCkRRNzdMdHZSSm9kbzM0QldMWXB4ODA0ZlZxaFEwWHlNYXV4M1Y5RWVJaG5UakZndVdRemUrQTNnQ1liS3BWdTUNClFCeEpzWmFnQk9XdHlWaTh1L0l1L3hmYVp6cisrek5QVTlDQ091RVFISzNINk9ZakJTV0xZT2RZRzZsMmlyVVANCjRBUkRVMFVLdVdyUkJRSXVwM3kxRVVKemRkNnpZWEJjNVkvVXJrMFZzaWtDellPaFh4QzlIOVczRm4wcFlDZnQNClc1UmxLM3A4eEtsUmFjSFRscDR3dEFDdkl1SWh3aEdEdlhGZTFpVTUzR2ZhS204WkZhSGNBN2NiRHBOVEV2azUNCnJNTy8wdmxWeEtteU9tZ3Rua0ZjZ3hkeWk2dndwNmhWTWE1OXRvUFlxdlpZaXRZUlBjeU9HeC8vQUlURENQSGwNCnlsVFFHbTlKQ2VHM2t0czhIQzA1TjJRWEtlVXhoakhvck93aFJjNmFuam1PZEJiYTl6KzZhSzRQdi9KcDU2OTMNCjI0dlZOQkllNEhsR21mNGZBYlBMaCtHNkdtTjdRQUQzejc2Ull1YlBtbEZGa3FxaElrRENjMWF3U3lTbnNiMDYNCjlaclMxa3pjbnpLOElmMmVqeUwxbi91SXgya29RcDNMUVR6WnlDdG9xOGhvN3liZEJoeFZLNVVmU3hiQW5Kb2oNCmdiN3VUSzFDNnFoN2lxZVl2cHR0OXRtY2FRS1BCT0xJazFjcFM5a1NjZlRIVHRkRTl2cW5hNzMzcngwa2pFSzENCmpsZElLd3h4aTVjYy9oZDNEZnNXUTRnSG9wclpkWGRpVU1MSnFRVHBEbVZ1YngydklpUkFhcmtNTnBkOGhzeTINCllGWFVmYS9HaU5sMmF4M1VJWDl6TURrYVBFU0JMY2pJY1VidS8wQzJZcERCQkxLaXd4bTZRRjF2Ym41eE9HZE4NCkZ0b3JhSXpXc045M3ZKc2thTkF6aTU0ZGQyR0wvQUlWTmcvaG9wRzA3QjZJd241WlZZSUJvY0FDNDBGbXVRejINCnlMcHBsSUdxZVE2V1NlZ1JmUm44ZHBiaWk4SUJwZ1lGcnhpQUQ3dWlDclo5eVAxN2h6L01oblhCZ0JCUzl3SWwNCnVyZlBhVGl0bUVQN1RhWVFUcHU5R0tQdE5qbVJFQzBQTitvVjdqdklvZkYxWjNzK0pTbldhWnZtTHByY3ZDcUQNCkxZcGxyK3ZDUGVNeXVTZ0x5QW5Ha21IQ2xpS1RHb3FGK0hRWVhsUE11UWN5b0E0MXJJY1FsVkN2K2xndXpTREYNClFOaEJtOE1LSTJ2YVBUbTBZN2hYZ3NEWjFzdFlmdEtDK3RpMGdlNHZjZWxoSkxpc0VZRWVFTUROZ29TL3crTHQNCmlsUlM4ZUppc3B5a0RXN0dXZE1vZzJMYTh3WlJlMFJIL2tjdWowNElaVGpZY0xNeHZtZ2s2ekNGT2x4eHlGN0kNCmNVSlQvcUtxMExzSHlNQUJ6aUVyU3NISkhpajFiT3c2c0NhUkVYdlRmNnRESzg2dk56dXlCSFRXVkdxcDFyWjkNCnl1aFJ1SjM2RWRienVWRWQwTjZaM1JYNFBRdUcrNHVlQmZoYmtmZ0xKckdKZFRmTk5ocFZYdWFqdjJpeEpkVTkNCmZWdDROUXIyekljZFY5WE5BZExSTHVoTFU1czVrbDhFKzJsQjQvVldlYjRaQTFvcTNoQ1VJcEpuWmdSSmdxU0cNCjgvWEQ5L2xaZHp2ZWloTWFJSlVSUUJXazJOYkduQUxRVnJrMkFqenNwQm9uTTJUYkg5VnVncXpXTlM2NkhVWWYNCkUxdE4weGUrYWhVaFBEbEQzR21wRTUvZ0JuU1V0K2tRTlptMVRPUDdnb2NzT3RlTEhmRzMxdUFiWFhBQ3NNNTINCjVCWCtQcnNuYVRvaG1YbmtGaGtxSll0RWpsc0hJMHJjVU5RZjArdWV1Y3RNeXNrYjgxTXhDcFA0YW9kcEV1TkMNCnRnRXF3aGdud2JpTDY4SlJhYW8zWjZ5N2xiZlJFdkowUDdnZXZuMGl3Z3RnZHJQMm5KZFM4ZVVOUXVtUkNZTXMNCm03cUtRMjhwOGZ1WjZmOTRvSU5IQW9PSk9lMXdNRDRqOXZSZnRQdEpVNnNLVDM5eW5IczJjeWxiWWtGQXFUT3oNCmkrUmhkUmJldUt5Yk1vRXgvU3hmb0VIaDdSQUJXek40REk5dzJXaGRIN0wwaEJ5dUJUMkdSb2NaRFRZalllcmgNCmFSclA2WkM0bWVlb29GekdudXJxZ0tJZEVkNWU3NmlZanFuVk1MMUUrdytDSlNSRHFoZ0c1NXo0NjVld1pCZHANCkZFQi95UT09DQo9Vk1lYg0KLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQ0K", + "size": 4167 + } + }, + "raw": { + "id": "16ff09b1baca2051", + "threadId": "16ff09b1baca2051", + "labelIds": ["IMPORTANT", "STARRED", "CATEGORY_PERSONAL", "Label_8913178789750967510"], + "snippet": "", + "sizeEstimate": 9733, + "historyId": "1406373", + "internalDate": "1580289690000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-1707b9c96c5d7893.json b/test/source/mock/google/exported-messages/message-export-1707b9c96c5d7893.json new file mode 100644 index 00000000000..719a0f94f7a --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-1707b9c96c5d7893.json @@ -0,0 +1,63 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "1707b9c96c5d7893", + "threadId": "1707b9c222f75ad8", + "labelIds": [ + "IMPORTANT", + "STARRED", + "Label_15", + "SENT", + "INBOX" + ], + "snippet": "-----BEGIN PGP MESSAGE----- owGbwMvMwMVYfy8j1GPd8g7GNXlJHCWpFSV6JRUlcSH3akoyMosVyhOLFVLzkosq C0pSUxTKM0syFNIL0rm4gISCrm5xZnoekEosys0vUtAtUkjLyS8Hq9VLzs8tSCzJ", + "payload": { + "partId": "", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Date", + "value": "Tue, 25 Feb 2020 09:10:23 +0000" + }, + { + "name": "Subject", + "value": "gpg: signed only but armored" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Content-Type", + "value": "text/plain; charset=\"UTF-8\"" + } + ], + "body": { + "size": 1027, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCm93R2J3TXZNd01WWWZ5OGoxR1BkOGc3R05YbEpIQ1dwRlNWNkpSVWxjU0gzYWtveU1vc1Z5aE9MRlZMemtvc3ENCkMwcFNVeFRLTTBzeUZOSUwwcm00Z0lTQ3JtNXhabm9la0Vvc3lzMHZVdEF0VWtqTHlTOEhxOVZMenM4dFNDekoNClRNck15U3lwZEVqUFRjek1BWWtwNk9uRHJPRHFaREptWVdEa1lwQVZVMlFKVlRoMVRtZWIzSExocHh0WVlRNWkNClpRSzVnb0dMVXdBbVlsOG13REMzeXFKM1JxWGVheDJuMTA4YjQyc2MrSTI5ekUxZkx2ZGdxMVR6M1pMMGEyWjUNClhTVERvYlh5b2lHbmo3NDhrLzhpWDdkSlljNUMrVFRtUE1YdFBtWUpLbWQ3Vjd2Mng2Njc1QmZSK20yNWVkbnINClBmRUI5ays0N2lROXlOc2d1OVRHOE5DL2hoY2NhbE1rVDFVVWN2N1YwN21XMlpSYmZ2U29wMVpTVS9iWG0zYy8NCjhuZCtaU2hmbXJIUVlNTWZlM1htaWxkbWJoczJmN1M2SThHK3lhbWhySDFYc25YS2xjL2NhNjNTNTNUVTd1NWUNCitYN3ZpbDk3elRjM2NEZ3RQL3V3NkdCNm1tVG84bXFsYjIwR3l0RzFMdVl6WmZ0UDU1WFlMN1h5TzVNOFJ6eDINClpjTEJQVHNmenM4bzZiZ3h0MGZCdWNJbGRzN256TE95S2xkK0cydSt1U3F6dWo5d2dwZU9TWDE0OWYrOHk3Ti8NCmhsNW5iWElvM3FMM1FYYVd3c1h2aDdmSVRWcDE1NS9ieFNYS1g2NWZ1TG1oK0VUMjRaOUM3VjhpR2Y5TTd2NzYNCnRJK2pTTlJ1N2NuQXR0eGxYNHRPR0hodHVNSCtUVThuTnYxY1BFYzFYL0gxVlJ2OTVtV2FibDNsUCtIVm1vdS8NCnJreU4xL3NXbDd0Uy9mWlAzdlZscDNNU1B2cXkvUDZUM1ZLaFhTWWRXRnpoeWJsQjZLaHF6QWJCdXVWZi8yYlkNCktSeDEyMzl2OXVack0zeUVaT2MwSnR6Tno3TGg3eGI2ZTg5dEluZTRibHg4MWFSVDdiODZZcm9VSEdmZTBQRjQNCnNIalJuUVdkbWVVMmtnY21IK0xVRWR4ZDRiSmd4L1NRd1ByYis2emllUTBtTGJEc3ZabTdnSEZQZXE1WlcrL2UNCkJVOC9jTmMyYmQ0OUtXcmRUOC96S3BKOUttdlY5dXo0QVFBPQ0KPXI4U28NCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg==" + } + }, + "sizeEstimate": 1384, + "historyId": "1405958", + "internalDate": "1582621823000" + }, + "attachments": {}, + "raw": { + "id": "1707b9c96c5d7893", + "threadId": "1707b9c222f75ad8", + "labelIds": ["IMPORTANT", "STARRED", "Label_15", "SENT", "INBOX"], + "snippet": "-----BEGIN PGP MESSAGE----- owGbwMvMwMVYfy8j1GPd8g7GNXlJHCWpFSV6JRUlcSH3akoyMosVyhOLFVLzkosq C0pSUxTKM0syFNIL0rm4gISCrm5xZnoekEosys0vUtAtUkjLyS8Hq9VLzs8tSCzJ", + "sizeEstimate": 1384, + "historyId": "1405958", + "internalDate": "1582621823000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-17b91b7e122902d2.json b/test/source/mock/google/exported-messages/message-export-17b91b7e122902d2.json new file mode 100644 index 00000000000..b1eda7f5a2e --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-17b91b7e122902d2.json @@ -0,0 +1,82 @@ +{ + "acctEmail": "ci.tests.gmail@flowcrypt.test", + "full": { + "id": "17b91b7e122902d2", + "threadId": "17b91b7e122902d2", + "labelIds": ["SENT"], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt Email Encryption 8.1.4 Comment: Seamlessly send and receive encrypted email wV4DeWfgCtVtdnoSAQdAczt+hbsxnSHPx74G4dlCg1FgCaur5a5UST3gyRGo", + "payload": { + "partId": "", + "mimeType": "multipart/mixed", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "multipart/mixed; boundary=\"----sinikael-?=_1-16302373515050.421932310810367\"" + }, + { + "name": "Openpgp", + "value": "id=07481C8ACF9D49FE" + }, + { + "name": "From", + "value": "ci.tests.gmail@flowcrypt.test" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Subject", + "value": "[ci.test] encrypted email for offline decrypt" + }, + { + "name": "Date", + "value": "Sun, 29 Aug 2021 07:42:32 -0400" + }, + { + "name": "MIME-Version", + "value": "1.0" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/plain" + }, + { + "name": "Content-Transfer-Encoding", + "value": "quoted-printable" + } + ], + "body": { + "size": 738, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgRW1haWwgRW5jcnlwdGlvbiA4LjEuNA0KQ29tbWVudDogU2VhbWxlc3NseSBzZW5kIGFuZCByZWNlaXZlIGVuY3J5cHRlZCBlbWFpbA0KDQp3VjREZVdmZ0N0VnRkbm9TQVFkQWN6dCtoYnN4blNIUHg3NEc0ZGxDZzFGZ0NhdXI1YTVVU1QzZ3lSR28NCnIxTXdMeTYyakNrRjYweHFOa2NFdXE3RDRISS9zUCs0bzdVajRqQ0xQVXZHa1l0VlVSUFFwYml6V3JFKw0KSFJxaW9kRmt3VjREZVdmZ0N0VnRkbm9TQVFkQUpSWjZZbmljbWUyOHNYZklHT3h4dlpmL1JZaEhHd2tHDQorQ09vbnEvdGFVSXdFZ1BTcjZMV2RUeWQ3QzV5eTdPRmFtc0UvUkhNRndnTHFJWU1wME1wQkh2b1c3YkkNCnN2TlJabkxRVFlWaHRscTcwc0FlQVgzY0kxVGE1MVRpVERiZ1BsMHFZdTN4aktraWxaU0NlQXNiSTVOUQ0KbldtRDZKZjdTNlQyVy81L3JXZ0FMMXlYWWNseXdHUU9ra2xodi9vS2pjTXJZZ0tGOC9RNWxBK3R5MkYzDQp4cFNubE1FL0hxaGF0bTVRekhHWElEOUZsdzlXYTFyaTRKMkpqQ205RVhhR0FVVVh0WmM1cGViN25SYjENClAxWi85aVlXemVRSUxqZm12YmFDNnB4MUNrVlRXcW5ZeW1vbmNkNVFaazl0Wk5HeGwzWGtIdWNITUQzOQ0Kc0FzdVQyUkVCaWJxbFdVeFd3bTBIUWI0RVpkaTFNNUdkQ3JaRFl6Sm8vcVZGYWxCS3dxVTV1bVhDQW9JDQplUkRvR2FYRU5GSS9JWHJEDQo9Z2tLcQ0KLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQ0K" + } + } + ] + }, + "sizeEstimate": 1466, + "historyId": "2625887", + "internalDate": "1630237352000" + }, + "attachments": {}, + "raw": { + "id": "17b91b7e122902d2", + "threadId": "17b91b7e122902d2", + "labelIds": ["SENT"], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt Email Encryption 8.1.4 Comment: Seamlessly send and receive encrypted email wV4DeWfgCtVtdnoSAQdAczt+hbsxnSHPx74G4dlCg1FgCaur5a5UST3gyRGo", + "sizeEstimate": 1466, + "raw": "UmVjZWl2ZWQ6IGZyb20gNzE3Mjg0NzMwMjQ0DQoJbmFtZWQgdW5rbm93bg0KCWJ5IGdtYWlsYXBpLmdvb2dsZS5jb20NCgl3aXRoIEhUVFBSRVNUOw0KCVN1biwgMjkgQXVnIDIwMjEgMDc6NDI6MzIgLTA0MDANCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOw0KIGJvdW5kYXJ5PSItLS0tc2luaWthZWwtPz1fMS0xNjMwMjM3MzUxNTA1MC40MjE5MzIzMTA4MTAzNjciDQpPcGVucGdwOiBpZD0wNzQ4MUM4QUNGOUQ0OUZFDQpGcm9tOiBHbWFpbCBDSSBUZXN0IDxjaS50ZXN0cy5nbWFpbEBmbG93Y3J5cHQuZGV2Pg0KVG86IEdtYWlsIENJIFRlc3QgPGNpLnRlc3RzLmdtYWlsQGZsb3djcnlwdC5kZXY-DQpTdWJqZWN0OiBbY2kudGVzdF0gZW5jcnlwdGVkIGVtYWlsIGZvciBvZmZsaW5lIGRlY3J5cHQNCkRhdGU6IFN1biwgMjkgQXVnIDIwMjEgMDc6NDI6MzIgLTA0MDANCk1lc3NhZ2UtSWQ6IDxDQU85Rlk5dVFHSFcyX3FBR0NlM054NGVWQ3hZcFRFWFc4WUpuOVpQdit6YUtERUJHWndAbWFpbC5nbWFpbC5jb20-DQpNSU1FLVZlcnNpb246IDEuMA0KDQotLS0tLS1zaW5pa2FlbC0_PV8xLTE2MzAyMzczNTE1MDUwLjQyMTkzMjMxMDgxMDM2Nw0KQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluDQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBxdW90ZWQtcHJpbnRhYmxlDQoNCi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLQ0KVmVyc2lvbjogRmxvd0NyeXB0IEVtYWlsIEVuY3J5cHRpb24gOC4xLjQNCkNvbW1lbnQ6IFNlYW1sZXNzbHkgc2VuZCBhbmQgcmVjZWl2ZSBlbmNyeXB0ZWQgZW1haWwNCg0Kd1Y0RGVXZmdDdFZ0ZG5vU0FRZEFjenQraGJzeG5TSFB4NzRHNGRsQ2cxRmdDYXVyNWE1VVNUM2d5UkdvDQpyMU13THk2MmpDa0Y2MHhxTmtjRXVxN0Q0SEkvc1ArNG83VWo0akNMUFV2R2tZdFZVUlBRcGJpeldyRSsNCkhScWlvZEZrd1Y0RGVXZmdDdFZ0ZG5vU0FRZEFKUlo2WW5pY21lMjhzWGZJR094eHZaZi9SWWhIR3drRw0KK0NPb25xL3RhVUl3RWdQU3I2TFdkVHlkN0M1eXk3T0ZhbXNFL1JITUZ3Z0xxSVlNcDBNcEJIdm9XN2JJDQpzdk5SWm5MUVRZVmh0bHE3MHNBZUFYM2NJMVRhNTFUaVREYmdQbDBxWXUzeGpLa2lsWlNDZUFzYkk1TlENCm5XbUQ2SmY3UzZUMlcvNS9yV2dBTDF5WFljbHl3R1FPa2tsaHYvb0tqY01yWWdLRjgvUTVsQSt0eTJGMw0KeHBTbmxNRS9IcWhhdG01UXpIR1hJRDlGbHc5V2Excmk0SjJKakNtOUVYYUdBVVVYdFpjNXBlYjduUmIxDQpQMVovOWlZV3plUUlMamZtdmJhQzZweDFDa1ZUV3FuWXltb25jZDVRWms5dFpOR3hsM1hrSHVjSE1EMzkNCnNBc3VUMlJFQmlicWxXVXhXd20wSFFiNEVaZGkxTTVHZENyWkRZekpvL3FWRmFsQkt3cVU1dW1YQ0FvSQ0KZVJEb0dhWEVORkkvSVhyRA0KPTNEZ2tLcQ0KLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQ0KDQotLS0tLS1zaW5pa2FlbC0_PV8xLTE2MzAyMzczNTE1MDUwLjQyMTkzMjMxMDgxMDM2Ny0tDQo=", + "historyId": "2625887", + "internalDate": "1630237352000" + } +} diff --git a/test/source/mock/google/exported-messages/message-export-18024d53a24b19fe.json b/test/source/mock/google/exported-messages/message-export-18024d53a24b19fe.json new file mode 100644 index 00000000000..352fdb9ba6c --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-18024d53a24b19fe.json @@ -0,0 +1,106 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "18024d53a24b19fe", + "threadId": "18024d53a24b19fe", + "labelIds": ["INBOX", "Label_35"], + "snippet": "テストですテスト", + "payload": { + "partId": "", + "mimeType": "multipart/signed", + "filename": "", + "headers": [ + { + "name": "Date", + "value": "Fri, 26 Mar 2021 22:08:51 +0900 (JST)" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Subject", + "value": "テストです" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "Mime-Version", + "value": "1.0" + }, + { + "name": "Content-Type", + "value": "Multipart/Signed; protocol=\"application/pgp-signature\"; micalg=pgp-sha256; boundary=\"--Security_Multipart(Fri_Mar_26_22_08_51_2021_147)--\"" + }, + { + "name": "Content-Transfer-Encoding", + "value": "7bit" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "Text/Plain; charset=iso-2022-jp" + }, + { + "name": "Content-Transfer-Encoding", + "value": "7bit" + } + ], + "body": { + "size": 30, + "data": "44OG44K544OI44Gn44GZCuODhuOCueODiAo=" + } + }, + { + "partId": "1", + "mimeType": "application/pgp-signature", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "application/pgp-signature" + }, + { + "name": "Content-Transfer-Encoding", + "value": "7bit" + } + ], + "body": { + "attachmentId": "18024d53a24b19fe-signature", + "size": 256 + } + } + ] + }, + "sizeEstimate": 1036, + "historyId": "1350094", + "internalDate": "1616764131000" + }, + "attachments": { + "18024d53a24b19fe-signature": { + "data": "LS0tLS1CRUdJTiBQR1AgU0lHTkFUVVJFLS0tLS0KCnFjZVUvaW5rd1p5YkFRQzNuZmpNOUEvaXRYMXE3d3p6YWpMbW5VZ0NDeXBxZWRheGdNT2J5S3ZVQlE9PQo9MGtORAotLS0tLUVORCBQR1AgU0lHTkFUVVJFLS0tLS0K", + "size": 256 + } + }, + "raw": { + "id": "18024d53a24b19fe", + "threadId": "18024d53a24b19fe", + "labelIds": ["INBOX", "Label_35"], + "snippet": "テストですテスト", + "sizeEstimate": 1036, + "raw": "RGF0ZTogRnJpLCAyNiBNYXIgMjAyMSAyMjowODo1MSArMDkwMCAoSlNUKQpNZXNzYWdlLUlkOiA8MjAyMTAzMjYuMjIwODUxLjE0MjA4NDkyMTM2MTg0MjU5NkBjZW5zb3JlZD4KVG86IHJlY2lwaWVudEBlbWFpbC5jb20KU3ViamVjdDogPT9pc28tMjAyMi1qcD9CP0d5UkNKVVlsT1NWSUpFY2tPUnNvUWc9PT89CkZyb206IFRvbW95dWtpIE11cmFrYW1pIDx0b21veXVraUBwb2JveC5jb20+Ck1pbWUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlwZTogTXVsdGlwYXJ0L1NpZ25lZDsgcHJvdG9jb2w9ImFwcGxpY2F0aW9uL3BncC1zaWduYXR1cmUiOwogbWljYWxnPXBncC1zaGEyNTY7CiBib3VuZGFyeT0iLS1TZWN1cml0eV9NdWx0aXBhcnQoRnJpX01hcl8yNl8yMl8wOF81MV8yMDIxXzE0NyktLSIKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogN2JpdAoKLS0tLVNlY3VyaXR5X011bHRpcGFydChGcmlfTWFyXzI2XzIyXzA4XzUxXzIwMjFfMTQ3KS0tCkNvbnRlbnQtVHlwZTogVGV4dC9QbGFpbjsgY2hhcnNldD1pc28tMjAyMi1qcApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0CgobJEIlRiU5JUgkRyQ5GyhCChskQiVGJTklSBsoQgoKLS0tLVNlY3VyaXR5X011bHRpcGFydChGcmlfTWFyXzI2XzIyXzA4XzUxXzIwMjFfMTQ3KS0tCkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vcGdwLXNpZ25hdHVyZQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0CgotLS0tLUJFR0lOIFBHUCBTSUdOQVRVUkUtLS0tLQoKcWNlVS9pbmt3WnliQVFDM25mak05QS9pdFgxcTd3enphakxtblVnQ0N5cHFlZGF4Z01PYnlLdlVCUT09Cj0wa05ECi0tLS0tRU5EIFBHUCBTSUdOQVRVUkUtLS0tLQoKLS0tLVNlY3VyaXR5X011bHRpcGFydChGcmlfTWFyXzI2XzIyXzA4XzUxXzIwMjFfMTQ3KS0tLS0K", + "historyId": "1350094", + "internalDate": "1616764131000" + } +} diff --git a/test/source/mock/google/exported-messages/message-export-1821bf879a6f71e0.json b/test/source/mock/google/exported-messages/message-export-1821bf879a6f71e0.json deleted file mode 100644 index fd4ad86fb7c..00000000000 --- a/test/source/mock/google/exported-messages/message-export-1821bf879a6f71e0.json +++ /dev/null @@ -1,118 +0,0 @@ -{ - "acctEmail": "flowcrypt.compatibility@gmail.com", - "full": { - "id": "1821bf879a6f71e0", - "threadId": "1821bf879a6f71e0", - "labelIds": ["SENT"], - "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt Email Encryption 8.3.1 Comment: Seamlessly send and receive encrypted email wV4DBQQnHrSzW44SAQdASAfSFmFf1F2NjOnjpPuSVUmgy+mtq9qzLrRy203g", - "payload": { - "partId": "", - "mimeType": "multipart/mixed", - "filename": "", - "headers": [ - { - "name": "Content-Type", - "value": "multipart/mixed; boundary=\"----sinikael-?=_1-16583266435440.5429396972265759\"" - }, - { - "name": "Openpgp", - "value": "id=E8F0517BA6D7DAB6081C96E4ADAC279C95093207" - }, - { - "name": "From", - "value": "sender@domain.com" - }, - { - "name": "To", - "value": "flowcrypt.compatibility@gmail.com" - }, - { - "name": "Subject", - "value": "Test attachment #3505" - }, - { - "name": "Date", - "value": "Wed, 20 Jul 2022 07:17:24 -0700" - }, - { - "name": "MIME-Version", - "value": "1.0" - } - ], - "body": { - "size": 0 - }, - "parts": [ - { - "partId": "0", - "mimeType": "text/plain", - "filename": "", - "headers": [ - { - "name": "Content-Type", - "value": "text/plain" - }, - { - "name": "Content-Transfer-Encoding", - "value": "quoted-printable" - } - ], - "body": { - "size": 2680, - "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgRW1haWwgRW5jcnlwdGlvbiA4LjMuMQ0KQ29tbWVudDogU2VhbWxlc3NseSBzZW5kIGFuZCByZWNlaXZlIGVuY3J5cHRlZCBlbWFpbA0KDQp3VjREQlFRbkhyU3pXNDRTQVFkQVNBZlNGbUZmMUYyTmpPbmpwUHVTVlVtZ3krbXRxOXF6THJSeTIwM2cNCnBBWXd3NTFBWVBSSFZZSGE3TE9mT2lzRGJGc3JXS3kzOERKUWpiaHJmenlJVy9XSVV3ZzRZQlhtc1o3SQ0KUzlPQUltVzJ3Y0ZNQTB0YUwvem1MWlVCQVEvNkFpcmxPSEdVL1lucjR6cFNBMlpSeTBDaGhGbHFuRTRvDQpwUTlrTUhndE51NndjNG8wVDBwM0VySWoxVHNSUm9UdDdRTFM0ZzhFemp1SDBHTWN0QlA4cWxMSFFrRFMNClF4bGgvaXZ1M0pGRWpXSU80N2psWDZJTmFIbXpsU080V0VqakNlUVJSRGlrT21tNVU0WWlqTC9NcmtoMA0KSytVMFlEc3JORjlha0VxR3NTRFdpemVRbXc4aDRyTVplckhBUmtkZFFGNzVRaDlKQzFrN3lWQTJodnBKDQpGQ0E3RDNodFhUK2ZPY1VBYlc3bzIrMEdZazR3a0M2OFRhL0Y0SWlwWVYwN1R0U0ttQWJvNTFOYWlWdHcNCklEMFJHK282Vnord0w0VzdvT1NoSFpaTllzZzlaS0hnNitNa1JwQitrZ3YyYzQwSkpWNmpsZTlsUVptaA0KTG1WMkwxbUxHeDhlaGkwS0hjNzV0Y0FCTmI4V0tYTmlQMkw1Q2tuSGtPaHYxTlBYdzNLZ052VlliN0tsDQpwdnJROGRlWjBqNk96K3V1NVRXZmI4ZFJZYjlNYVNHMmJwb1Uwa0ZwN0NKR3FPZmdQcUZIQUliSHdsWTMNCngrb2RNdXdUdHJHa2ozMTJ4anhJd1JaVXZkcm1UYzk4OTh4aVRDWDNpZDh5anJXd3gzUTA3MklscXZYVw0Kb2ZlRTVBelJQN2xiYkp5T05vTHlmNlEzaVlROUhTTS9ENVJ6cFFqZnY3SjNFNEZzNXBsM2phYjFhWG9LDQppaklPWFVBczJvdFdzWitDTWxzaUI4Wjg0ZTAvTHBSTzdudGtqOWtXRWZqY3pJNE1GYm9STHkzK2lCSjgNCkFVdkJKSlhpZTc3M0E5eVpDOWwrV0VoTWxxR0NGTFplZkhpSlk3Z0YxUERwRVVDVnB5bkJ3VXdEdmIxMg0KWVBhWmpjUUJFQUNhdWoyTEtYUk9NRnFGRFNSY1RGK2J0N1ZOS1VSVVQ1OHd6NUNwb3NRWFJGaGRwTXhrDQovUnVyRGV3VlNkYXI1MjVwNjJNNW1KYUxGUUxCZmhZa1h5OFVTbXo2WDllcjhqb3Fsb3lwcnAvMTVCL1ENClZUaHB5dUdlQmdYVmJMZXdmYVZSK0tSNEt0MllhVlQ0cUx4OUxpNVA5Y3VUd3R4SnBLOHdwdTNjd1JJdw0KQXJDWU9nbi9sVG1DSG04MXZCdjdGSmZkaC9GV3dDQVVZL3QyWXI0RTdHTjE5WDdxNm5RSWNsblcvUmZVDQpnQWhiSldSVk1OQWt0NmdQcWJ5M1VuTFZ2L1JiMC9MS1BQNyt5RUVtcWZ5M2RmZkw0VHBvMU1aUEhkNEYNCm4vcllnY1NIODRkWi94VDk0RDNza011cDc5UzRvcUFqVDBYYko2QlQ4cXVzSW9IRHhaelMyMnRwWExVZA0KajB1MXFFWjlKVlVRWVhKTERLYmtUUlNXWXp1emMzdXlyZ2RYd2UrRVNrb2RBcE1zRVpoUTVqRllzcHNYDQpCYktsYmNuRmROSWJ5S016VE0yMWlLWG90RmVsSnFZMHp5QzU4eldKNGpaZ1A3OGpaeFBING1TWkJYSXANCnF2UFRBZWpxK25Ub29mTVo3YTk5SHhPSU93L1llOHF1cWQ4TlJKU2VUVVdKRFFvZkpmaWpldXlIdW9BWg0Kakh5NDlaZk5uYmVobjQvNU5raVh6ckpoL1dzaTBaSGRad1pBMk16TkUrTFdtSkZOVERNT0tpaVJ2QktpDQpVN3EvSXpRdURuTVlySWFiUjZMWEZiRGlVZlRacTcxc3NPOVNFSS9JRGdHRmhJR0pxb1cvZHdNL1VHWVQNClFab284UnNtYmU1bFdmUkQvMFlSa05KNEZoSWVIYnlmeWRMQjRBSEJVdmpYWmdTZU55OVl5MFI5TDQ2MQ0KVFFGdHVHMjh5djR2RzVaTnorS1ZKZUtFT1VVYmtMN3hDWkdDTVlUc0ZmcGpyZEE0bWtGSDhIQjRia2xRDQpDSWRDT2tNbmJlSEdmSnc5em45ZDZRdFRkVXMyR0tRWncvYlB3bExYbDdQQW9wS0FjTmZDYzJnWTNDRzcNClFRSEcreEhwL1BNWFkxQy9kbHRUaFJJUkV6S2puejVDdndoV2FVb2JHaHhiL09pZ0tzQXlKV1FZbEsrYg0KbDM2UFVxU1lWNWc1YTdTeVdKZ1QxcmdMTEYrQWt0Vy9YMHJQYWRETkdiSSthWVhuMGRWcTRQb3VSYmZmDQpZSThmVmZOZmxQWk80aXFGclRBZnhYcXhXTjIxVkFpQ1k1dm5SMEpRck9HbUNqY2doZGcvWkFBQytqUjENCk4xU0dkVit4b21CMVpVb01KYnBTWW9MdEZWWGhuMmc0SUR1UmRucG1nNExFNkxBUng0VEhybFZtQU5wSA0KcitIWE9NcWNaM2t1QkNHSVRnUUN4bnkrZGh5MWdkUjF0WTNnaG9wUlZoK3IvYVU0R1FycHh6am5ZZnF0DQpKcHk3UUVqVzNYMmVhYlg1RHhyak1NSkZ1Q3AxSCtkUTFhWUc3QnhvMWhtNTBaQldBVk1DdnREakpWUHANCmlEYUM3UlJ0M1VYUnJJaDljQlJJdWlSbWxlT1ArZ1Z3RW1Dcjh0dXZadk1kZU9wZW5keExiM0k2Y1g2Vg0KajZJQ3lxYTJoMTBUWE9uNWp6dDc0Tm5wUG9tL1FGMlpyWGNGUzU5VmRCSVhEUnNubDFpYStVL1UyaERZDQpGbGc4MXVpRmZWSWhRWUJVM3lGekRMb1lYRWRoUTZHQ0RlNldFdmZwTnVzZFFDenl4QXFFOUVqN2d1alUNCmtSZTh0SWV3elYwamkvcEh6SHhDMnNYcGM1OXFSK2NrQkVRYnRuWXA5V3hnOSs3VFM0OVNVVlFaMElDdQ0KU205S1NHZjdkUmdrc1dsa1l4ak1BY0FZNFZBbUQ4K3NQckt5YWNqR2orUlpTTlkwTDZMQmw1bUpDU2FFDQovd0xjakFmcU1EWGVrNmVZU282UUwvbzgwcmF6RDJKT3czY3BaSXhkNU9lWXFuRmk2a0hGMDROTkpKODANCk9ETzRRVFpCZFVBSnVUV1Q3MXNIS2Z1cS9WY01CeC9XYVE9PQ0KPVpZdzUNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg==" - } - }, - { - "partId": "1", - "mimeType": "application/octet-stream", - "filename": "\"what\"'s_up%3F.txt.pgp", - "headers": [ - { - "name": "Content-Type", - "value": "application/octet-stream; name=\"what's_up?.txt.pgp\"" - }, - { - "name": "Content-Disposition", - "value": "attachment; filename=\"what\"'s_up%3F.txt.pgp" - }, - { - "name": "X-Attachment-Id", - "value": "f_SykdJPdZrAIeptyFOrGAjHhFMFVxIU@flowcrypt" - }, - { - "name": "Content-Id", - "value": "" - }, - { - "name": "Content-Transfer-Encoding", - "value": "base64" - } - ], - "body": { - "attachmentId": "ANGjdJ_LF_J2Ue8NzggJDwDFt5wDMoHy9of6PzbfeUzMiG2SdHlRK7UPNqXukXD0eheb0aDkTe-QPUCwMUwCEO46gBTSRMdS7URPoiyf1aZVQk0lNc-8u6WIZBSXOmqC8vGo-y6gzUMlfn-5AQCJAwYbqZptil9S22QXbmg-aDmEz4BC6K2CJsCSe-AKUeXNeTa2ZKupUknWPxKwzrOql-Su7OEbIjRPXUGOpgQ8MHa6QW8yBdOKeR0QV7Ajrad4WfV0FSK7l23x3KVOakgwaPov1b5QdFtDi7TMHJp8Txk7BfhZ_5jBY6u5_qaSxNKVw_HuL7uoImgYzzEDt0Afdwg6Zqj1u2qK2YQeC5Jm43qPF1TSh6XIU5V8RI6wmZWchrB6EpUYeTSHYuH8B2uU", - "size": 1220 - } - } - ] - }, - "sizeEstimate": 5445, - "historyId": "1366528", - "internalDate": "1658326644000" - }, - "attachments": { - "ANGjdJ_LF_J2Ue8NzggJDwDFt5wDMoHy9of6PzbfeUzMiG2SdHlRK7UPNqXukXD0eheb0aDkTe-QPUCwMUwCEO46gBTSRMdS7URPoiyf1aZVQk0lNc-8u6WIZBSXOmqC8vGo-y6gzUMlfn-5AQCJAwYbqZptil9S22QXbmg-aDmEz4BC6K2CJsCSe-AKUeXNeTa2ZKupUknWPxKwzrOql-Su7OEbIjRPXUGOpgQ8MHa6QW8yBdOKeR0QV7Ajrad4WfV0FSK7l23x3KVOakgwaPov1b5QdFtDi7TMHJp8Txk7BfhZ_5jBY6u5_qaSxNKVw_HuL7uoImgYzzEDt0Afdwg6Zqj1u2qK2YQeC5Jm43qPF1TSh6XIU5V8RI6wmZWchrB6EpUYeTSHYuH8B2uU": { - "data": "wV4DBQQnHrSzW44SAQdAx_uh3kOxES2zmWgsEKYqh70CTBLgQ6zTNCvaUKCs4R0wCcF9e2p5v5ryBphRD18X4gL9EPdgGp_7fEwMts7l1rweMSL1rEzfdumH7e89r-aiwcFMA0taL_zmLZUBAQ_8Cah5jC_hVfsSVEW8K1jIHr4pLON0_Z46bjl3mEaYlsapzNBqPuGCh6LXEOFtjIXdtesdvH4QDcocp2rUGvZfmOUZK9iupw-a6Xa2zvgPHCSghcKlzFTfhWTjhA9h2vXOgXIRlqb5ImmM5MVr6Bmdykth3IBbrZ_uPb58VBbKDi_HQoaSfr9QFTZys0cN6nfDFRr5LKlt0eqov69Jvs2ccOcWTTR8GGM57pPg7A32uf3vMBtTZmFnvVdbmnm9enDTZj87TgPVg5Vy1nYhfWicyDRwYMY-k0gJRNOfKM2oa0nDf6GXfs37SebvC2_aOLOa11lswP7Dx_ltOC9jTcrEM-Uy65OsRGAEIkFf6RMjTFborfreEyLpUMUr2PFG-3vuC2i3lWCseNpO8yDN3NMHzWrL7YjQ72MjanZVKGI0xjtGM5wYaEP2voCY0Rx83pTqHyphHWWlWxYMnp7kmIgnf4BnBIb2aC2z6EnfrlvhqmG3i3uiDxiL9-XVoK03hwSKJQsBlBgwYXWm6o0ABVTcjESpHfcDIwqU5C6aZz8E2CQX2T45poMHSzMSqOYZZjZdL2UP0ePsOU8ub0AqAX2W8NODjw2uY0dn0G1TKbxlHYK7wFc7SKh5ylWosF7CL7p7bk_JuoUMdOdwIg6lO_w-cR3u6BOGtj0EvW_1YFcwKe_BwUwDvb12YPaZjcQBEACtr2jO7A_CJyYlr_BzOf2MQOWNLdaxr2kbVKcs0X5XupI9m2u2e49s7Lp9IftxhOkEgvoQjF_E6-k8BkOrLfVU0o6DqcjsOfpNdHzFWWYhPvk7mizhaMWSfoibpS90IJibbhASsCPSv3bgfdgu2IhCCeMRZ1df66LrcP1qN7FE40iY7Yr9eS5SxLl_GXefEcTTD1ZkHXxhEXmoEzWl_kQOy_uYEcwoaN3t3LKiT010k0RJ898SNYVmS0UjEQAuIZSdzMn0Z133dEBBFOo05RkzxZenQ4YUiZhgUiFTRTpBl0BLm-y9XFq_SeAk7IHJP7ZyQncShck06USiVCGNsGjqLGeUgC4P-Zdp0SO1gKZEuuSNokJrFeR63pvhj4RdVLYUaCP1ly8r3WDURB7pWz8LYHpUS28hFpmVOXx-zIoYakcCJXqdmS6nyfAeCR-KXc2aOUn5Z8CZFrVbpTAeLAoSob4ZeCPnrnu0FKIvKeKDrnv6fHXD7-K5MXI5hHINqDgyvVQ0xXRuz0hoC5CKABSoHmpc_YIefZmTl8oUhF4LfIb63rsaQg1spaPdbEkBCdoK_QOI-x6YGPL2RI04Nz0ZFzDAwROSTBxPPDPXCIa8sixr4-CHBanDvE8u_3g2grya_LqzjuoAbvHK3FHOMTIL_PB3Uuu7Tgm3XtOAXGbHJdJEAYIt1UcNIYFCL-Fu8wTXF3NOj57ChQEykLe0z4rYfg5Y8mP82O9dqba-TpaEa4KFz6OUFYilVLJIMe9l16dSfa_tvtE", - "size": 1220 - } - }, - "raw": { - "id": "1821bf879a6f71e0", - "threadId": "1821bf879a6f71e0", - "labelIds": ["SENT"], - "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt Email Encryption 8.3.1 Comment: Seamlessly send and receive encrypted email wV4DBQQnHrSzW44SAQdASAfSFmFf1F2NjOnjpPuSVUmgy+mtq9qzLrRy203g", - "sizeEstimate": 5445, - "raw": "UmVjZWl2ZWQ6IGZyb20gNzE3Mjg0NzMwMjQ0DQoJbmFtZWQgdW5rbm93bg0KCWJ5IGdtYWlsYXBpLmdvb2dsZS5jb20NCgl3aXRoIEhUVFBSRVNUOw0KCVdlZCwgMjAgSnVsIDIwMjIgMDc6MTc6MjQgLTA3MDANCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOw0KIGJvdW5kYXJ5PSItLS0tc2luaWthZWwtPz1fMS0xNjU4MzI2NjQzNTQ0MC41NDI5Mzk2OTcyMjY1NzU5Ig0KT3BlbnBncDogaWQ9RThGMDUxN0JBNkQ3REFCNjA4MUM5NkU0QURBQzI3OUM5NTA5MzIwNw0KRnJvbTogRmxvd0NyeXB0IENvbXBhdGliaWxpdHkgPGZsb3djcnlwdC5jb21wYXRpYmlsaXR5QGdtYWlsLmNvbT4NClRvOiBSb2JvdCBGbG93Q3J5cHQgPHJvYm90QGZsb3djcnlwdC5jb20-DQpTdWJqZWN0OiBUZXN0IGF0dGFjaG1lbnQgIzM1MDUNCkRhdGU6IFdlZCwgMjAgSnVsIDIwMjIgMDc6MTc6MjQgLTA3MDANCk1lc3NhZ2UtSWQ6IDxDQUtidUxUcFpuQ09jS1plX0F1akxRT1lNWCt6b1c4dEF2aXRqOTBuOWJ3NHhqSkVkMVFAbWFpbC5nbWFpbC5jb20-DQpNSU1FLVZlcnNpb246IDEuMA0KDQotLS0tLS1zaW5pa2FlbC0_PV8xLTE2NTgzMjY2NDM1NDQwLjU0MjkzOTY5NzIyNjU3NTkNCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbg0KQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogcXVvdGVkLXByaW50YWJsZQ0KDQotLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS0NClZlcnNpb246IEZsb3dDcnlwdCBFbWFpbCBFbmNyeXB0aW9uIDguMy4xDQpDb21tZW50OiBTZWFtbGVzc2x5IHNlbmQgYW5kIHJlY2VpdmUgZW5jcnlwdGVkIGVtYWlsDQoNCndWNERCUVFuSHJTelc0NFNBUWRBU0FmU0ZtRmYxRjJOak9uanBQdVNWVW1neSttdHE5cXpMclJ5MjAzZw0KcEFZd3c1MUFZUFJIVllIYTdMT2ZPaXNEYkZzcldLeTM4REpRamJocmZ6eUlXL1dJVXdnNFlCWG1zWjdJDQpTOU9BSW1XMndjRk1BMHRhTC96bUxaVUJBUS82QWlybE9IR1UvWW5yNHpwU0EyWlJ5MENoaEZscW5FNG8NCnBROWtNSGd0TnU2d2M0bzBUMHAzRXJJajFUc1JSb1R0N1FMUzRnOEV6anVIMEdNY3RCUDhxbExIUWtEUw0KUXhsaC9pdnUzSkZFaldJTzQ3amxYNklOYUhtemxTTzRXRWpqQ2VRUlJEaWtPbW01VTRZaWpML01ya2gwDQpLK1UwWURzck5GOWFrRXFHc1NEV2l6ZVFtdzhoNHJNWmVySEFSa2RkUUY3NVFoOUpDMWs3eVZBMmh2cEoNCkZDQTdEM2h0WFQrZk9jVUFiVzdvMiswR1lrNHdrQzY4VGEvRjRJaXBZVjA3VHRTS21BYm81MU5haVZ0dw0KSUQwUkcrbzZWeit3TDRXN29PU2hIWlpOWXNnOVpLSGc2K01rUnBCK2tndjJjNDBKSlY2amxlOWxRWm1oDQpMbVYyTDFtTEd4OGVoaTBLSGM3NXRjQUJOYjhXS1hOaVAyTDVDa25Ia09odjFOUFh3M0tnTnZWWWI3S2wNCnB2clE4ZGVaMGo2T3ordXU1VFdmYjhkUlliOU1hU0cyYnBvVTBrRnA3Q0pHcU9mZ1BxRkhBSWJId2xZMw0KeCtvZE11d1R0ckdrajMxMnhqeEl3UlpVdmRybVRjOTg5OHhpVENYM2lkOHlqcld3eDNRMDcySWxxdlhXDQpvZmVFNUF6UlA3bGJiSnlPTm9MeWY2UTNpWVE5SFNNL0Q1UnpwUWpmdjdKM0U0RnM1cGwzamFiMWFYb0sNCmlqSU9YVUFzMm90V3NaK0NNbHNpQjhaODRlMC9McFJPN250a2o5a1dFZmpjekk0TUZib1JMeTMraUJKOA0KQVV2QkpKWGllNzczQTl5WkM5bCtXRWhNbHFHQ0ZMWmVmSGlKWTdnRjFQRHBFVUNWcHluQndVd0R2YjEyDQpZUGFaamNRQkVBQ2F1ajJMS1hST01GcUZEU1JjVEYrYnQ3Vk5LVVJVVDU4d3o1Q3Bvc1FYUkZoZHBNeGsNCi9SdXJEZXdWU2RhcjUyNXA2Mk01bUphTEZRTEJmaFlrWHk4VVNtejZYOWVyOGpvcWxveXBycC8xNUIvUQ0KVlRocHl1R2VCZ1hWYkxld2ZhVlIrS1I0S3QyWWFWVDRxTHg5TGk1UDljdVR3dHhKcEs4d3B1M2N3Ukl3DQpBckNZT2duL2xUbUNIbTgxdkJ2N0ZKZmRoL0ZXd0NBVVkvdDJZcjRFN0dOMTlYN3E2blFJY2xuVy9SZlUNCmdBaGJKV1JWTU5Ba3Q2Z1BxYnkzVW5MVnYvUmIwL0xLUFA3K3lFRW1xZnkzZGZmTDRUcG8xTVpQSGQ0Rg0Kbi9yWWdjU0g4NGRaL3hUOTREM3NrTXVwNzlTNG9xQWpUMFhiSjZCVDhxdXNJb0hEeFp6UzIydHBYTFVkDQpqMHUxcUVaOUpWVVFZWEpMREtia1RSU1dZenV6YzN1eXJnZFh3ZStFU2tvZEFwTXNFWmhRNWpGWXNwc1gNCkJiS2xiY25GZE5JYnlLTXpUTTIxaUtYb3RGZWxKcVkwenlDNTh6V0o0alpnUDc4alp4UEg0bVNaQlhJcA0KcXZQVEFlanErblRvb2ZNWjdhOTlIeE9JT3cvWWU4cXVxZDhOUkpTZVRVV0pEUW9mSmZpamV1eUh1b0FaDQpqSHk0OVpmTm5iZWhuNC81TmtpWHpySmgvV3NpMFpIZFp3WkEyTXpORStMV21KRk5URE1PS2lpUnZCS2kNClU3cS9JelF1RG5NWXJJYWJSNkxYRmJEaVVmVFpxNzFzc085U0VJL0lEZ0dGaElHSnFvVy9kd00vVUdZVA0KUVpvbzhSc21iZTVsV2ZSRC8wWVJrTko0RmhJZUhieWZ5ZExCNEFIQlV2alhaZ1NlTnk5WXkwUjlMNDYxDQpUUUZ0dUcyOHl2NHZHNVpOeitLVkplS0VPVVVia0w3eENaR0NNWVRzRmZwanJkQTRta0ZIOEhCNGJrbFENCkNJZENPa01uYmVIR2ZKdzl6bjlkNlF0VGRVczJHS1Fady9iUHdsTFhsN1BBb3BLQWNOZkNjMmdZM0NHNw0KUVFIRyt4SHAvUE1YWTFDL2RsdFRoUklSRXpLam56NUN2d2hXYVVvYkdoeGIvT2lnS3NBeUpXUVlsSytiDQpsMzZQVXFTWVY1ZzVhN1N5V0pnVDFyZ0xMRitBa3RXL1gwclBhZEROR2JJK2FZWG4wZFZxNFBvdVJiZmYNCllJOGZWZk5mbFBaTzRpcUZyVEFmeFhxeFdOMjFWQWlDWTV2blIwSlFyT0dtQ2pjZ2hkZy9aQUFDK2pSMQ0KTjFTR2RWK3hvbUIxWlVvTUpicFNZb0x0RlZYaG4yZzRJRHVSZG5wbWc0TEU2TEFSeDRUSHJsVm1BTnBIDQpyK0hYT01xY1oza3VCQ0dJVGdRQ3hueStkaHkxZ2RSMXRZM2dob3BSVmgrci9hVTRHUXJweHpqbllmcXQNCkpweTdRRWpXM1gyZWFiWDVEeHJqTU1KRnVDcDFIK2RRMWFZRzdCeG8xaG01MFpCV0FWTUN2dERqSlZQcA0KaURhQzdSUnQzVVhSckloOWNCUkl1aVJtbGVPUCtnVndFbUNyOHR1dlp2TWRlT3BlbmR4TGIzSTZjWDZWDQpqNklDeXFhMmgxMFRYT241anp0NzRObnBQb20vUUYyWnJYY0ZTNTlWZEJJWERSc25sMWlhK1UvVTJoRFkNCkZsZzgxdWlGZlZJaFFZQlUzeUZ6RExvWVhFZGhRNkdDRGU2V0V2ZnBOdXNkUUN6eXhBcUU5RWo3Z3VqVQ0Ka1JlOHRJZXd6VjBqaS9wSHpIeEMyc1hwYzU5cVIrY2tCRVFidG5ZcDlXeGc5KzdUUzQ5U1VWUVowSUN1DQpTbTlLU0dmN2RSZ2tzV2xrWXhqTUFjQVk0VkFtRDgrc1ByS3lhY2pHaitSWlNOWTBMNkxCbDVtSkNTYUUNCi93TGNqQWZxTURYZWs2ZVlTbzZRTC9vODByYXpEMkpPdzNjcFpJeGQ1T2VZcW5GaTZrSEYwNE5OSko4MA0KT0RPNFFUWkJkVUFKdVRXVDcxc0hLZnVxL1ZjTUJ4L1dhUT0zRD0zRA0KPTNEWll3NQ0KLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQ0KDQotLS0tLS1zaW5pa2FlbC0_PV8xLTE2NTgzMjY2NDM1NDQwLjU0MjkzOTY5NzIyNjU3NTkNCkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtOyBuYW1lPSJ3aGF0J3NfdXA_LnR4dC5wZ3AiDQpDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZSowKj11dGYtOCcnd2hhdCdzX3VwJTNGLnR4dC5wZ3ANClgtQXR0YWNobWVudC1JZDogZl9TeWtkSlBkWnJBSWVwdHlGT3JHQWpIaEZNRlZ4SVVAZmxvd2NyeXB0DQpDb250ZW50LUlkOiA8Zl9TeWtkSlBkWnJBSWVwdHlGT3JHQWpIaEZNRlZ4SVVAZmxvd2NyeXB0Pg0KQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0DQoNCndWNERCUVFuSHJTelc0NFNBUWRBeC91aDNrT3hFUzJ6bVdnc0VLWXFoNzBDVEJMZ1E2elROQ3ZhVUtDczRSMHdDY0Y5ZTJwNXY1cnkNCkJwaFJEMThYNGdMOUVQZGdHcC83ZkV3TXRzN2wxcndlTVNMMXJFemZkdW1IN2U4OXIrYWl3Y0ZNQTB0YUwvem1MWlVCQVEvOENhaDUNCmpDL2hWZnNTVkVXOEsxaklIcjRwTE9OMC9aNDZiamwzbUVhWWxzYXB6TkJxUHVHQ2g2TFhFT0Z0aklYZHRlc2R2SDRRRGNvY3AyclUNCkd2WmZtT1VaSzlpdXB3K2E2WGEyenZnUEhDU2doY0tsekZUZmhXVGpoQTloMnZYT2dYSVJscWI1SW1tTTVNVnI2Qm1keWt0aDNJQmINCnJaL3VQYjU4VkJiS0RpL0hRb2FTZnI5UUZUWnlzMGNONm5mREZScjVMS2x0MGVxb3Y2OUp2czJjY09jV1RUUjhHR001N3BQZzdBMzINCnVmM3ZNQnRUWm1GbnZWZGJtbm05ZW5EVFpqODdUZ1BWZzVWeTFuWWhmV2ljeURSd1lNWStrMGdKUk5PZktNMm9hMG5EZjZHWGZzMzcNClNlYnZDMi9hT0xPYTExbHN3UDdEeC9sdE9DOWpUY3JFTStVeTY1T3NSR0FFSWtGZjZSTWpURmJvcmZyZUV5THBVTVVyMlBGRyszdnUNCkMyaTNsV0NzZU5wTzh5RE4zTk1IeldyTDdZalE3Mk1qYW5aVktHSTB4anRHTTV3WWFFUDJ2b0NZMFJ4ODNwVHFIeXBoSFdXbFd4WU0NCm5wN2ttSWduZjRCbkJJYjJhQzJ6NkVuZnJsdmhxbUczaTN1aUR4aUw5K1hWb0swM2h3U0tKUXNCbEJnd1lYV202bzBBQlZUY2pFU3ANCkhmY0RJd3FVNUM2YVp6OEUyQ1FYMlQ0NXBvTUhTek1TcU9ZWlpqWmRMMlVQMGVQc09VOHViMEFxQVgyVzhOT0RqdzJ1WTBkbjBHMVQNCktieGxIWUs3d0ZjN1NLaDV5bFdvc0Y3Q0w3cDdiay9KdW9VTWRPZHdJZzZsTy93K2NSM3U2Qk9HdGowRXZXLzFZRmN3S2UvQndVd0QNCnZiMTJZUGFaamNRQkVBQ3RyMmpPN0EvQ0p5WWxyL0J6T2YyTVFPV05MZGF4cjJrYlZLY3MwWDVYdXBJOW0ydTJlNDlzN0xwOUlmdHgNCmhPa0Vndm9RakYvRTYrazhCa09yTGZWVTBvNkRxY2pzT2ZwTmRIekZXV1loUHZrN21pemhhTVdTZm9pYnBTOTBJSmliYmhBU3NDUFMNCnYzYmdmZGd1MkloQ0NlTVJaMWRmNjZMcmNQMXFON0ZFNDBpWTdZcjllUzVTeExsL0dYZWZFY1RURDFaa0hYeGhFWG1vRXpXbC9rUU8NCnkvdVlFY3dvYU4zdDNMS2lUMDEwazBSSjg5OFNOWVZtUzBVakVRQXVJWlNkek1uMFoxMzNkRUJCRk9vMDVSa3p4WmVuUTRZVWlaaGcNClVpRlRSVHBCbDBCTG0reTlYRnEvU2VBazdJSEpQN1p5UW5jU2hjazA2VVNpVkNHTnNHanFMR2VVZ0M0UCtaZHAwU08xZ0taRXV1U04NCm9rSnJGZVI2M3B2aGo0UmRWTFlVYUNQMWx5OHIzV0RVUkI3cFd6OExZSHBVUzI4aEZwbVZPWHgreklvWWFrY0NKWHFkbVM2bnlmQWUNCkNSK0tYYzJhT1VuNVo4Q1pGclZicFRBZUxBb1NvYjRaZUNQbnJudTBGS0l2S2VLRHJudjZmSFhENytLNU1YSTVoSElOcURneXZWUTANCnhYUnV6MGhvQzVDS0FCU29IbXBjL1lJZWZabVRsOG9VaEY0TGZJYjYzcnNhUWcxc3BhUGRiRWtCQ2RvSy9RT0kreDZZR1BMMlJJMDQNCk56MFpGekRBd1JPU1RCeFBQRFBYQ0lhOHNpeHI0K0NIQmFuRHZFOHUvM2cyZ3J5YS9McXpqdW9BYnZISzNGSE9NVElML1BCM1V1dTcNClRnbTNYdE9BWEdiSEpkSkVBWUl0MVVjTklZRkNMK0Z1OHdUWEYzTk9qNTdDaFFFeWtMZTB6NHJZZmc1WThtUDgyTzlkcWJhK1RwYUUNCmE0S0Z6Nk9VRllpbFZMSklNZTlsMTZkU2ZhL3R2dEU9DQotLS0tLS1zaW5pa2FlbC0_PV8xLTE2NTgzMjY2NDM1NDQwLjU0MjkzOTY5NzIyNjU3NTktLQ0K", - "historyId": "1366528", - "internalDate": "1658326644000" - } -} diff --git a/test/source/mock/google/exported-messages/message-export-182263bf9f105adf.json b/test/source/mock/google/exported-messages/message-export-182263bf9f105adf.json deleted file mode 100644 index 20b977551a0..00000000000 --- a/test/source/mock/google/exported-messages/message-export-182263bf9f105adf.json +++ /dev/null @@ -1,118 +0,0 @@ -{ - "acctEmail": "flowcrypt.compatibility@gmail.com", - "full": { - "id": "182263bf9f105adf", - "threadId": "182263bf9f105adf", - "labelIds": ["SENT", "INBOX"], - "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt Email Encryption 8.3.2 Comment: Seamlessly send and receive encrypted email wcBMAxKVyQ+A04zgAQf9E3HP4UlGo0W7zOWIIaDjWhtH/OGuKvw3j+UToZxs fbhdMw8z4j36k+", - "payload": { - "partId": "", - "mimeType": "multipart/mixed", - "filename": "", - "headers": [ - { - "name": "Content-Type", - "value": "multipart/mixed; boundary=\"----sinikael-?=_1-16584988408450.8002882430055658\"" - }, - { - "name": "Openpgp", - "value": "id=277D1ADA213881F4ABE0415395E783DC0289E2E2" - }, - { - "name": "From", - "value": "sender@domain.com" - }, - { - "name": "To", - "value": "flowcrypt.compatibility@gmail.com" - }, - { - "name": "Subject", - "value": "Test attachment #3505 (with %)" - }, - { - "name": "Date", - "value": "Fri, 22 Jul 2022 07:07:20 -0700" - }, - { - "name": "MIME-Version", - "value": "1.0" - } - ], - "body": { - "size": 0 - }, - "parts": [ - { - "partId": "0", - "mimeType": "text/plain", - "filename": "", - "headers": [ - { - "name": "Content-Type", - "value": "text/plain" - }, - { - "name": "Content-Transfer-Encoding", - "value": "quoted-printable" - } - ], - "body": { - "size": 1774, - "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgRW1haWwgRW5jcnlwdGlvbiA4LjMuMg0KQ29tbWVudDogU2VhbWxlc3NseSBzZW5kIGFuZCByZWNlaXZlIGVuY3J5cHRlZCBlbWFpbA0KDQp3Y0JNQXhLVnlRK0EwNHpnQVFmOUUzSFA0VWxHbzBXN3pPV0lJYURqV2h0SC9PR3VLdnczaitVVG9aeHMNCmZiaGRNdzh6NGozNmsramszOHU0SDQ5YUxvTFd5RGFSRjB0VmREYjYvYys3SGFvblBpMTJlajlEd0VKdg0KTDV3UWEvOHJhYUc1bWFPMFRPTjc1QytMSnQzdHBEcDJDWnpaVlp6bDJHVHBPb1hmZXp1RjNRVzRkM2NWDQpNS3JUMXZZbU1lMHlrL043Y0FPSTZVVjg0R2dJNU1JaTR6Z0h0aEdLMXMyNWxVOGg4RXFUZmhBTGN3KzYNClVqbTFzNm9ZYWNobDNXc09oQWF0SEN5cURYVE0rYkE2YTlFRUh4STkyRk9mVEFSRGpNaXJZVkdDL1h4VQ0Kb1R1VTdqNkwzSnFUVGNWQzBCY0duRGt2ZmVReGRlRGsxdGFIK0J0ZUtDa0ZSN1l3a3luU090Y3Z1Q0lTDQo3TUZlQTNsbjRBclZiWFo2RWdFSFFEdDlEOXdLLzN4YVdBbUJ0cnFLd0dtQWN3SytBdUo3cEFGT1FjOUUNClNERURNSWpwOTh2WkxwbmFCMC92WVl4MXlhUi9TVUMxSmdQc2g5RkRLd2MyanJsNVVuNWh6aEtDZkd6bA0KbnI4Qm0yN2tETUhBVEFNU2xja1BnTk9NNEFFSUFNTGFtY2FubVp6RG5RUnYwZis3UHE2MWtRVWxMeTJjDQpZZy9BSHhnZnFUeVhDK2pQOFAxYWxxc2VCQ29vZDR4azJzakRmbVJ2YVY5UGp6WURvT0t1SHQ5SktQei8NCk45MFdOV3ZMamVJWnpWWDIzcERDVGdzYW0vYkRBOSsvTkFjRUZtRi91M2gyNEN5TTYrbk1Jcm5vQ2plSg0KUDljS0orYXB6YXhHV1ZZRTlhQVovYno2ZmVjTC9JTlZGaStqK0NiOGV1WklQYWhNSkxLRXAydkFObmRCDQpqcVl1M1c5b0xLRm5INStuNjZNeEZ5NmNSMk9JUkdqVFUxc1h2RkEwcE1VN2FWSFBOUkNtV3JHcXJvWWENCmdJZDdDSW9UR3I5WUF4Q0FoK1ZLQWdvZHVZOXR2M2dLS09leHhYWEQwT1hBbXl3NnpmcmI4ZHo0bzVPYg0KVE1UV2pGeWVic3JCWGdONVorQUsxVzEyZWhJQkIwRDBEV1BLMDdiZXp1aS8wOTMwWmNJNGFhY1BjMU1xDQphaCtqcHdBamhsNE5LREI4T2UrL0ZRSHVOM1drUkZ0OHVtT1FQOGZmOHFMR2RMdVRsZ2V0ekFtcE9hOWcNCmpwV28vNTVEZUNPTU85UTViYkRTd084Qk10Z25PS3dYRUt3eGh2eUhxWTI4NngzV1d3NERPWEZBcUdWWA0KU2RjTGZIS0tOVjFaMkhmQ3hiMVZsemtiWGJobFAvbEw1UzlXSGMvWmo4aFFOUzU4dWFoNFE2QVRDTDZHDQo3YjhkUU5iSzZvdXVSNnl0cW1GaitVek1rU3oyL1QrN3hWMDFLZGFhMGxMNDZrZVFkdzJraXhsU1FQY20NCllkR1IydjRUZk5qTHV6dW5IVjdobjRjcUdwbm9HNzZtWkNXTmRPaFJlTFNVMHhZV0h6U1ZUT2h1WGY0eg0KalFlNFZsNDU5UFg4SGw1N01DLzRSQ2kzM05YVnMyK2dpQmpybmYybml2RHA1TE9RYWlvN0pES3dqRm1UDQpPbEh0d2J0S1kwckVOQ0JZMHRxNGM2dEdqR0V2MUNkMkJtTmFxeWZYbHhXRFZXUEdlQ2xpaDdVc0Z5RjUNCnFWeFlpejJWRjJwVDBrcEN6dzJmcHZZNHlsWmFEVjhFN2xLaTV0TklHRGZ6djg4Mlg5QmJxSFpkN05qRQ0Kcmk2dzZTTUJBY3RVOGxUQkdGYXBnZkxRajlRZWlmRlhkT004WmRKc1dNZnFURXVsUmpVTnVrV3BYYXkrDQo0a2RzZEl0djdWRStBNEpYNzk0eDFacVJ2R1ErUjh5L0xkd09ycjBOblFJSlcxaTAvZnFLWTluNnM2NGoNCkFZVWZRM05vQzc0Nk1rQ0lnblM1TnIwbmVVQVY5RGZlNDd5dStqYUMxR2VHWkdlWVhSKzR3Z0ZyQnc9PQ0KPUgwa1YNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg==" - } - }, - { - "partId": "1", - "mimeType": "application/octet-stream", - "filename": "\"what\"'s_up%25253F.txt.pgp", - "headers": [ - { - "name": "Content-Type", - "value": "application/octet-stream; name=\"what's_up%253F.txt.pgp\"" - }, - { - "name": "Content-Disposition", - "value": "attachment; filename=\"what\"'s_up%25253F.txt.pgp" - }, - { - "name": "X-Attachment-Id", - "value": "f_jgDgLdTNOIiQXMrKOffiaJhGpPoWmo@flowcrypt" - }, - { - "name": "Content-Id", - "value": "" - }, - { - "name": "Content-Transfer-Encoding", - "value": "base64" - } - ], - "body": { - "attachmentId": "ANGjdJ90Mhq2GnvXZGFL2K0XClki6eYxB94kw7Pdnq4Su3N_pg56ZZJ6np9JC6BqwU1Fw4bU3BHlwC4zqAs5pYhYa2clFLaikv-4ivwO-sxK4aEvIOWdnq3wDBXiD5hJKtiNEqoYl2vYVxrN-7c85_MY4bgVpYSuzLNP001_cckJWV3L3Aairne4eSSka3KfmjLf2NORrnX1usUW1nBka1Ie2vKf3t1T21EBXSFWIFQu4INg6s_hfAVv05ohoX9kGBxb03GsLyrFYpnfYSYYwDba90-2c105IzOMfuDxdOnZOfyX8jHCj1Qq9pwrX2qmkv8S_V2uH8awhPXc2-F5UXtb25XecGpzcXaXIp4qqjcUtnQCB1n5HMKxUTUvxdVtdy_P3SWIE_-pBuL_KXIy", - "size": 808 - } - } - ] - }, - "sizeEstimate": 3988, - "historyId": "2302597", - "internalDate": "1658498840000" - }, - "attachments": { - "ANGjdJ90Mhq2GnvXZGFL2K0XClki6eYxB94kw7Pdnq4Su3N_pg56ZZJ6np9JC6BqwU1Fw4bU3BHlwC4zqAs5pYhYa2clFLaikv-4ivwO-sxK4aEvIOWdnq3wDBXiD5hJKtiNEqoYl2vYVxrN-7c85_MY4bgVpYSuzLNP001_cckJWV3L3Aairne4eSSka3KfmjLf2NORrnX1usUW1nBka1Ie2vKf3t1T21EBXSFWIFQu4INg6s_hfAVv05ohoX9kGBxb03GsLyrFYpnfYSYYwDba90-2c105IzOMfuDxdOnZOfyX8jHCj1Qq9pwrX2qmkv8S_V2uH8awhPXc2-F5UXtb25XecGpzcXaXIp4qqjcUtnQCB1n5HMKxUTUvxdVtdy_P3SWIE_-pBuL_KXIy": { - "data": "wcBMAxKVyQ-A04zgAQf_eHoWWhNCd09l3jlb3I1PELK_HfEQHFCdTX3MDVN7MD_9kpmR4zvSBKPHb_r5HFxD4-h_6jA4nS25E2Dbk4lLJYtxAuMdCaVun74O4w55PG9FIpt3syokcaNa9kIoQijvy0q9sIqWdO4af7Brpi8-om92jN_52h_TFF1Xx-AxVzWCdIzY4lhaVugiZlCG35gFfM8sWuv9Nvl9DPWcQ4yKGv4u0jwsDlrmyekBuF6_HcOVJiggZKB7XLk9h15G8HiLADnNd7DZWCsUgsTJSqCgVQrYvWs8xHf9MFmTArIpJ_loAoh2p1wTaZiT6yQfVk6j2G6MXnPyQ8nIvKvz4d7kNsFeA3ln4ArVbXZ6EgEHQI0yF0YGdf8txeorJoo-jr7cex8lEZ9L7II6qCeKY7N2MBbaYmYCHw1kiehlM05QbuBkz6MvMEOwwY0sfs8-4hIgw1vGSCWVHl0D6J9_EdZO4sHATAMSlckPgNOM4AEIAIYXnXE2x3FqetiCjeRMuZaGQqWWRRpFCr9YHD8BCURrTw1DgGyOjE1D4UsLmKVjnydI5_pkQbEnPiGybVoLr2O7-XNqCSsn2VKwrw7YiKx0-9wNJALPvbjHpGP3T_fBfL57J5zZZVwEVOLkdJl3uiIg0luAATDfqb2bac8vBryDW3x4VfQw600Fk1SV0lasTMIkTvEsFtPLnC3IOHGwX_ZrD4x5Mf6H6PkI5_0sjuHRZA_EJDjUWb5B6la_-eGof5ZLdwpKHywQLNQ0O4XzeM9zkzW6ZK-DjYvzwdaZbgFV5eOTo2rLp399-Hg5Twgw21QRdezXqfj4fcITjViQXHDBXgN5Z-AK1W12ehIBB0AtnfILmB8nnpS5HiKYQzUZBu6gfEpgw7GL0MV_5Xg7djDD8enL2sQmnHuekqgifTaWyHaVPDQLpTj2U0DqwFPAxRpoWmiC4cdQidZQBxFO943SSAGhuv11Jw7r8dQUSG6_A4cVQNuyGhQvdV7orAuM-gIO9vhcGE_R9tFpHD8-UYMJrlFPuO4Ej6RxUCl7bKVbfGiQUXNJFq83xw", - "size": 808 - } - }, - "raw": { - "id": "182263bf9f105adf", - "threadId": "182263bf9f105adf", - "labelIds": ["SENT", "INBOX"], - "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt Email Encryption 8.3.2 Comment: Seamlessly send and receive encrypted email wcBMAxKVyQ+A04zgAQf9E3HP4UlGo0W7zOWIIaDjWhtH/OGuKvw3j+UToZxs fbhdMw8z4j36k+", - "sizeEstimate": 3988, - "raw": "UmVjZWl2ZWQ6IGZyb20gNzE3Mjg0NzMwMjQ0DQoJbmFtZWQgdW5rbm93bg0KCWJ5IGdtYWlsYXBpLmdvb2dsZS5jb20NCgl3aXRoIEhUVFBSRVNUOw0KCUZyaSwgMjIgSnVsIDIwMjIgMDc6MDc6MjAgLTA3MDANCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOw0KIGJvdW5kYXJ5PSItLS0tc2luaWthZWwtPz1fMS0xNjU4NDk4ODQwODQ1MC44MDAyODgyNDMwMDU1NjU4Ig0KT3BlbnBncDogaWQ9Mjc3RDFBREEyMTM4ODFGNEFCRTA0MTUzOTVFNzgzREMwMjg5RTJFMg0KRnJvbTogR21haWwgQ0kgVGVzdCA8Y2kudGVzdHMuZ21haWxAZmxvd2NyeXB0LmRldj4NClRvOiBHbWFpbCBDSSBUZXN0IDxjaS50ZXN0cy5nbWFpbEBmbG93Y3J5cHQuZGV2Pg0KU3ViamVjdDogVGVzdCBhdHRhY2htZW50ICMzNTA1ICh3aXRoICUpDQpEYXRlOiBGcmksIDIyIEp1bCAyMDIyIDA3OjA3OjIwIC0wNzAwDQpNZXNzYWdlLUlkOiA8Q0FPOUZZOXZITE5pPTdRaD1GeU9lTGhHTjRGVjNxYnZ3TUJlMEFURm9PajR6aE1mYUN3QG1haWwuZ21haWwuY29tPg0KTUlNRS1WZXJzaW9uOiAxLjANCg0KLS0tLS0tc2luaWthZWwtPz1fMS0xNjU4NDk4ODQwODQ1MC44MDAyODgyNDMwMDU1NjU4DQpDb250ZW50LVR5cGU6IHRleHQvcGxhaW4NCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFibGUNCg0KLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgRW1haWwgRW5jcnlwdGlvbiA4LjMuMg0KQ29tbWVudDogU2VhbWxlc3NseSBzZW5kIGFuZCByZWNlaXZlIGVuY3J5cHRlZCBlbWFpbA0KDQp3Y0JNQXhLVnlRK0EwNHpnQVFmOUUzSFA0VWxHbzBXN3pPV0lJYURqV2h0SC9PR3VLdnczaitVVG9aeHMNCmZiaGRNdzh6NGozNmsramszOHU0SDQ5YUxvTFd5RGFSRjB0VmREYjYvYys3SGFvblBpMTJlajlEd0VKdg0KTDV3UWEvOHJhYUc1bWFPMFRPTjc1QytMSnQzdHBEcDJDWnpaVlp6bDJHVHBPb1hmZXp1RjNRVzRkM2NWDQpNS3JUMXZZbU1lMHlrL043Y0FPSTZVVjg0R2dJNU1JaTR6Z0h0aEdLMXMyNWxVOGg4RXFUZmhBTGN3KzYNClVqbTFzNm9ZYWNobDNXc09oQWF0SEN5cURYVE0rYkE2YTlFRUh4STkyRk9mVEFSRGpNaXJZVkdDL1h4VQ0Kb1R1VTdqNkwzSnFUVGNWQzBCY0duRGt2ZmVReGRlRGsxdGFIK0J0ZUtDa0ZSN1l3a3luU090Y3Z1Q0lTDQo3TUZlQTNsbjRBclZiWFo2RWdFSFFEdDlEOXdLLzN4YVdBbUJ0cnFLd0dtQWN3SytBdUo3cEFGT1FjOUUNClNERURNSWpwOTh2WkxwbmFCMC92WVl4MXlhUi9TVUMxSmdQc2g5RkRLd2MyanJsNVVuNWh6aEtDZkd6bA0KbnI4Qm0yN2tETUhBVEFNU2xja1BnTk9NNEFFSUFNTGFtY2FubVp6RG5RUnYwZis3UHE2MWtRVWxMeTJjDQpZZy9BSHhnZnFUeVhDK2pQOFAxYWxxc2VCQ29vZDR4azJzakRmbVJ2YVY5UGp6WURvT0t1SHQ5SktQei8NCk45MFdOV3ZMamVJWnpWWDIzcERDVGdzYW0vYkRBOSsvTkFjRUZtRi91M2gyNEN5TTYrbk1Jcm5vQ2plSg0KUDljS0orYXB6YXhHV1ZZRTlhQVovYno2ZmVjTC9JTlZGaStqK0NiOGV1WklQYWhNSkxLRXAydkFObmRCDQpqcVl1M1c5b0xLRm5INStuNjZNeEZ5NmNSMk9JUkdqVFUxc1h2RkEwcE1VN2FWSFBOUkNtV3JHcXJvWWENCmdJZDdDSW9UR3I5WUF4Q0FoK1ZLQWdvZHVZOXR2M2dLS09leHhYWEQwT1hBbXl3NnpmcmI4ZHo0bzVPYg0KVE1UV2pGeWVic3JCWGdONVorQUsxVzEyZWhJQkIwRDBEV1BLMDdiZXp1aS8wOTMwWmNJNGFhY1BjMU1xDQphaCtqcHdBamhsNE5LREI4T2UrL0ZRSHVOM1drUkZ0OHVtT1FQOGZmOHFMR2RMdVRsZ2V0ekFtcE9hOWcNCmpwV28vNTVEZUNPTU85UTViYkRTd084Qk10Z25PS3dYRUt3eGh2eUhxWTI4NngzV1d3NERPWEZBcUdWWA0KU2RjTGZIS0tOVjFaMkhmQ3hiMVZsemtiWGJobFAvbEw1UzlXSGMvWmo4aFFOUzU4dWFoNFE2QVRDTDZHDQo3YjhkUU5iSzZvdXVSNnl0cW1GaitVek1rU3oyL1QrN3hWMDFLZGFhMGxMNDZrZVFkdzJraXhsU1FQY20NCllkR1IydjRUZk5qTHV6dW5IVjdobjRjcUdwbm9HNzZtWkNXTmRPaFJlTFNVMHhZV0h6U1ZUT2h1WGY0eg0KalFlNFZsNDU5UFg4SGw1N01DLzRSQ2kzM05YVnMyK2dpQmpybmYybml2RHA1TE9RYWlvN0pES3dqRm1UDQpPbEh0d2J0S1kwckVOQ0JZMHRxNGM2dEdqR0V2MUNkMkJtTmFxeWZYbHhXRFZXUEdlQ2xpaDdVc0Z5RjUNCnFWeFlpejJWRjJwVDBrcEN6dzJmcHZZNHlsWmFEVjhFN2xLaTV0TklHRGZ6djg4Mlg5QmJxSFpkN05qRQ0Kcmk2dzZTTUJBY3RVOGxUQkdGYXBnZkxRajlRZWlmRlhkT004WmRKc1dNZnFURXVsUmpVTnVrV3BYYXkrDQo0a2RzZEl0djdWRStBNEpYNzk0eDFacVJ2R1ErUjh5L0xkd09ycjBOblFJSlcxaTAvZnFLWTluNnM2NGoNCkFZVWZRM05vQzc0Nk1rQ0lnblM1TnIwbmVVQVY5RGZlNDd5dStqYUMxR2VHWkdlWVhSKzR3Z0ZyQnc9M0Q9M0QNCj0zREgwa1YNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg0KLS0tLS0tc2luaWthZWwtPz1fMS0xNjU4NDk4ODQwODQ1MC44MDAyODgyNDMwMDU1NjU4DQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTsgbmFtZT0id2hhdCdzX3VwJTI1M0YudHh0LnBncCINCkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7DQogZmlsZW5hbWUqMCo9dXRmLTgnJ3doYXQnc191cCUyNTI1M0YudHh0LnBncA0KWC1BdHRhY2htZW50LUlkOiBmX2pnRGdMZFROT0lpUVhNcktPZmZpYUpoR3BQb1dtb0BmbG93Y3J5cHQNCkNvbnRlbnQtSWQ6IDxmX2pnRGdMZFROT0lpUVhNcktPZmZpYUpoR3BQb1dtb0BmbG93Y3J5cHQ-DQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQNCg0Kd2NCTUF4S1Z5UStBMDR6Z0FRZi9lSG9XV2hOQ2QwOWwzamxiM0kxUEVMSy9IZkVRSEZDZFRYM01EVk43TUQvOWtwbVI0enZTQktQSA0KYi9yNUhGeEQ0K2gvNmpBNG5TMjVFMkRiazRsTEpZdHhBdU1kQ2FWdW43NE80dzU1UEc5RklwdDNzeW9rY2FOYTlrSW9RaWp2eTBxOQ0Kc0lxV2RPNGFmN0JycGk4K29tOTJqTi81MmgvVEZGMVh4K0F4VnpXQ2RJelk0bGhhVnVnaVpsQ0czNWdGZk04c1d1djlOdmw5RFBXYw0KUTR5S0d2NHUwandzRGxybXlla0J1RjYvSGNPVkppZ2daS0I3WExrOWgxNUc4SGlMQURuTmQ3RFpXQ3NVZ3NUSlNxQ2dWUXJZdldzOA0KeEhmOU1GbVRBcklwSi9sb0FvaDJwMXdUYVppVDZ5UWZWazZqMkc2TVhuUHlROG5Jdkt2ejRkN2tOc0ZlQTNsbjRBclZiWFo2RWdFSA0KUUkweUYwWUdkZjh0eGVvckpvbytqcjdjZXg4bEVaOUw3SUk2cUNlS1k3TjJNQmJhWW1ZQ0h3MWtpZWhsTTA1UWJ1Qmt6Nk12TUVPdw0Kd1kwc2ZzOCs0aElndzF2R1NDV1ZIbDBENko5L0VkWk80c0hBVEFNU2xja1BnTk9NNEFFSUFJWVhuWEUyeDNGcWV0aUNqZVJNdVphRw0KUXFXV1JScEZDcjlZSEQ4QkNVUnJUdzFEZ0d5T2pFMUQ0VXNMbUtWam55ZEk1L3BrUWJFblBpR3liVm9McjJPNytYTnFDU3NuMlZLdw0Kcnc3WWlLeDArOXdOSkFMUHZiakhwR1AzVC9mQmZMNTdKNXpaWlZ3RVZPTGtkSmwzdWlJZzBsdUFBVERmcWIyYmFjOHZCcnlEVzN4NA0KVmZRdzYwMEZrMVNWMGxhc1RNSWtUdkVzRnRQTG5DM0lPSEd3WC9ackQ0eDVNZjZINlBrSTUvMHNqdUhSWkEvRUpEalVXYjVCNmxhLw0KK2VHb2Y1Wkxkd3BLSHl3UUxOUTBPNFh6ZU05emt6VzZaSytEall2endkYVpiZ0ZWNWVPVG8yckxwMzk5K0hnNVR3Z3cyMVFSZGV6WA0KcWZqNGZjSVRqVmlRWEhEQlhnTjVaK0FLMVcxMmVoSUJCMEF0bmZJTG1COG5ucFM1SGlLWVF6VVpCdTZnZkVwZ3c3R0wwTVYvNVhnNw0KZGpERDhlbkwyc1Ftbkh1ZWtxZ2lmVGFXeUhhVlBEUUxwVGoyVTBEcXdGUEF4UnBvV21pQzRjZFFpZFpRQnhGTzk0M1NTQUdodXYxMQ0KSnc3cjhkUVVTRzYvQTRjVlFOdXlHaFF2ZFY3b3JBdU0rZ0lPOXZoY0dFL1I5dEZwSEQ4K1VZTUpybEZQdU80RWo2UnhVQ2w3YktWYg0KZkdpUVVYTkpGcTgzeHc9PQ0KLS0tLS0tc2luaWthZWwtPz1fMS0xNjU4NDk4ODQwODQ1MC44MDAyODgyNDMwMDU1NjU4LS0NCg==", - "historyId": "2302597", - "internalDate": "1658498840000" - } -} diff --git a/test/source/mock/google/exported-messages/message-export-1869220e0c8f16de.json b/test/source/mock/google/exported-messages/message-export-1869220e0c8f16de.json new file mode 100644 index 00000000000..0adec63e0e4 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-1869220e0c8f16de.json @@ -0,0 +1,105 @@ +{ + "acctEmail": "ci.tests.gmail@flowcrypt.test", + "full": { + "id": "1869220e0c8f16de", + "threadId": "1869220e0c8f16de", + "labelIds": ["IMPORTANT", "CATEGORY_PERSONAL", "INBOX"], + "snippet": "-----BEGIN PGP MESSAGE----- Version: ProtonMail wV4DeWfgCtVtdnoSAQdAPNQhPJG8if4F6R6Dneng7TfppSVPQYHsKYCqoKKD 9W8wDO6xf08jS+Sn7QJcs/N/5so8bfppkTmx9xgEly5JIhwyrcIGp7R/ClN6 0hW9YzzB0sHjAeNkIAPLOMRhW+", + "payload": { + "partId": "", + "mimeType": "multipart/mixed", + "filename": "", + "headers": [ + { + "name": "Date", + "value": "Mon, 27 Feb 2023 09:07:46 +0000" + }, + { + "name": "To", + "value": "ci.tests.gmail@flowcrypt.dev" + }, + { + "name": "From", + "value": "ci.tests.gmail@flowcrypt.test" + }, + { + "name": "Subject", + "value": "Inline signed and encrypted" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Content-Type", + "value": "multipart/mixed; boundary=\"b1_APtjrArD3xyvepenMGInm3lxJB3YfIvNBM8MvjwSkc0\"" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/plain; charset=utf-8" + }, + { + "name": "Content-Transfer-Encoding", + "value": "base64" + } + ], + "body": { + "size": 1154, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBQcm90b25NYWlsDQoNCndWNERlV2ZnQ3RWdGRub1NBUWRBUE5RaFBKRzhpZjRGNlI2RG5lbmc3VGZwcFNWUFFZSHNLWUNxb0tLRA0KOVc4d0RPNnhmMDhqUytTbjdRSmNzL04vNXNvOGJmcHBrVG14OXhnRWx5NUpJaHd5cmNJR3A3Ui9DbE42DQowaFc5WXp6QjBzSGpBZU5rSUFQTE9NUmhXK0F2WW41aEx3UXphZWNBK0pmbXZIY0pzWlZESlNVbGxTNUUNCk9ENnBUdUtHb0tVUEF1RGdpbkF5cXVvRlI4WlFOSVFwUUk5ZUt5U2JXMXpWemNMWmVsMS9XeEZ4VWdXZQ0KTndFMHhRUWl2Kys4Z0FWcUQ1UkJEZDZGdjY5RlpCMVBNbHc1QmpDaTdpQnp3VXZzZ3UwVW1nZFErZ1ozDQplSTZXMkxSTVZYUUNEd0t3OTcxZDBMMWpxNmZEYmtLTklYVHVRbEY4b2xXeVRmd20zK3BYdmdidVFCdEkNCmhkaW9ndWEwcElEQkdQbDlScmdENFNUcjJnTUJFMk8yWWVJZG5NQVVWZE5ZelVSOUFxYkpnQm5NdTU2Lw0KOHJkcS9oTFpRWEpyL3hzdTVEeUgxbkd1Z1JLU0Y2dDVkSlpZSkQvN1hNNENKWkJ6OHZrWENjcTdtTmdSDQp3MWsrMGZZVUJjeXNxWFFNdTNOWlo5OVU0NHQxY25WcW9KNnowblFHSmJLZGhIditFQTMxU1VpV3lJQnANCmxWOUVnTmViM0s4TG9KUE9icGdqVWswTjJuS0JhRXl4UDhRZ2FDQ1psajV6ZDVYbEtFRE5IdUMzR2kyUw0KbkQvYmt4Y2ZsTkhsWkR2MGIxWEdNcUlCZExEalVXTUV2ZXdzR3VwdFRBQ25IazR4SDB6MWVRckNNT3pPDQphbHkrYWY4anRFMVo4NDBMbzJRb1U3M2VEUjdaVCtlV2hOQ1hYVDNSZ2w2VmVSRWRteVp2VG1FTXVPMkINCmluTG91MU1JeWxoc1lPZC9vVzcwUW9OcUtMU3EzRG9nOElNM2pqaGpNN0s0ZEZBVFF0cnVaWC9BVXFRSg0KNG00VDZRclBEL21lOFR5SzBRV1Y0UzREZGJhVVVxUVViUndKa2hIN0d6VGxmSDVHNnQycnFmaWRyczhjDQp4bkVtSXZvVUc3Wkp0UEFtWW9USlRDZ24zOHc2SWMxVElMTWZKRFlQMWZkYjI5S25lZXpOSHI1QkwzR08NCndmbTZ1aTM3VGZTNmMvaFI2WDEvalB6dDQ0R09Yb3l0N0RnaFgvVXFYcTJ0cDJjcjFBTUhRWlEwSXFxTA0KdUpEakVhWHZpOHFzZStvRGdTWityaDRQNEsrL01vS1phdUZwOUtrYjZjd0VEU2JvUkxZSFFOYkdOL25xDQpQZkJYN0hDN1N6dXoNCj1WUGd5DQotLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tDQo=" + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "0xA5140005.asc", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream; name=\"0xA5140005.asc\"" + }, + { + "name": "Content-Transfer-Encoding", + "value": "base64" + }, + { + "name": "Content-Disposition", + "value": "attachment; filename=\"0xA5140005.asc\"" + } + ], + "body": { + "attachmentId": "1869220e0c8f16de-part1", + "size": 3291 + } + } + ] + }, + "sizeEstimate": 11617, + "historyId": "2491473", + "internalDate": "1677488866000" + }, + "attachments": { + "1869220e0c8f16de-part1": { + "data": "LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgp4c0ZOQkdQOGIxSUJFQUN2WTk1bkVZRUZDOUpFZVA0NzVCWTRGSERaSzhITE5TTWJ4c2tRZGNSYXV3eXUKNEpyVm5Yb3UvOFFmdEtaejNheVVGbEswbVJ5NWFHZytEMW1jTjJFRHVmd0E3ZnVPb3dHWk1yOVdxeE9sCm1SK21YL0I3eWM4RmZNTHNIWjhrOVQzRncrcy9QbTR0dEdBaHVBSUpkMEx5bzZZTGdaVGFoL0hNK1MyOApQUUhFcGZPQWdtYk52YjdXYUxRd2gwb1RNR01Mb3NYSENoOE5PdlNXOVRTNHpCK2JNaEVuZkY1MytYTTUKUlVac0RRU3M4cDU5aXRjbjdrVTNMNDVDSzhWamc2UzQ5bWlHcFo2eFBESitmS04vWmhMelRrVDVhSFZ2Ck9qVUpMQ0NYcFluRzh1cVUvMXhYTGRBTk0xRk5LSFRrNEV1dUdpSEZBNlhZZWlQVnd4L2ROdytJdmVQUgpjYmd0a0dvTWZkZXQ0eXdmVWZyRnlkRlV1WEhmNTlYSm9hUzB0azNuVS9nUkMwZlJnZVN3ZFFhbVoxaXMKeEFzeXBydDlwUFNIbVZWQ3lGRU95Qk5ELzhsaWxCOFpMNS8xYmxPQmdyWkdqMXpNUm5VSkhEanM2VGtQCmhBcXc5ZEw2ais0cE4ybzNnalVGY2JQQng5TGZiZldicnFhWk1Xd2tEYi95c0E0cFNDZUxCbkdZSXc3OApoRExjaWpDZStSSkxsdTJzbkhmUnFjQ0kyd2FiK01NVUhDMTF4VHA1bHpBNHUwZW9xdWZwK0xPdWREWHoKemF3c2RqeitvalJ4ZjBZaUVkNGpZVmtJOS9xUDRXVmtPM1FtSlBOV3JEdzNYRGpTU3Z3cHo1ZWxyRTBsCjI0cE9IMXBHTE4vNkNEWnAwaDF3TnRMaEVBWDBhSWYva2N5cGp3QVJBUUFCelN0elkyaHNaVzFoZW14bApRSEJ5YjNSdmJpNXRaU0E4YzJOb2JHVnRZWHBzWlVCd2NtOTBiMjR1YldVK3dzR0tCQkFCQ0FBK0JRSmoKL0c5U0JBc0pCd2dKRUdGdFdXdkNCbDFJQXhVSUNnUVdBQUlCQWhrQkFoc0RBaDRCRmlFRXBSUUFCVmRTCnRFKzU2Z2lWWVcxWmE4SUdYVWdBQUpzVkVBQ0N3TzkwaC9qZldLMEtKMjAzejlmUm5EVCtpWDFhaFRFbgpJdnpzR1VYd281b3BUSzhrOGZ6L3daRE5sOWl0cmQ5YzY1ZldPa2VpVllNMGpESU54ZUV2aFR3SndUcVkKeWljK3lmbm5IOUVNSUJsVUNkMzZkaCt4SUsyR3dkbXRkcVlCRHd5S3pPcVdHUlFiM3pFOUk2YUhhakk3Cnl6YUp5eEVCTHYybXJOSWQyVnRyejEySmJKSnY0Uk80RHYzc1pQSm9KZmJrdVY1eGc2dUVVdElrOWFBTQppRGROVWhrdzNKdlBxL2NLbmg2QUFIUEJTeHhWOGRSWE9UZ0lnZjVuY29YTm9keUd0YnBQemlzN0h4eisKNUt3b3lma0R6UVl0QUtWcFhSbHloK0YwNkM1alVDVXZtb0Z4Wm9INDBPZlNCcEhLY3U0RUtxSUJoMjhiCm9JMG9meFFDSVd2TWlZa2NmWWVLam53ZzI1TWRwWXZhdHhTNE5RVmVnenEwRGhpVkVpc08wY0t0S2F3bgpWR1BYVFVzZXZHc3dJQ3NKQlM5RFJ2M0ZNa0dKSURxUjFTL0UyR1daYTMrVTZBNFR3UHJjbXpmWHZ6cVEKK3Z4UGRxMDNmTUV4SUhlWWxjbmV4eXBGVU45Sy9MdExnWEVHMzQvTFhYSTlnTkJqeWZZVXdqTFpBdWVoCllxc01xTTA1d2FKM1psZ2JaRXNlUEswTE1mUk85ZzZscTdMc0Z0QjBxMjh1NUl3SzZNN0Zub3g1YnpRcgpoSURYQUZwVTRydzdHV1dLRjcxVWp3OXI2UDhyWTBSY1JhVzJSR2xZOCt0UXZ4blNIY0svS2k2b3psV1EKQ3Y1YmxIdXIvRW1UTzluZU84NGRIc3BDOGQ1R2d3djhxREZSNWRlb2htL1RMbGtoM2M3QlRRUmovRzlTCkFSQUF2OEFaZHNad1d0eEU3K05NWCtDQXVyaEZ3dkl4ZURPanJYZTVMZUJoeklFVVZYa1ROSXBmL3VkcQpCZkgzNExjZW1tb0I2cFBucGF4UzBHcmcvYThGTGs3VFJVMldrdWNybmJUOG51djlHaWhKQ3l1Y0M5Q28KNVpvVm1Od0lGcnhhU2tDNW9RdnNRb3l0VXlrNVRKOTVlZ1RzN3Fjc0lDb3VDcGNJSmZNK3NlTnRwYzI2ClhEV1ZyZitMM0ZXR0s0N0xCRXhIaFVySWJnRWlVakxmSHdDR1pFUXNjdGZUSXM0VzJQSmhmRi9lZ2lQRQpERExoZldnRFFBcGxacnI2dlpsQ3dQbUd5NUpZallNcTR1MzYzKzllVS9wM2pCYUswa0pnM08xS3ZEeG4Kb20vcDRvdUE2NFVia0I2NWdCVzU4WENFQ1dHSmkrQXNLVTRubUJUWHU2RHVGWlVTZWRMbDdMRW1tRnZjCkFIZDVQcDlXRnZuN1VLYWU3cVpSZExUOFFEbFJ1dG4xSWlWUUxubG9jSTNkSFMxQXcwdXpiYzgra2RFOApTTmJEQlpZa0xiN2ViK2FMc1F0U2VnQ3UyMSt5SWZNT0JjQlNvUWE5dUIzTDlaQzF4dm9vR3pXS1djQ1AKakV5a1FjM2FrcUFDSEdBc1hYU09Xdmxmeng0ZHI5b0RRQVNvcWRRZFpiM2ozdkROcVlZSzAwQUp5UTlSCmN6aWM0dHFEbmdVWDhpblRTQXN3a2VRL04vWklUSTJZM2x3RDBLRi92WVRPU2w3U0swd1ZMSFp5NTROWApWaVpjdVJKd1l6cVBvQnBmajJJTEdUYTVvL1duVHpXQVFsK0hIbEQweFhoc0xDMEVleWlLTWtCaTBYLzAKTW9IcmRFdnd2alNWSUg3bUdvKzFoQzJQaXBFQUVRRUFBY0xCZGdRWUFRZ0FLZ1VDWS94dlVna1FZVzFaCmE4SUdYVWdDR3d3V0lRU2xGQUFGVjFLMFQ3bnFDSlZoYlZscndnWmRTQUFBbGZBUC8xTXN6T0toa29xUQpLNkpRSEt5ZkJ4WGsrTUtocDFUVEF3dHorMVgxT0FPa3JtLzBRaTlTOGtKVTFMTFFVWFFXQ05Bc1lNN0gKODRsTGZ1OVhUdUhtMzkvUWh1cFVManQxU0F6YzlIZnJpMDBpU2ZXQkI3ZGlKWDZVTWpSTU9BdU5waUorCi9uS084bTdRSnA2MXR2V2R4WUpVQVhvSjBuaVpzblhrMktrSkpIdGNlcVZGR0l1Vmp5RlpWelozWjJJMQpRVk9BOHJ4TVo5YlNwbmx6SkZiSGl5Rm1tQXhMam4wVXNyL3dES09QT3ViYVZndDMrVlZvbjZpNE1XUG4KQ2dKK0t5dVhJOE9tOTl2UkkzL2QvZkgwWnJCZUsxVnljOHYyVFRYdFpIdE93cHFjekRuMEpENHQrVi90CnY1MTJjTWVYR0hqWDFmMGJORGtlUko3Y3p5WDkyRmJ5TGhlUHVDZzNveEV2Qjd5a25TT3pPMEIvZ21HYQpyQ0JzM01sdGtFM2ZTOXA4aGFhc2pCWDFRTGRrUUFDNHZUMzFCSXJoeUZGYlF4bkJlRkd3L1BLMFJvZ2EKM2dVSDRXUmtZMjR4ZEo1Wk9rdGo3RjZ5NW1oeHY2OXhiYUpldDRXQi82TUdtMzZaYzlNMFQwdGNKbHJHClhUWEZFdy9Qd1JCMVFKbHVNL0t4bGlMMldjSFNwcjFyZ1JER0JtR0NPR1lZclBramlIdUJvM0pxc1ZtMApXTkE1c05RS3hnN1BPKzc4V2RLOW5EQ2w4WlZpbVdMb3daUjc3NkVoUThuQ3FuOGNraWs5WStBbEpMUVkKbVpqL25wNE5oaWZvYklqdzRNR2NmOGgyWU9xNmZXaGh5WlFLazFJT3hWdjB3Wm5xeWpjSHAzL0hxbEVxCmRVRGRsRE5HWWFNTgo9ZWZDbgotLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0t", + "size": 3291 + } + }, + "raw": { + "id": "1869220e0c8f16de", + "threadId": "1869220e0c8f16de", + "labelIds": ["IMPORTANT", "CATEGORY_PERSONAL", "INBOX"], + "snippet": "-----BEGIN PGP MESSAGE----- Version: ProtonMail wV4DeWfgCtVtdnoSAQdAPNQhPJG8if4F6R6Dneng7TfppSVPQYHsKYCqoKKD 9W8wDO6xf08jS+Sn7QJcs/N/5so8bfppkTmx9xgEly5JIhwyrcIGp7R/ClN6 0hW9YzzB0sHjAeNkIAPLOMRhW+", + "sizeEstimate": 11617, + "historyId": "2491473", + "internalDate": "1677488866000" + } +} diff --git a/test/source/mock/google/exported-messages/message-export-1882fa9e2b996242.json b/test/source/mock/google/exported-messages/message-export-1882fa9e2b996242.json new file mode 100644 index 00000000000..0e733c9d668 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-1882fa9e2b996242.json @@ -0,0 +1,92 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "1882fa9e2b996242", + "threadId": "1882fa9e2b996242", + "labelIds": ["IMPORTANT", "SENT", "INBOX"], + "snippet": "-----BEGIN PGP MESSAGE----- yMCxATvCy8zAxHhitbJOfXrcEcbTKkkMIOCRmpOTr6NQkpFZrABEiQolqcUlCrmpxcWJ6alchw5U sjAwMjEoiymyhJfeapohyXRUYeazxTBjWJkSeOtDWJnBRnFxCsDEv33mYDjmdsuGPyx68g7tMwe3 tqlevvUo5EIap+", + "payload": { + "partId": "", + "mimeType": "multipart/alternative", + "filename": "", + "headers": [ + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Date", + "value": "Thu, 18 May 2023 19:20:42 +0300" + }, + { + "name": "Subject", + "value": "SHA1 test inline" + }, + { + "name": "From", + "value": "sha1@sign.com" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Content-Type", + "value": "multipart/alternative; boundary=\"0000000000009dfa5f05fbfa2faa\"" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/plain; charset=\"UTF-8\"" + } + ], + "body": { + "size": 575, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCnlNQ3hBVHZDeTh6QXhIaGl0YkpPZlhyY0VjYlRLa2tNSU9DUm1wT1RyNk5Ra3BGWnJBQkVpUW9scWNVbENybXB4Y1dKNmFsY2h3NVUNCnNqQXdNakVvaXlteWhKZmVhcG9oeVhSVVllYXp4VEJqV0prU2VPdERXSm5CUm5GeENzREV2MzNtWURqbWRzdUdQeXg2OGc3dE13ZTMNCnRxbGV2dlVvNUVJYXArd21abTZtUlhjT0dCcGx2SnkxbWZ1cTFwbHJ0MDhxczk3WTJ6dEIrL1hidXlHM0lyNDh1N0kzcG1EK1RXYWUNCldTZDVkMjZRWVhjdXVzYXVjMFh5L2ZTMS9GWGJQSmFZSGxDZU1DZm5ockY5ZDJqeUgzM1YrZXI2cjNsUzVpL21jaE9LZmZwZ2xrdFQNCmQ2WjM2Ly9Nc21jek4wMFdkNjB0OVQrcXlMejBUNC9VRzJZOWxnZjM2N2YzZCtrWVBFMExTN21YdUZtamxQWGZ3MG5LeVZzU2VGaXUNCjNkdXorVmZ6VTNIVlo2NUw0eGM1UEJZd1dMbHNoZGNHOTRWVHQyb0szY3VMQzV6dXkvM2tzMHN3MStNR3ptS3RqTWVKcnFYcGgrOHANCjVXNUptSEwyOHFhcmJRdnYrNzFWM25pNm9kazhaMk5EYmFuMnkxa0ENCj1SdXluDQotLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tDQo=" + } + }, + { + "partId": "1", + "mimeType": "text/html", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/html; charset=\"UTF-8\"" + }, + { + "name": "Content-Transfer-Encoding", + "value": "quoted-printable" + } + ], + "body": { + "size": 1266, + "data": "PGRpdiBkaXI9Imx0ciI-PGRpdiBzdHlsZT0iY29sb3I6cmdiKDAsMCwwKTtmb250LWZhbWlseTomcXVvdDtEcm9pZCBTYW5zIE1vbm8mcXVvdDssJnF1b3Q7bW9ub3NwYWNlJnF1b3Q7LG1vbm9zcGFjZTtmb250LXNpemU6MTRweDtsaW5lLWhlaWdodDoxOXB4O3doaXRlLXNwYWNlOnByZSI-PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6cmdiKDE2MywyMSwyMSkiPi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLTwvc3Bhbj48L2Rpdj48YnI-PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6cmdiKDE2MywyMSwyMSkiPnlNQ3hBVHZDeTh6QXhIaGl0YkpPZlhyY0VjYlRLa2tNSU9DUm1wT1RyNk5Ra3BGWnJBQkVpUW9scWNVbENybXB4Y1dKNmFsY2h3NVU8L3NwYW4-PC9kaXY-PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6cmdiKDE2MywyMSwyMSkiPnNqQXdNakVvaXlteWhKZmVhcG9oeVhSVVllYXp4VEJqV0prU2VPdERXSm5CUm5GeENzREV2MzNtWURqbWRzdUdQeXg2OGc3dE13ZTM8L3NwYW4-PC9kaXY-PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6cmdiKDE2MywyMSwyMSkiPnRxbGV2dlVvNUVJYXArd21abTZtUlhjT0dCcGx2SnkxbWZ1cTFwbHJ0MDhxczk3WTJ6dEIrL1hidXlHM0lyNDh1N0kzcG1EK1RXYWU8L3NwYW4-PC9kaXY-PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6cmdiKDE2MywyMSwyMSkiPldTZDVkMjZRWVhjdXVzYXVjMFh5L2ZTMS9GWGJQSmFZSGxDZU1DZm5ockY5ZDJqeUgzM1YrZXI2cjNsUzVpL21jaE9LZmZwZ2xrdFQ8L3NwYW4-PC9kaXY-PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6cmdiKDE2MywyMSwyMSkiPmQ2WjM2Ly9Nc21jek4wMFdkNjB0OVQrcXlMejBUNC9VRzJZOWxnZjM2N2YzZCtrWVBFMExTN21YdUZtamxQWGZ3MG5LeVZzU2VGaXU8L3NwYW4-PC9kaXY-PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6cmdiKDE2MywyMSwyMSkiPjNkdXorVmZ6VTNIVlo2NUw0eGM1UEJZd1dMbHNoZGNHOTRWVHQyb0szY3VMQzV6dXkvM2tzMHN3MStNR3ptS3RqTWVKcnFYcGgrOHA8L3NwYW4-PC9kaXY-PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6cmdiKDE2MywyMSwyMSkiPjVXNUptSEwyOHFhcmJRdnYrNzFWM25pNm9kazhaMk5EYmFuMnkxa0E8L3NwYW4-PC9kaXY-PGRpdj48c3BhbiBzdHlsZT0iY29sb3I6cmdiKDE2MywyMSwyMSkiPj1SdXluPC9zcGFuPjwvZGl2PjxkaXY-PHNwYW4gc3R5bGU9ImNvbG9yOnJnYigxNjMsMjEsMjEpIj4tLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tPC9zcGFuPjwvZGl2PjwvZGl2PjwvZGl2Pg0K" + } + } + ] + }, + "sizeEstimate": 2501, + "historyId": "2634857", + "internalDate": "1684426842000" + }, + "attachments": {}, + "raw": { + "id": "1882fa9e2b996242", + "threadId": "1882fa9e2b996242", + "labelIds": ["IMPORTANT", "SENT", "INBOX"], + "snippet": "-----BEGIN PGP MESSAGE----- yMCxATvCy8zAxHhitbJOfXrcEcbTKkkMIOCRmpOTr6NQkpFZrABEiQolqcUlCrmpxcWJ6alchw5U sjAwMjEoiymyhJfeapohyXRUYeazxTBjWJkSeOtDWJnBRnFxCsDEv33mYDjmdsuGPyx68g7tMwe3 tqlevvUo5EIap+", + "sizeEstimate": 2501, + "historyId": "2634857", + "internalDate": "1684426842000" + } +} diff --git a/test/source/mock/google/exported-messages/message-export-1885ded59a2b5a8d.json b/test/source/mock/google/exported-messages/message-export-1885ded59a2b5a8d.json new file mode 100644 index 00000000000..91713516e58 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-1885ded59a2b5a8d.json @@ -0,0 +1,118 @@ +{ + "acctEmail": "ci.tests.gmail@flowcrypt.test", + "full": { + "id": "1885ded59a2b5a8d", + "threadId": "1885ded59a2b5a8d", + "labelIds": ["STARRED", "SENT", "INBOX"], + "snippet": "See attachment", + "payload": { + "partId": "", + "mimeType": "multipart/mixed", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "multipart/mixed; boundary=\"----sinikael-?=_1-16852030157220.20294758385357903\"" + }, + { + "name": "Openpgp", + "value": "id=9BA39CE075F0839B30340FC807481C8ACF9D49FE" + }, + { + "name": "From", + "value": "ci.tests.gmail@flowcrypt.test" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Subject", + "value": "I'm attaching cleartext signed message as an attachment" + }, + { + "name": "Date", + "value": "Sat, 27 May 2023 10:56:55 -0500" + }, + { + "name": "MIME-Version", + "value": "1.0" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/plain" + }, + { + "name": "Content-Transfer-Encoding", + "value": "quoted-printable" + } + ], + "body": { + "size": 14, + "data": "U2VlIGF0dGFjaG1lbnQ=" + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "sample_cleartext.asc", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream; name=sample_cleartext.asc" + }, + { + "name": "Content-Disposition", + "value": "attachment; filename=sample_cleartext.asc" + }, + { + "name": "X-Attachment-Id", + "value": "f_JAEwIiHAlGaJaOIMRPoptmvXSiAmYD@flowcrypt" + }, + { + "name": "Content-Id", + "value": "" + }, + { + "name": "Content-Transfer-Encoding", + "value": "base64" + } + ], + "body": { + "attachmentId": "ANGjdJ_0g7PGqJSjI8-Wjd5o8HcVnAHxIk-H210TAxxwfhKWlCUqnXbZtBdwjPQqN9omCqn-0-r4JBy6amb0ogGz9jZL9q11Z_iUJzxr_X0MlJj0cw-3EYCFKPDrpfVVQZ-28Ajhd35CkI3Z93s3FU4BUKHROZR1qdEPOoQM63k1IOPTfL9c7ES-W8EaOKxB-k0n0frlXqpTJgv-AHAi9NEAaq-ghluobPc4JiSjgkK7_0MkykEm4oZfBSHSuzG94c3HWeYNJw4bcWFHiKRln7bB8nq5JTJe546Zg2MoVkMuc7K6a0cUwGd9mdAUAPqPyq1ENIQ9bGFK7ozlDezHHZYP8rOTEL3QBx6rEE-aaGT2MEQyWPtsp8Zgt42prnUjysPDe-uVs-pl31UpIDhf", + "size": 1071 + } + } + ] + }, + "sizeEstimate": 2587, + "historyId": "2673627", + "internalDate": "1685203015000" + }, + "attachments": { + "ANGjdJ_0g7PGqJSjI8-Wjd5o8HcVnAHxIk-H210TAxxwfhKWlCUqnXbZtBdwjPQqN9omCqn-0-r4JBy6amb0ogGz9jZL9q11Z_iUJzxr_X0MlJj0cw-3EYCFKPDrpfVVQZ-28Ajhd35CkI3Z93s3FU4BUKHROZR1qdEPOoQM63k1IOPTfL9c7ES-W8EaOKxB-k0n0frlXqpTJgv-AHAi9NEAaq-ghluobPc4JiSjgkK7_0MkykEm4oZfBSHSuzG94c3HWeYNJw4bcWFHiKRln7bB8nq5JTJe546Zg2MoVkMuc7K6a0cUwGd9mdAUAPqPyq1ENIQ9bGFK7ozlDezHHZYP8rOTEL3QBx6rEE-aaGT2MEQyWPtsp8Zgt42prnUjysPDe-uVs-pl31UpIDhf": { + "data": "LS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UtLS0tLQ0KSGFzaDogU0hBMjU2DQoNClN0YW5kYXJkIG1lc3NhZ2UNCg0Kc2lnbmVkIGlubGluZQ0KDQpzaG91bGQgZWFzaWx5IHZlcmlmeQ0KVGhpcyBpcyBlbWFpbCBmb290ZXINCi0tLS0tQkVHSU4gUEdQIFNJR05BVFVSRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgNS4wLjQgR21haWwgRW5jcnlwdGlvbiBmbG93Y3J5cHQuY29tDQpDb21tZW50OiBTZWFtbGVzc2x5IHNlbmQsIHJlY2VpdmUgYW5kIHNlYXJjaCBlbmNyeXB0ZWQgZW1haWwNCg0Kd3NGY0JBRUJDQUFRQlFKWis3NFlDUkFHeWxVK3drVmRjQUFBZkFrUUFLWXdUQ1FVWDRLMjZqd3pLUEcwDQp1ZTYralN5Z3BrTmxzSHFmbzdaVTBTWWJ2YW8weEVvMVFRUHk5elZXN3pQMzlVQUpaa041RXBJQVJCekYNCjY3MUFBM3MwS3Rrbkx0MEFZZmlUSmRrcVRpaFJqSlpIQkhRY3hra2Fqd3MrM0JyOG9CaWVCNHppMTlHSg0Kb09xanlpMnV4bDdCeTVDU1AyMzhCNkNYQlRnYVlraC83VHBZSkRnRnp1aHRYdHgwYVdCUDloN1RnRVlODQpBWU5tdEdJdFQ2VzJRL0pvQjI5Y1ZzeHl1Z1ZzUWhkZk04REE1TXBFWlkyWmsvK1VIWE4wTDQ1ckVKRmoNCjhISmtSODN2b2l3QWU2RGRrTFFIYllmVnl0U0RaTitLODB4Ti9WQ1FmZGQ3K0hLcEtiZnRJaWcwY1htcg0KK09zb0RNR3ZQV2tHRXFKUmg1N2JleldmejZqbmtTU0pTWDltWEZHNktTSjJ4dWozMG5QWHNsMVduMVh2DQp3UjVUM0wya0R1c2x1RkVSaXEwTm5LRHdBdmVIWkl6aDd4dGptWVJsR1ZOdWp0YTBxVFFYVHlhanhEcHUNCmdaSXFaS2pEVlpwN0NqS1lZUHp2Z1VzaWhQemxneXFBb2RrTXBsL0loWWlkUE1CMTM1bFY0QkJLSHJGMg0KVXJiYjJ0WE1IYTZyRVpvajZqYlMwdXcvTzFmU0JKQVNZZmxySjFNOFlMc0ZDd0JIcE1XV0wzOG9qYm1LDQppMUVIWUlVOEEveTBxRUxQcEtvcmduTE5LaDh0MDVhMDFuclVXZC9lWERLUzFiYkdsTGVSNlIvWXZPTTUNCkFEanZneXdwaUdtcndkZWhpb0t0UzBTckhSdkV4WXg4b3J5MGlMbzBjTEdFUkFyWjNqeWNGOEYrUzJYcA0KNUJuSQ0KPUYyb20NCi0tLS0tRU5EIFBHUCBTSUdOQVRVUkUtLS0tLQ0K", + "size": 1071 + } + }, + "raw": { + "id": "1885ded59a2b5a8d", + "threadId": "1885ded59a2b5a8d", + "labelIds": ["STARRED", "SENT", "INBOX"], + "snippet": "See attachment", + "sizeEstimate": 2587, + "raw": "UmVjZWl2ZWQ6IGZyb20gNzE3Mjg0NzMwMjQ0DQoJbmFtZWQgdW5rbm93bg0KCWJ5IGdtYWlsYXBpLmdvb2dsZS5jb20NCgl3aXRoIEhUVFBSRVNUOw0KCVNhdCwgMjcgTWF5IDIwMjMgMTA6NTY6NTUgLTA1MDANCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOw0KIGJvdW5kYXJ5PSItLS0tc2luaWthZWwtPz1fMS0xNjg1MjAzMDE1NzIyMC4yMDI5NDc1ODM4NTM1NzkwMyINCk9wZW5wZ3A6IGlkPTlCQTM5Q0UwNzVGMDgzOUIzMDM0MEZDODA3NDgxQzhBQ0Y5RDQ5RkUNCkZyb206IEdtYWlsIENJIFRlc3QgPGNpLnRlc3RzLmdtYWlsQGZsb3djcnlwdC5kZXY-DQpUbzogR21haWwgQ0kgVGVzdCA8Y2kudGVzdHMuZ21haWxAZmxvd2NyeXB0LmRldj4NClN1YmplY3Q6IEknbSBhdHRhY2hpbmcgY2xlYXJ0ZXh0IHNpZ25lZCBtZXNzYWdlIGFzIGFuIGF0dGFjaG1lbnQNCkRhdGU6IFNhdCwgMjcgTWF5IDIwMjMgMTA6NTY6NTUgLTA1MDANCk1lc3NhZ2UtSWQ6IDxDQU85Rlk5dXU3aUZSPVlaSlkyZSt0d1VqTjZ5OURLR0w1R2JPc1JTTTBEdTFPNWY4NHdAbWFpbC5nbWFpbC5jb20-DQpNSU1FLVZlcnNpb246IDEuMA0KDQotLS0tLS1zaW5pa2FlbC0_PV8xLTE2ODUyMDMwMTU3MjIwLjIwMjk0NzU4Mzg1MzU3OTAzDQpDb250ZW50LVR5cGU6IHRleHQvcGxhaW4NCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFibGUNCg0KU2VlIGF0dGFjaG1lbnQNCi0tLS0tLXNpbmlrYWVsLT89XzEtMTY4NTIwMzAxNTcyMjAuMjAyOTQ3NTgzODUzNTc5MDMNCkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtOyBuYW1lPXNhbXBsZV9jbGVhcnRleHQuYXNjDQpDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT1zYW1wbGVfY2xlYXJ0ZXh0LmFzYw0KWC1BdHRhY2htZW50LUlkOiBmX0pBRXdJaUhBbEdhSmFPSU1SUG9wdG12WFNpQW1ZREBmbG93Y3J5cHQNCkNvbnRlbnQtSWQ6IDxmX0pBRXdJaUhBbEdhSmFPSU1SUG9wdG12WFNpQW1ZREBmbG93Y3J5cHQ-DQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQNCg0KTFMwdExTMUNSVWRKVGlCUVIxQWdVMGxIVGtWRUlFMUZVMU5CUjBVdExTMHRMUTBLU0dGemFEb2dVMGhCTWpVMkRRb05DbE4wWVc1aw0KWVhKa0lHMWxjM05oWjJVTkNnMEtjMmxuYm1Wa0lHbHViR2x1WlEwS0RRcHphRzkxYkdRZ1pXRnphV3g1SUhabGNtbG1lUTBLVkdocA0KY3lCcGN5QmxiV0ZwYkNCbWIyOTBaWElOQ2kwdExTMHRRa1ZIU1U0Z1VFZFFJRk5KUjA1QlZGVlNSUzB0TFMwdERRcFdaWEp6YVc5dQ0KT2lCR2JHOTNRM0o1Y0hRZ05TNHdMalFnUjIxaGFXd2dSVzVqY25sd2RHbHZiaUJtYkc5M1kzSjVjSFF1WTI5dERRcERiMjF0Wlc1MA0KT2lCVFpXRnRiR1Z6YzJ4NUlITmxibVFzSUhKbFkyVnBkbVVnWVc1a0lITmxZWEpqYUNCbGJtTnllWEIwWldRZ1pXMWhhV3dOQ2cwSw0KZDNOR1kwSkJSVUpEUVVGUlFsRktXaXMzTkZsRFVrRkhlV3hWSzNkclZtUmpRVUZCWmtGclVVRkxXWGRVUTFGVldEUkxNalpxZDNwTA0KVUVjd0RRcDFaVFlyYWxONVozQnJUbXh6U0hGbWJ6ZGFWVEJUV1dKMllXOHdlRVZ2TVZGUlVIazVlbFpYTjNwUU16bFZRVXBhYTA0MQ0KUlhCSlFWSkNla1lOQ2pZM01VRkJNM013UzNScmJreDBNRUZaWm1sVVNtUnJjVlJwYUZKcVNscElRa2hSWTNocmEyRnFkM01yTTBKeQ0KT0c5Q2FXVkNOSHBwTVRsSFNnMEtiMDl4YW5scE1uVjRiRGRDZVRWRFUxQXlNemhDTmtOWVFsUm5ZVmxyYUM4M1ZIQlpTa1JuUm5wMQ0KYUhSWWRIZ3dZVmRDVURsb04xUm5SVmxPRFFwQldVNXRkRWRKZEZRMlZ6SlJMMHB2UWpJNVkxWnplSGwxWjFaelVXaGtaazA0UkVFMQ0KVFhCRldsa3lXbXN2SzFWSVdFNHdURFExY2tWS1Jtb05DamhJU210U09ETjJiMmwzUVdVMlJHUnJURkZJWWxsbVZubDBVMFJhVGl0TA0KT0RCNFRpOVdRMUZtWkdRM0swaExjRXRpWm5SSmFXY3dZMWh0Y2cwS0swOXpiMFJOUjNaUVYydEhSWEZLVW1nMU4ySmxlbGRtZWpacQ0KYm10VFUwcFRXRGx0V0VaSE5rdFRTako0ZFdvek1HNVFXSE5zTVZkdU1WaDJEUXAzVWpWVU0wd3lhMFIxYzJ4MVJrVlNhWEV3VG01TA0KUkhkQmRtVklXa2w2YURkNGRHcHRXVkpzUjFaT2RXcDBZVEJ4VkZGWVZIbGhhbmhFY0hVTkNtZGFTWEZhUzJwRVZscHdOME5xUzFsWg0KVUhwMloxVnphV2hRZW14bmVYRkJiMlJyVFhCc0wwbG9XV2xrVUUxQ01UTTFiRlkwUWtKTFNISkdNZzBLVlhKaVlqSjBXRTFJWVRaeQ0KUlZwdmFqWnFZbE13ZFhjdlR6Rm1VMEpLUVZOWlpteHlTakZOT0ZsTWMwWkRkMEpJY0UxWFYwd3pPRzlxWW0xTERRcHBNVVZJV1VsVg0KT0VFdmVUQnhSVXhRY0V0dmNtZHVURTVMYURoME1EVmhNREZ1Y2xWWFpDOWxXRVJMVXpGaVlrZHNUR1ZTTmxJdldYWlBUVFVOQ2tGRQ0KYW5abmVYZHdhVWR0Y25ka1pXaHBiMHQwVXpCVGNraFNka1Y0V1hnNGIzSjVNR2xNYnpCalRFZEZVa0Z5V2pOcWVXTkdPRVlyVXpKWQ0KY0EwS05VSnVTUTBLUFVZeWIyME5DaTB0TFMwdFJVNUVJRkJIVUNCVFNVZE9RVlJWVWtVdExTMHRMUTBLDQotLS0tLS1zaW5pa2FlbC0_PV8xLTE2ODUyMDMwMTU3MjIwLjIwMjk0NzU4Mzg1MzU3OTAzLS0NCg==", + "historyId": "2673627", + "internalDate": "1685203015000" + } +} diff --git a/test/source/mock/google/exported-messages/message-export-188721aebb71c16c.json b/test/source/mock/google/exported-messages/message-export-188721aebb71c16c.json new file mode 100644 index 00000000000..a70a59e3da7 --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-188721aebb71c16c.json @@ -0,0 +1,126 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "188721aebb71c16c", + "threadId": "188721aebb71c16c", + "labelIds": [ + "Label_15", + "SENT", + "INBOX" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt Email Encryption 8.4.7 Comment: Seamlessly send and receive encrypted email wcFMA0taL/zmLZUBAQ/+KI9KKzEER58FcRk0S1yqhbMp5ucWw/trGOupYyia", + "payload": { + "partId": "", + "mimeType": "multipart/mixed", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "multipart/mixed; boundary=\"----sinikael-?=_1-16855415442170.8906747903599939\"" + }, + { + "name": "Openpgp", + "value": "id=E8F0517BA6D7DAB6081C96E4ADAC279C95093207" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Subject", + "value": "Test attachment #3505" + }, + { + "name": "Date", + "value": "Wed, 31 May 2023 06:59:06 -0700" + }, + { + "name": "MIME-Version", + "value": "1.0" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/plain" + }, + { + "name": "Content-Transfer-Encoding", + "value": "quoted-printable" + } + ], + "body": { + "size": 4122, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgRW1haWwgRW5jcnlwdGlvbiA4LjQuNw0KQ29tbWVudDogU2VhbWxlc3NseSBzZW5kIGFuZCByZWNlaXZlIGVuY3J5cHRlZCBlbWFpbA0KDQp3Y0ZNQTB0YUwvem1MWlVCQVEvK0tJOUtLekVFUjU4RmNSazBTMXlxaGJNcDV1Y1d3L3RyR091cFl5aWENCmNrRHd0TW1kMVJhYW1qd0k4bklnZXp5R09Lell2N2lSQ0tKSmpIRmtZaFREejh6QnI5ckdzaXdaVlFncQ0KNzZ3U1hOMzNSbnZ0czYrQ1A5WWZ3NmJHekk0UlRYaHlmR0JpMzJiNlMwQjMxcityTDFtM3dSUVhzck9wDQo0QUk0N2FpUnFPS0tGMHlhRlpka3JZWExrQ1F0Y0FhTXI5SzdkT1Izb3drc3FXVVpndEMxMmR1MDY1YTINCllxZjdNRnNQcGs0S3RhaXRZTTFOTFF6NzltbjlPeWdtTXlwLzdrZ1ljYWlqYWFYZlVxd1dQcSt3Y05iZw0KeEJHNXcvRmpJU1BOWFRaelNQMnQvRW0xNnZWRzBsbWlNOWRyTmlHV1MrSDcxbFhreEFrNDFtV1Y0NWw3DQp5anlCRHNJdUdZcVNzb1E1c3Y2ZnU4US9hdXFJQnRaam5MRHJhUnFldE5YVkdrT1owVVZYTUF0b1NCSnYNCm5LV1hjMXU5dm0xakY4ZFptK09kN3NhOVY4Zi8zam5BaHJsTTlkSldPQXd0YkJpa1VYc1plWFMxSEhlZQ0Kb2FEUjNiYWc0VFJpN0J5ZVZGR1Y5TGwwY2JjSlZVb2MvT2hpYzhaejJRTFRDaDhUaDdxZGF4a1RjbHY2DQpZTWtJNjEvS0dtb0hDUXNNcmtPVCt4bkJHUkhpNy9jMnF0N3FBTEZZaTlzcVBoRldKb1ZFYnl4dFNPM28NCkZ6MmFxWDJJVDV1ZDBxbWVaQ1A5QXlLdkpaVmpVNkJtZzdYT29GNVQ1ZUtiblNSUFdRZjNlVmRjOG44Vw0KM1R0RldrbERVTzYrUDg2WXppendKK0h1a0lEVE9vdFBjQlpPcTZNL1hzekJ3VXdEdmIxMllQYVpqY1FCDQpELzRxMlBoVHR6aWExbVBzMlJ2ZFFOTUo5cElxdnk3TEJJNk9KZDdrSE1JTkM4SDdTRVBBcWlaekYxYzYNCjBWVmN0UW1aN1NuajVKOHRaNTFYZmQzbERzM2hFczBQNE5oZEkxUURkdFRzMUkvbGYyQ2QrVktEQlFDSw0KT1NwV0VQSDlCM1ZuYVlVNzFsWEYzRTV3ZXVNMFRKQ2RIUkgxZ04wdVlxSFo5TTBJS0pjeGdOSHBDaUZPDQpCVkcwdzdmTmplakxYOHdDMUx4YmRYTWExY0pVcDhpYjhXdEk1ZVMwS2FQajlZNnViMUpRcTlpUVdXVHUNCmVoQVlmVlBGZWZQVjN0VXZORjVZc1pHeUFxTWFwOEk3MmN1cjRpWTNSS1g3V0lzOHZTeTZIRGJtUzRMVw0KeWhQZ2pWSHMvV0I0YVMyUXlMcjFadUlDZUlkRHQvN1RKTHFOQUdmZ2xSVG52ZnEweEtwTUtIczVVNnA4DQpKS2h2TUIyR2gydVpZaGRiMjdoaElqMUtBNkh5cFpRUHhyZDJwaGpVRlNSa0NSM05QNW1ieHlXbWN1NHkNCm1vU08rNEhLazlhemZkNklySHE0YjFRckJ5Rkwvc28wVFBtNFBVQW4zaDIwMmhKTU54WWdRdnB4bmc5WQ0KcnZVcmljY2RMUFpudTQ3MTlSbG9ZcTB3RVk1Y2paRHlQc0R3dG1Oa1hmRWJGbHdUekE2ci9tWndjalBEDQpKK0FBZ04vaTRjdkhZVFRFWHhPSEJDUTdsdzNuVzdzSS9zRHlSQW5UU25KODdSaU9pRE1DaEFhRUVmMDENCnJPM3gyYmplODE2STJjaTdPRDQvL2ljano1aEl5aWRqcFVOSUVEUGpESitLdE40QWF1QzdKa1p4d05KeA0KeEJ0cTNNYkZMREIyYlZZWmIwRUhxNUM1ZDhGZUEybjBreTNrTC9wVkVnRUhRSUtCelJIV1FyTnA4T2FjDQpMakpiVGFVOW9YamZMeUdqYTRISElPN0RkT29RTUtVYitLTS9rL051TktiY1o0c3NDWVRiUjhyc2xrRTQNCnpNclRac3h1QldubVhDdnI5ZHdQVmdXTGNOYStZcS9yRXNIQlRBTkxXaS84NWkyVkFRRVAvUkFJOVlpSw0KVEM1SzMyRDFrVnI3d0NqNU1NcVR5Q2hnUHJDMGI2NEpBLzVMeFRXRlhhaEc2RWwzaHdtMGxQODAvR2h3DQpBdjhFdW1xRTZqVUNnbTBaUWNqVVFPMEo0bVdmNDBLQ09zdkRVK01GTUdlQ3ArNDYzT3lURnJ4WmNIaTMNCmxsNjdpS0xGa1lNNDlwWSt1WVZoN1lRdm9nZERET2RaQXFPWmNlQXRnUGhiNU81UnUvcjEzVU92ZXBIZA0KamkvU0pHOTZoNzA0dURLK2RPOGM0dmtKN1Q2ZC9kRHUvYTlrazRvcGNuVm4wV3ZqRm9uU1BmcCtiOFFtDQpoY0ZERjBqbFBQdDVZNWoydll2REI5OXNNYUIwby9UVm53eFBnVEFuMkdRODF4dTcyOXo5ampwUnZocXQNCmJlZlA3TE5oTWhrQnRicXhVK01yTnZJUFRISXBOUmZJTDFwbzd3V0R4WlJudnpINGRCbk1jaGdiSmRHOA0KUG8raUsvcDlITkd6bkI0b3hHMVJkV2duV2Z0czdxUFlNQlpwdzg5ekFtbjV4Z0s4ZXYzdEJtTGVxdHIxDQo1T2hZYlgwNXJZd0gwUjJsbUc1SWQ5L3JOU2ZzRkpWTDJDQlVGUnFWOWpJc1NsdDAwUnBsUDBKNmwxOEwNCkpXc3d3Y3AzaHlvRlllS09GaCt3TjBITEJrUHBuR0x6eXdQYVduL3lRcFpqY25QcFZOQkNibjZDY1dFSw0KaE1ZeEFNakpsaWVTN25uNzhGMkZnWXVLSm5uREttSnpMOTBUM2tCdjc1WmJERklTQXpjdGhJL0tkQjU3DQo0ZW45YS9ya0ZjNkx5NnlUeHFuQ2xkaE91L1ZiL0ZpTHVFS1ZVbm9KcTZNTzFLeWI3aGFvYy9hVE51R3ENCkIwOGkvZGRMbUZnZ1RHNnh3Y0ZNQTcyOWRtRDJtWTNFQVJBQTFZU0xic2J1c2VZRnpjbEJabHJLRStRaQ0KcCs3THVmUkt2N3hDa3BYanFFZEJqMWwwOCtUNlFwZnEzUUdlVkdySDU4Q3dBL1ZCMzhXZmVIYVN6S2xLDQp3SDlVMVRHMFhqZG5wUm53eEZDQVpVUjA0NzdIVU9FQmRMZ3RUZWd3eGVGRjQwUUEwYllaZllHcHdKM2UNCm9ZdGJ4ejJkeDhTSHFKMWgzUUowNVhOUTNKQjlDK01YSWV3YW00K1RvWFptUVRSanI1V3JUb0VpeUxWTA0KRHpYQlIrYXB5YnlXTmhzeFVoTlcreUE0S0RXZHZYbnBMSDBUSno0VW9aTUpTQWVhcnk2ZDgzRHo5dmlsDQphUTBpWmJCWEprSWVacGxlbmlyQXF4bWYvRVduOEJKT20wS1R2Y2pxTW96dThPQm9ScG9LZytUUElSZGYNCllteERianJiMmxPeUI0b3VkWCs0WHZzVTlzamZiRzBrSk1iUldENXdKK2lxRjdvc3czUVhTMFh0SE41dA0KakxlcDh2akdWMVZTUHFxWlNtVkg1TXZSa1NraGtJeFd1c2Zma2J0a04rNXlGYzVnSWlnRmt3V1ZWcWpQDQo4RmZYZHFRcitrNlF3Uk9EbkRVR1l2K0ZEaFFVNjdxQlhQM2FlaG9RYTZON2dkMS9wQ1FnSG9zVzBTcGQNCko3bVZWcGIzVFZ3enYwUkQxTzZiNDNqbmY0bTZsdmdOZjlwUm1EOWxNSXZiaUJrM2t6WUlrUGVSZ0dIVg0KNi9VeVRwQXJSdjZrdW1wRUNVeFlJSDBYK3paRnVDNmdUbjRqZVJqb2k1S2N6UHRDRklwNGFFeWMwYjNnDQpHQWl1SWJWYkg5Vk4xSUtxZmViOG9HSStBZ2prQW91ZUxIV0tXTzVHdmRUOG9mZWx4Q2VYck1LN3RUSFMNCndkc0JwVlk5UnV4dFdiaGF0VWJyd0R2VzlVbXJXRG1naHVVSGg5VWthVUNjV3FvOTA2ZlQ2R1N1OWtUMw0KNG1PYnJqbGU3eXlSa3oyY3crVDMyNzRoeGZ3bmNqayszdUFtOW1iQzRCY3kvNDFwOGlOWHdZQjJyYlJqDQo1VjZtaFdiZ2RnbFpqcllWQ25QVnFrOThyN2haL1BKcENUOVB2OEtXMFZTakh5c3NmSWNqN1lobDhiT00NClJvYjE2Z0RzWUE5SjFTd1c2Q0owSnQxWEc5UTc2RkN5b1g2QnRNMUxWY3FHMlFLYUZoY3JQbUQzN3lubQ0KZDZkZUg4Rjk0K2doZnhVRlFuQlZUMGtsVzBBTnpWUnJwTWxSM1RoRUJFTHRTYUpOZ3IxbFowVTQzMVdVDQpUa0x4d09meWxjaEhsZFRMSzBPa0lLMlBySlc3R0dVSEdFVmNCbGJRT0dnUXFQMzFROXhhWVRBdVNHZEsNClhQc3BuT0hvYUZaZjUvcjZyVHBEdnBVekhRYWR6OTZtRDRLRk1XYTFVMy9iVzMzRnFFMGxCR2c2YXh3Qg0KRHo4UW1UMkFXUlJpc0RaUGZkU01NWUNnalFYZDJqQVo5U0ZzY1ZSODVaUDlqTEIyR200OWhkei84WktmDQpOc2dPditZMVIrN0hIMjFpNU1VVDlLYTB0bE9LcGVFd05vdklyOGpYS0tFcjdraEx2SnJ4TnNCSFk5blMNCnBOb0V5eHZBS2xXMXdSdm82VnNJVFhDQUp1bmpoVVFyVm9TbUJtYktuQWZZemkyOTRiNG5GYjAvYkZxdg0KaFIzb0hKcUs0bm9MWXpLZFpBVEJIWGdzNlF4Vm1oR2VQajJrd1JBYllHNFR1SWZKNkNnMHBSaXU2NzZsDQptMGlMaS93WFF0VDc2bmZZWDhiWVVtaDV2bHYvTW5LcGZBdlpDM1JDNXVuZFhYeWhHTm9zY2I1eWp4V1ENCmZwaEI3YXNBdUowMlk2VktCeDBQMk1CVDVOdnlPU3o0RWcyVUljWTdZV0tha0NjRWRsQUNsbEVMRzE1Vg0KSCtUQ1JmNGNqUStCekFKck9LZFIxOGkyTEdOR2ZWVzFmMUN4K2JYQzl6YnBmMjdBNjVxNUpCZGpidG9BDQpjb0ZKV3NPcmYyNjl0YnZFQUFtYkE5c1ZQbkN4bnk0b2xXT1RDVmFudmJjSC8yQVVTMTdoDQo9cC94cA0KLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQ0K" + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "what's_up?.txt.pgp", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream; name=\"what's_up?.txt.pgp\"" + }, + { + "name": "Content-Disposition", + "value": "attachment; filename*0*=\"utf-8''what's_up%3F.txt.pgp\"" + }, + { + "name": "X-Attachment-Id", + "value": "f_TwRqngHBJBTuWpmsYkjIsImtCizyqT@flowcrypt" + }, + { + "name": "Content-Id", + "value": "" + }, + { + "name": "Content-Transfer-Encoding", + "value": "base64" + } + ], + "body": { + "attachmentId": "ANGjdJ93TiZoScoZbqS4-47RXwU7J4ZyMzvoUHZYrpna6bun9VTypNPxCD0p1v6j_5aB9wo_0w8lxdxCK0morUP3M4pikZWkxHO-BdzHzBumdQI4uBXuKUbQGw47vJfKB69SkDc9ClfBENTw6cpSVQlAQXUvckJu1lTbjbSAXXbhoCB3saQtHsdJ7QB0LHG3QBqM18gBsTDLsHoNtfA7xX-EnbT0VJ6l4tIcM9pKnGdmyrA4S2Ap-3Bz2jxgIuGYhexBJpbNtzUMOZHPY_cYnast6ZHkNgWZMqVLqvO4UOqlgELoRbJnaUCX8YXebW_IPPVq5zELRcWn14QOwway5s5bmW3nG0MgUtqZMuo9nizmRpfprNMylsF28ajv9WrL-gzFV9gEUiVvH40n82F6", + "size": 2273 + } + } + ] + }, + "sizeEstimate": 8347, + "historyId": "1408057", + "internalDate": "1685541546000" + }, + "attachments": { + "ANGjdJ93TiZoScoZbqS4-47RXwU7J4ZyMzvoUHZYrpna6bun9VTypNPxCD0p1v6j_5aB9wo_0w8lxdxCK0morUP3M4pikZWkxHO-BdzHzBumdQI4uBXuKUbQGw47vJfKB69SkDc9ClfBENTw6cpSVQlAQXUvckJu1lTbjbSAXXbhoCB3saQtHsdJ7QB0LHG3QBqM18gBsTDLsHoNtfA7xX-EnbT0VJ6l4tIcM9pKnGdmyrA4S2Ap-3Bz2jxgIuGYhexBJpbNtzUMOZHPY_cYnast6ZHkNgWZMqVLqvO4UOqlgELoRbJnaUCX8YXebW_IPPVq5zELRcWn14QOwway5s5bmW3nG0MgUtqZMuo9nizmRpfprNMylsF28ajv9WrL-gzFV9gEUiVvH40n82F6": { + "data": "wcFMA0taL_zmLZUBAQ__U2iTaxTs-GJ2VMxg87fFIxjkz5RXhhO86T5A-bRrA3LuUrQaXIbYkwcqQlokpRRmqs8HlpM_pQr8yz0A1HBJkrjWeKcKSJ6mxUr0H-3huxhOjP35V87Pr-MzvM1AnHxBorFnef4rqsu1uaI_7ny6kwURGCzBpqnLzzV0SUzgXRcUcxooBUr6BszM1y2tg3-VTMEn3U2EKKST6EVpQL2kcuKGBrM5zLnrEvwIhXrLckrf6fHLFQA83ooyiojH0XCnsIcgn999LIveZb0LAULlSDDgeuQ8pGFXSMCgtf02x3euLq22USaMDTijkQUgw4TRRBifVgeX7ffJ0V0hQLppUOP91OWgu81LX-CbUJuR5So0W8jgv7Z_UJyoRZ8QPsnVCP6KBmweLXorkdA4yq0GU_DMgRKT4kTVZz7sBzIyAWKd_ZyPmowfh_o85UqQoGhp3ALuRvCw_WbTzRLclJsfwP2Kl1nC5TXVvakQVefSm2fiuShHNe1rSZIstVZp6z51Xvm6jO2GcY6kRuGRpnZ_NM1d7auokutZprdEplTqxCzt5Yde9ueKYnWtncBPxY2IVr1bHzrCANKnI1Dx0XdCumcq6HND6To7xLgzf1ZJlTrIm0_19wMTZuVZ6au5JfgsK9Fs--mh39mY0g3BE3lBZlVn0PU11ZiMvM0QmP-nQavBwUwDvb12YPaZjcQBD_97nsunGO3jNqU7muSv2mLkg4N_pwnAVbZgMKwpeI3Ktj0OstRQj4RiSkTBbcut8GWV99s9R_iFCrTQsMX0qOUXi3r7-beC6_gFA-RplLAZgXbwZlMx9Ip_ZsvoU2fRHNdu2SIqNs-BFQIBpiUPWrBz01pJdfOA_IjDGJ3ZZXRwejCwoB-InMGhEWJ6FVs9ekeuW4wF40VvsLuS1Kp30VI4-SCH5txf7cX5jdDOcoPN6n1_BZHWQ77qhhOcb5To8aw0fKpYmEUAZ3Qc7OUtBlxZ_4dH8vfGsUZoiLORFWPjPZ_lxzf4kjBN8VC-f-F3eclGRyng8yezsp_Lrx-HNTlD6i7U131zTBKCgYJWN9iWJRbKSeG5JOPBfJaPfRDuUUq3dk5okbYsVX07RcWjeltB33T5UAj6nj7ydtxsaXjWPMjQUVPZKOI61-PrbcDJAhNefEkny3_7yF1BJjtV55-XVNaOIqcOzTrI5dpLJD5_Qp1BoZxOa8AJEiQkC7xKbZrq-zGjSeXoy1j_d1aYAOyFqeGcZ3y9me5XL0H5KGHRl_0A6hyCwhrnjYKH2IWYo5z-2Z-nQIaxpBJ4Yk90fHPUDnlnKEaZ5Z6xpDRtpRmgGZddHPKeJPbZE8Om4t-mTsH7KF2NbrzZyYvMWKSPwMvQmNc9ygX6O27fA0GS7s_A7cFeA2n0ky3kL_pVEgEHQIU1b4e8CnRlglTzixgVj11p0vvcxVME8nwJd9DgRYhoMLIlNSpQjxTM0MZvrH1mUBn0h4pLcqTzaXGd04XkeQslcYqvzeIFTsJtVzCaS_Xz3MHBTANLWi_85i2VAQEP_iybEjWyeGtR6w9h7S6mSzOT9InJ9TsOLdx2AtC-VOPMz6VUl4BwyNy38mDg8hPz-quYhXPOmo-0d7r3ujxb_MeD65M_ESUsxyjtp8bf_iRWxDkjr9-aiPgi9MAj2qGMMxWv2hF8de9oL78oD2i4b10GuA9ubb_Xj52Qxp-ysKr5DdnO6F0lQXNfoviUndp1PgDodtZDawOOKSGuwUusU62J_82__iXLzowjb1J-kMS5_FzWnjQod9BpOzE2eA5yYtg_MKt5jSWxRVE6omuwf6jQUAAS-nX9MpF2cotB_XD0uUweQTVhaDiYfMopT_sXjV0gQEbT7tTCYH0p4LvXEYwaZbsCmtS4k2ijUE6EqkHmL8CKQ_U0zL7EMXg2hADnCLJU9Xozo-XlnulZxmzOC5j0qtzhB5_xuSUFEkkIWz_GoE_FJlebaLSlMVi3z_7WrVZhntZnJnLD87HBC_ia68VBO17MUyc4kIOpsHL1bEJDqaFmlKFcGFvGoJcxmTqakT3m1gkhFw_f7lDpDA9mY708lQ6n1NxmfwB_wuHUOtfOcqxaeLG1nw_lhoYLJwJqVBsCG3SD8sywUjDQWGYj1-_4HD1Lm8My3Vw-H0mjd9jo2lo9Q7sig9KmTfeG1cPHjiHmop2UrRbAEkYfY21EcKbLiFvYlagMX0WEWgUbOKjZwcFMA729dmD2mY3EAQ_-L_LKYUt8BM66jVrK3GKXEs9mz52oNRDsXFyKxkC8jdIyxYR_h6vcTiDrOu-lkVIdrQmqMHkB45hvQMCKxFOKCl9R0_ECPqscjghNph_mBoKUlh_VypUWLXpr54ttcrzT7jOb1FEZUxTxnQZMQvK1Z4OG_YqNonTPC9E7HSULLZ2g_1FhrHnfEewtQF_EgY5DhbTX8eJbDtRz80mLtw1_LToSsTuEgLVwqO1eF1uckmuiokJc5-z0VRtYOALIxX4_tWigEsD1qczy9J3ne3-DjLFuZcOMocW7LawxnrEdSxkJf2CRrCl5C87yNpPnwxo9lm-Qk77E5WnupNlIrJfpxuoxvrGZ8eWFFQkm4tCOOyIuhYaB3mjXCgnINA53iLs1tCsdEL9ZS_--gC4rTvDFNjWojBDGq_kOZDlOVJCHK9OMfsC3elSc_VIcx6-aqf3OBRF8ryzt8-kFCOEHLNKi1SiyX9tAugXMTNsRXLXobiEjO6sGpdLEzmJZxyxu1IQ_YTD5BY9y8BfqsvQcDZ5KWJi6FJaXpNrMGBRAMOQogHmWnXqgdkz8S-vlggcX0q87OZmRxsP3unS_nxAclycGge7kROOFEvbKCnFcLfgptLYeAeKvhno892ualX9X175RoZ-WOVm9-MF_StWmS41vdKIpGWxXxE5rhQlA608My53SQwGF7q6vYrVPIL6DT1RlArbpdI54OSpTKvCbVC7E2Ku6vFlV1SkEyIGymC51IFDWRskEoF9Lqu9uma0BwKkPJcKZwrA", + "size": 2273 + } + }, + "raw": { + "id": "188721aebb71c16c", + "threadId": "188721aebb71c16c", + "labelIds": [ + "Label_15", + "SENT", + "INBOX" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt Email Encryption 8.4.7 Comment: Seamlessly send and receive encrypted email wcFMA0taL/zmLZUBAQ/+KI9KKzEER58FcRk0S1yqhbMp5ucWw/trGOupYyia", + "sizeEstimate": 8347, + "raw": "UmVjZWl2ZWQ6IGZyb20gNzE3Mjg0NzMwMjQ0DQoJbmFtZWQgdW5rbm93bg0KCWJ5IGdtYWlsYXBpLmdvb2dsZS5jb20NCgl3aXRoIEhUVFBSRVNUOw0KCVdlZCwgMzEgTWF5IDIwMjMgMDY6NTk6MDYgLTA3MDANCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOw0KIGJvdW5kYXJ5PSItLS0tc2luaWthZWwtPz1fMS0xNjg1NTQxNTQ0MjE3MC44OTA2NzQ3OTAzNTk5OTM5Ig0KT3BlbnBncDogaWQ9RThGMDUxN0JBNkQ3REFCNjA4MUM5NkU0QURBQzI3OUM5NTA5MzIwNw0KRnJvbTogRmxvd0NyeXB0IENvbXBhdGliaWxpdHkgPGZsb3djcnlwdC5jb21wYXRpYmlsaXR5QGdtYWlsLmNvbT4NClRvOiBGbG93Q3J5cHQgQ29tcGF0aWJpbGl0eSA8Zmxvd2NyeXB0LmNvbXBhdGliaWxpdHlAZ21haWwuY29tPg0KU3ViamVjdDogVGVzdCBhdHRhY2htZW50ICMzNTA1DQpEYXRlOiBXZWQsIDMxIE1heSAyMDIzIDA2OjU5OjA2IC0wNzAwDQpNZXNzYWdlLUlkOiA8Q0FLYnVMVHBwaXU3N2QzZ090Z050c1BiMDl5Vkw4Rm9CRVVRdmhRT2hPLUZBWENjOXpBQG1haWwuZ21haWwuY29tPg0KTUlNRS1WZXJzaW9uOiAxLjANCg0KLS0tLS0tc2luaWthZWwtPz1fMS0xNjg1NTQxNTQ0MjE3MC44OTA2NzQ3OTAzNTk5OTM5DQpDb250ZW50LVR5cGU6IHRleHQvcGxhaW4NCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFibGUNCg0KLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgRW1haWwgRW5jcnlwdGlvbiA4LjQuNw0KQ29tbWVudDogU2VhbWxlc3NseSBzZW5kIGFuZCByZWNlaXZlIGVuY3J5cHRlZCBlbWFpbA0KDQp3Y0ZNQTB0YUwvem1MWlVCQVEvK0tJOUtLekVFUjU4RmNSazBTMXlxaGJNcDV1Y1d3L3RyR091cFl5aWENCmNrRHd0TW1kMVJhYW1qd0k4bklnZXp5R09Lell2N2lSQ0tKSmpIRmtZaFREejh6QnI5ckdzaXdaVlFncQ0KNzZ3U1hOMzNSbnZ0czYrQ1A5WWZ3NmJHekk0UlRYaHlmR0JpMzJiNlMwQjMxcityTDFtM3dSUVhzck9wDQo0QUk0N2FpUnFPS0tGMHlhRlpka3JZWExrQ1F0Y0FhTXI5SzdkT1Izb3drc3FXVVpndEMxMmR1MDY1YTINCllxZjdNRnNQcGs0S3RhaXRZTTFOTFF6NzltbjlPeWdtTXlwLzdrZ1ljYWlqYWFYZlVxd1dQcSt3Y05iZw0KeEJHNXcvRmpJU1BOWFRaelNQMnQvRW0xNnZWRzBsbWlNOWRyTmlHV1MrSDcxbFhreEFrNDFtV1Y0NWw3DQp5anlCRHNJdUdZcVNzb1E1c3Y2ZnU4US9hdXFJQnRaam5MRHJhUnFldE5YVkdrT1owVVZYTUF0b1NCSnYNCm5LV1hjMXU5dm0xakY4ZFptK09kN3NhOVY4Zi8zam5BaHJsTTlkSldPQXd0YkJpa1VYc1plWFMxSEhlZQ0Kb2FEUjNiYWc0VFJpN0J5ZVZGR1Y5TGwwY2JjSlZVb2MvT2hpYzhaejJRTFRDaDhUaDdxZGF4a1RjbHY2DQpZTWtJNjEvS0dtb0hDUXNNcmtPVCt4bkJHUkhpNy9jMnF0N3FBTEZZaTlzcVBoRldKb1ZFYnl4dFNPM28NCkZ6MmFxWDJJVDV1ZDBxbWVaQ1A5QXlLdkpaVmpVNkJtZzdYT29GNVQ1ZUtiblNSUFdRZjNlVmRjOG44Vw0KM1R0RldrbERVTzYrUDg2WXppendKK0h1a0lEVE9vdFBjQlpPcTZNL1hzekJ3VXdEdmIxMllQYVpqY1FCDQpELzRxMlBoVHR6aWExbVBzMlJ2ZFFOTUo5cElxdnk3TEJJNk9KZDdrSE1JTkM4SDdTRVBBcWlaekYxYzYNCjBWVmN0UW1aN1NuajVKOHRaNTFYZmQzbERzM2hFczBQNE5oZEkxUURkdFRzMUkvbGYyQ2QrVktEQlFDSw0KT1NwV0VQSDlCM1ZuYVlVNzFsWEYzRTV3ZXVNMFRKQ2RIUkgxZ04wdVlxSFo5TTBJS0pjeGdOSHBDaUZPDQpCVkcwdzdmTmplakxYOHdDMUx4YmRYTWExY0pVcDhpYjhXdEk1ZVMwS2FQajlZNnViMUpRcTlpUVdXVHUNCmVoQVlmVlBGZWZQVjN0VXZORjVZc1pHeUFxTWFwOEk3MmN1cjRpWTNSS1g3V0lzOHZTeTZIRGJtUzRMVw0KeWhQZ2pWSHMvV0I0YVMyUXlMcjFadUlDZUlkRHQvN1RKTHFOQUdmZ2xSVG52ZnEweEtwTUtIczVVNnA4DQpKS2h2TUIyR2gydVpZaGRiMjdoaElqMUtBNkh5cFpRUHhyZDJwaGpVRlNSa0NSM05QNW1ieHlXbWN1NHkNCm1vU08rNEhLazlhemZkNklySHE0YjFRckJ5Rkwvc28wVFBtNFBVQW4zaDIwMmhKTU54WWdRdnB4bmc5WQ0KcnZVcmljY2RMUFpudTQ3MTlSbG9ZcTB3RVk1Y2paRHlQc0R3dG1Oa1hmRWJGbHdUekE2ci9tWndjalBEDQpKK0FBZ04vaTRjdkhZVFRFWHhPSEJDUTdsdzNuVzdzSS9zRHlSQW5UU25KODdSaU9pRE1DaEFhRUVmMDENCnJPM3gyYmplODE2STJjaTdPRDQvL2ljano1aEl5aWRqcFVOSUVEUGpESitLdE40QWF1QzdKa1p4d05KeA0KeEJ0cTNNYkZMREIyYlZZWmIwRUhxNUM1ZDhGZUEybjBreTNrTC9wVkVnRUhRSUtCelJIV1FyTnA4T2FjDQpMakpiVGFVOW9YamZMeUdqYTRISElPN0RkT29RTUtVYitLTS9rL051TktiY1o0c3NDWVRiUjhyc2xrRTQNCnpNclRac3h1QldubVhDdnI5ZHdQVmdXTGNOYStZcS9yRXNIQlRBTkxXaS84NWkyVkFRRVAvUkFJOVlpSw0KVEM1SzMyRDFrVnI3d0NqNU1NcVR5Q2hnUHJDMGI2NEpBLzVMeFRXRlhhaEc2RWwzaHdtMGxQODAvR2h3DQpBdjhFdW1xRTZqVUNnbTBaUWNqVVFPMEo0bVdmNDBLQ09zdkRVK01GTUdlQ3ArNDYzT3lURnJ4WmNIaTMNCmxsNjdpS0xGa1lNNDlwWSt1WVZoN1lRdm9nZERET2RaQXFPWmNlQXRnUGhiNU81UnUvcjEzVU92ZXBIZA0KamkvU0pHOTZoNzA0dURLK2RPOGM0dmtKN1Q2ZC9kRHUvYTlrazRvcGNuVm4wV3ZqRm9uU1BmcCtiOFFtDQpoY0ZERjBqbFBQdDVZNWoydll2REI5OXNNYUIwby9UVm53eFBnVEFuMkdRODF4dTcyOXo5ampwUnZocXQNCmJlZlA3TE5oTWhrQnRicXhVK01yTnZJUFRISXBOUmZJTDFwbzd3V0R4WlJudnpINGRCbk1jaGdiSmRHOA0KUG8raUsvcDlITkd6bkI0b3hHMVJkV2duV2Z0czdxUFlNQlpwdzg5ekFtbjV4Z0s4ZXYzdEJtTGVxdHIxDQo1T2hZYlgwNXJZd0gwUjJsbUc1SWQ5L3JOU2ZzRkpWTDJDQlVGUnFWOWpJc1NsdDAwUnBsUDBKNmwxOEwNCkpXc3d3Y3AzaHlvRlllS09GaCt3TjBITEJrUHBuR0x6eXdQYVduL3lRcFpqY25QcFZOQkNibjZDY1dFSw0KaE1ZeEFNakpsaWVTN25uNzhGMkZnWXVLSm5uREttSnpMOTBUM2tCdjc1WmJERklTQXpjdGhJL0tkQjU3DQo0ZW45YS9ya0ZjNkx5NnlUeHFuQ2xkaE91L1ZiL0ZpTHVFS1ZVbm9KcTZNTzFLeWI3aGFvYy9hVE51R3ENCkIwOGkvZGRMbUZnZ1RHNnh3Y0ZNQTcyOWRtRDJtWTNFQVJBQTFZU0xic2J1c2VZRnpjbEJabHJLRStRaQ0KcCs3THVmUkt2N3hDa3BYanFFZEJqMWwwOCtUNlFwZnEzUUdlVkdySDU4Q3dBL1ZCMzhXZmVIYVN6S2xLDQp3SDlVMVRHMFhqZG5wUm53eEZDQVpVUjA0NzdIVU9FQmRMZ3RUZWd3eGVGRjQwUUEwYllaZllHcHdKM2UNCm9ZdGJ4ejJkeDhTSHFKMWgzUUowNVhOUTNKQjlDK01YSWV3YW00K1RvWFptUVRSanI1V3JUb0VpeUxWTA0KRHpYQlIrYXB5YnlXTmhzeFVoTlcreUE0S0RXZHZYbnBMSDBUSno0VW9aTUpTQWVhcnk2ZDgzRHo5dmlsDQphUTBpWmJCWEprSWVacGxlbmlyQXF4bWYvRVduOEJKT20wS1R2Y2pxTW96dThPQm9ScG9LZytUUElSZGYNCllteERianJiMmxPeUI0b3VkWCs0WHZzVTlzamZiRzBrSk1iUldENXdKK2lxRjdvc3czUVhTMFh0SE41dA0KakxlcDh2akdWMVZTUHFxWlNtVkg1TXZSa1NraGtJeFd1c2Zma2J0a04rNXlGYzVnSWlnRmt3V1ZWcWpQDQo4RmZYZHFRcitrNlF3Uk9EbkRVR1l2K0ZEaFFVNjdxQlhQM2FlaG9RYTZON2dkMS9wQ1FnSG9zVzBTcGQNCko3bVZWcGIzVFZ3enYwUkQxTzZiNDNqbmY0bTZsdmdOZjlwUm1EOWxNSXZiaUJrM2t6WUlrUGVSZ0dIVg0KNi9VeVRwQXJSdjZrdW1wRUNVeFlJSDBYK3paRnVDNmdUbjRqZVJqb2k1S2N6UHRDRklwNGFFeWMwYjNnDQpHQWl1SWJWYkg5Vk4xSUtxZmViOG9HSStBZ2prQW91ZUxIV0tXTzVHdmRUOG9mZWx4Q2VYck1LN3RUSFMNCndkc0JwVlk5UnV4dFdiaGF0VWJyd0R2VzlVbXJXRG1naHVVSGg5VWthVUNjV3FvOTA2ZlQ2R1N1OWtUMw0KNG1PYnJqbGU3eXlSa3oyY3crVDMyNzRoeGZ3bmNqayszdUFtOW1iQzRCY3kvNDFwOGlOWHdZQjJyYlJqDQo1VjZtaFdiZ2RnbFpqcllWQ25QVnFrOThyN2haL1BKcENUOVB2OEtXMFZTakh5c3NmSWNqN1lobDhiT00NClJvYjE2Z0RzWUE5SjFTd1c2Q0owSnQxWEc5UTc2RkN5b1g2QnRNMUxWY3FHMlFLYUZoY3JQbUQzN3lubQ0KZDZkZUg4Rjk0K2doZnhVRlFuQlZUMGtsVzBBTnpWUnJwTWxSM1RoRUJFTHRTYUpOZ3IxbFowVTQzMVdVDQpUa0x4d09meWxjaEhsZFRMSzBPa0lLMlBySlc3R0dVSEdFVmNCbGJRT0dnUXFQMzFROXhhWVRBdVNHZEsNClhQc3BuT0hvYUZaZjUvcjZyVHBEdnBVekhRYWR6OTZtRDRLRk1XYTFVMy9iVzMzRnFFMGxCR2c2YXh3Qg0KRHo4UW1UMkFXUlJpc0RaUGZkU01NWUNnalFYZDJqQVo5U0ZzY1ZSODVaUDlqTEIyR200OWhkei84WktmDQpOc2dPditZMVIrN0hIMjFpNU1VVDlLYTB0bE9LcGVFd05vdklyOGpYS0tFcjdraEx2SnJ4TnNCSFk5blMNCnBOb0V5eHZBS2xXMXdSdm82VnNJVFhDQUp1bmpoVVFyVm9TbUJtYktuQWZZemkyOTRiNG5GYjAvYkZxdg0KaFIzb0hKcUs0bm9MWXpLZFpBVEJIWGdzNlF4Vm1oR2VQajJrd1JBYllHNFR1SWZKNkNnMHBSaXU2NzZsDQptMGlMaS93WFF0VDc2bmZZWDhiWVVtaDV2bHYvTW5LcGZBdlpDM1JDNXVuZFhYeWhHTm9zY2I1eWp4V1ENCmZwaEI3YXNBdUowMlk2VktCeDBQMk1CVDVOdnlPU3o0RWcyVUljWTdZV0tha0NjRWRsQUNsbEVMRzE1Vg0KSCtUQ1JmNGNqUStCekFKck9LZFIxOGkyTEdOR2ZWVzFmMUN4K2JYQzl6YnBmMjdBNjVxNUpCZGpidG9BDQpjb0ZKV3NPcmYyNjl0YnZFQUFtYkE5c1ZQbkN4bnk0b2xXT1RDVmFudmJjSC8yQVVTMTdoDQo9M0RwL3hwDQotLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tDQoNCi0tLS0tLXNpbmlrYWVsLT89XzEtMTY4NTU0MTU0NDIxNzAuODkwNjc0NzkwMzU5OTkzOQ0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW07IG5hbWU9IndoYXQnc191cD8udHh0LnBncCINCkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lKjAqPSJ1dGYtOCcnd2hhdCdzX3VwJTNGLnR4dC5wZ3AiDQpYLUF0dGFjaG1lbnQtSWQ6IGZfVHdScW5nSEJKQlR1V3Btc1lraklzSW10Q2l6eXFUQGZsb3djcnlwdA0KQ29udGVudC1JZDogPGZfVHdScW5nSEJKQlR1V3Btc1lraklzSW10Q2l6eXFUQGZsb3djcnlwdD4NCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NA0KDQp3Y0ZNQTB0YUwvem1MWlVCQVEvL1UyaVRheFRzK0dKMlZNeGc4N2ZGSXhqa3o1UlhoaE84NlQ1QStiUnJBM0x1VXJRYVhJYllrd2NxDQpRbG9rcFJSbXFzOEhscE0vcFFyOHl6MEExSEJKa3JqV2VLY0tTSjZteFVyMEgrM2h1eGhPalAzNVY4N1ByK016dk0xQW5IeEJvckZuDQplZjRycXN1MXVhSS83bnk2a3dVUkdDekJwcW5MenpWMFNVemdYUmNVY3hvb0JVcjZCc3pNMXkydGczK1ZUTUVuM1UyRUtLU1Q2RVZwDQpRTDJrY3VLR0JyTTV6TG5yRXZ3SWhYckxja3JmNmZITEZRQTgzb295aW9qSDBYQ25zSWNnbjk5OUxJdmVaYjBMQVVMbFNERGdldVE4DQpwR0ZYU01DZ3RmMDJ4M2V1THEyMlVTYU1EVGlqa1FVZ3c0VFJSQmlmVmdlWDdmZkowVjBoUUxwcFVPUDkxT1dndTgxTFgrQ2JVSnVSDQo1U28wVzhqZ3Y3Wi9VSnlvUlo4UVBzblZDUDZLQm13ZUxYb3JrZEE0eXEwR1UvRE1nUktUNGtUVlp6N3NCekl5QVdLZC9aeVBtb3dmDQpoL284NVVxUW9HaHAzQUx1UnZDdy9XYlR6UkxjbEpzZndQMktsMW5DNVRYVnZha1FWZWZTbTJmaXVTaEhOZTFyU1pJc3RWWnA2ejUxDQpYdm02ak8yR2NZNmtSdUdScG5aL05NMWQ3YXVva3V0WnByZEVwbFRxeEN6dDVZZGU5dWVLWW5XdG5jQlB4WTJJVnIxYkh6ckNBTktuDQpJMUR4MFhkQ3VtY3E2SE5ENlRvN3hMZ3pmMVpKbFRySW0wLzE5d01UWnVWWjZhdTVKZmdzSzlGcysrbWgzOW1ZMGczQkUzbEJabFZuDQowUFUxMVppTXZNMFFtUCtuUWF2QndVd0R2YjEyWVBhWmpjUUJELzk3bnN1bkdPM2pOcVU3bXVTdjJtTGtnNE4vcHduQVZiWmdNS3dwDQplSTNLdGowT3N0UlFqNFJpU2tUQmJjdXQ4R1dWOTlzOVIvaUZDclRRc01YMHFPVVhpM3I3K2JlQzYvZ0ZBK1JwbExBWmdYYndabE14DQo5SXAvWnN2b1UyZlJITmR1MlNJcU5zK0JGUUlCcGlVUFdyQnowMXBKZGZPQS9JakRHSjNaWlhSd2VqQ3dvQitJbk1HaEVXSjZGVnM5DQpla2V1VzR3RjQwVnZzTHVTMUtwMzBWSTQrU0NINXR4ZjdjWDVqZERPY29QTjZuMS9CWkhXUTc3cWhoT2NiNVRvOGF3MGZLcFltRVVBDQpaM1FjN09VdEJseFovNGRIOHZmR3NVWm9pTE9SRldQalBaL2x4emY0a2pCTjhWQytmK0YzZWNsR1J5bmc4eWV6c3AvTHJ4K0hOVGxEDQo2aTdVMTMxelRCS0NnWUpXTjlpV0pSYktTZUc1Sk9QQmZKYVBmUkR1VVVxM2RrNW9rYllzVlgwN1JjV2plbHRCMzNUNVVBajZuajd5DQpkdHhzYVhqV1BNalFVVlBaS09JNjErUHJiY0RKQWhOZWZFa255My83eUYxQkpqdFY1NStYVk5hT0lxY096VHJJNWRwTEpENS9RcDFCDQpvWnhPYThBSkVpUWtDN3hLYlpycSt6R2pTZVhveTFqL2QxYVlBT3lGcWVHY1ozeTltZTVYTDBINUtHSFJsLzBBNmh5Q3docm5qWUtIDQoySVdZbzV6KzJaK25RSWF4cEJKNFlrOTBmSFBVRG5sbktFYVo1WjZ4cERSdHBSbWdHWmRkSFBLZUpQYlpFOE9tNHQrbVRzSDdLRjJODQpicnpaeVl2TVdLU1B3TXZRbU5jOXlnWDZPMjdmQTBHUzdzL0E3Y0ZlQTJuMGt5M2tML3BWRWdFSFFJVTFiNGU4Q25SbGdsVHppeGdWDQpqMTFwMHZ2Y3hWTUU4bndKZDlEZ1JZaG9NTElsTlNwUWp4VE0wTVp2ckgxbVVCbjBoNHBMY3FUemFYR2QwNFhrZVFzbGNZcXZ6ZUlGDQpUc0p0VnpDYVMvWHozTUhCVEFOTFdpLzg1aTJWQVFFUC9peWJFald5ZUd0UjZ3OWg3UzZtU3pPVDlJbko5VHNPTGR4MkF0QytWT1BNDQp6NlZVbDRCd3lOeTM4bURnOGhQeitxdVloWFBPbW8rMGQ3cjN1anhiL01lRDY1TS9FU1VzeHlqdHA4YmYvaVJXeERranI5K2FpUGdpDQo5TUFqMnFHTU14V3YyaEY4ZGU5b0w3OG9EMmk0YjEwR3VBOXViYi9YajUyUXhwK3lzS3I1RGRuTzZGMGxRWE5mb3ZpVW5kcDFQZ0RvDQpkdFpEYXdPT0tTR3V3VXVzVTYySi84Mi8vaVhMem93amIxSitrTVM1L0Z6V25qUW9kOUJwT3pFMmVBNXlZdGcvTUt0NWpTV3hSVkU2DQpvbXV3ZjZqUVVBQVMrblg5TXBGMmNvdEIvWEQwdVV3ZVFUVmhhRGlZZk1vcFQvc1hqVjBnUUViVDd0VENZSDBwNEx2WEVZd2FaYnNDDQptdFM0azJpalVFNkVxa0htTDhDS1EvVTB6TDdFTVhnMmhBRG5DTEpVOVhvem8rWGxudWxaeG16T0M1ajBxdHpoQjUveHVTVUZFa2tJDQpXei9Hb0UvRkpsZWJhTFNsTVZpM3ovN1dyVlpobnRabkpuTEQ4N0hCQy9pYTY4VkJPMTdNVXljNGtJT3BzSEwxYkVKRHFhRm1sS0ZjDQpHRnZHb0pjeG1UcWFrVDNtMWdraEZ3L2Y3bERwREE5bVk3MDhsUTZuMU54bWZ3Qi93dUhVT3RmT2NxeGFlTEcxbncvbGhvWUxKd0pxDQpWQnNDRzNTRDhzeXdVakRRV0dZajErLzRIRDFMbThNeTNWdytIMG1qZDlqbzJsbzlRN3NpZzlLbVRmZUcxY1BIamlIbW9wMlVyUmJBDQpFa1lmWTIxRWNLYkxpRnZZbGFnTVgwV0VXZ1ViT0tqWndjRk1BNzI5ZG1EMm1ZM0VBUS8rTC9MS1lVdDhCTTY2alZySzNHS1hFczltDQp6NTJvTlJEc1hGeUt4a0M4amRJeXhZUi9oNnZjVGlEck91K2xrVklkclFtcU1Ia0I0NWh2UU1DS3hGT0tDbDlSMC9FQ1Bxc2NqZ2hODQpwaC9tQm9LVWxoL1Z5cFVXTFhwcjU0dHRjcnpUN2pPYjFGRVpVeFR4blFaTVF2SzFaNE9HL1lxTm9uVFBDOUU3SFNVTExaMmcvMUZoDQpySG5mRWV3dFFGL0VnWTVEaGJUWDhlSmJEdFJ6ODBtTHR3MS9MVG9Tc1R1RWdMVndxTzFlRjF1Y2ttdWlva0pjNSt6MFZSdFlPQUxJDQp4WDQvdFdpZ0VzRDFxY3p5OUozbmUzK0RqTEZ1WmNPTW9jVzdMYXd4bnJFZFN4a0pmMkNSckNsNUM4N3lOcFBud3hvOWxtK1FrNzdFDQo1V251cE5sSXJKZnB4dW94dnJHWjhlV0ZGUWttNHRDT095SXVoWWFCM21qWENnbklOQTUzaUxzMXRDc2RFTDlaUy8rK2dDNHJUdkRGDQpOaldvakJER3Eva09aRGxPVkpDSEs5T01mc0MzZWxTYy9WSWN4NithcWYzT0JSRjhyeXp0OCtrRkNPRUhMTktpMVNpeVg5dEF1Z1hNDQpUTnNSWExYb2JpRWpPNnNHcGRMRXptSlp4eXh1MUlRL1lURDVCWTl5OEJmcXN2UWNEWjVLV0ppNkZKYVhwTnJNR0JSQU1PUW9nSG1XDQpuWHFnZGt6OFMrdmxnZ2NYMHE4N09abVJ4c1AzdW5TL254QWNseWNHZ2U3a1JPT0ZFdmJLQ25GY0xmZ3B0TFllQWVLdmhubzg5MnVhDQpsWDlYMTc1Um9aK1dPVm05K01GL1N0V21TNDF2ZEtJcEdXeFh4RTVyaFFsQTYwOE15NTNTUXdHRjdxNnZZclZQSUw2RFQxUmxBcmJwDQpkSTU0T1NwVEt2Q2JWQzdFMkt1NnZGbFYxU2tFeUlHeW1DNTFJRkRXUnNrRW9GOUxxdTl1bWEwQndLa1BKY0tad3JBPQ0KLS0tLS0tc2luaWthZWwtPz1fMS0xNjg1NTQxNTQ0MjE3MC44OTA2NzQ3OTAzNTk5OTM5LS0NCg==", + "historyId": "1408057", + "internalDate": "1685541546000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/exported-messages/message-export-188722a157fd54a8.json b/test/source/mock/google/exported-messages/message-export-188722a157fd54a8.json new file mode 100644 index 00000000000..a58d2230ebe --- /dev/null +++ b/test/source/mock/google/exported-messages/message-export-188722a157fd54a8.json @@ -0,0 +1,126 @@ +{ + "acctEmail": "flowcrypt.compatibility@gmail.com", + "full": { + "id": "188722a157fd54a8", + "threadId": "188722a157fd54a8", + "labelIds": [ + "Label_15", + "SENT", + "INBOX" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt Email Encryption 8.4.7 Comment: Seamlessly send and receive encrypted email wcFMA0taL/zmLZUBAQ/+IaLhBG0HJzwSPXGoEtHipEpUS9sn3tB6yrfr28KC", + "payload": { + "partId": "", + "mimeType": "multipart/mixed", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "multipart/mixed; boundary=\"----sinikael-?=_1-16855425387000.9701207325067771\"" + }, + { + "name": "Openpgp", + "value": "id=E8F0517BA6D7DAB6081C96E4ADAC279C95093207" + }, + { + "name": "From", + "value": "sender@domain.com" + }, + { + "name": "To", + "value": "flowcrypt.compatibility@gmail.com" + }, + { + "name": "Subject", + "value": "Test attachment #3505 2" + }, + { + "name": "Date", + "value": "Wed, 31 May 2023 07:15:40 -0700" + }, + { + "name": "MIME-Version", + "value": "1.0" + } + ], + "body": { + "size": 0 + }, + "parts": [ + { + "partId": "0", + "mimeType": "text/plain", + "filename": "", + "headers": [ + { + "name": "Content-Type", + "value": "text/plain" + }, + { + "name": "Content-Transfer-Encoding", + "value": "quoted-printable" + } + ], + "body": { + "size": 4126, + "data": "LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgRW1haWwgRW5jcnlwdGlvbiA4LjQuNw0KQ29tbWVudDogU2VhbWxlc3NseSBzZW5kIGFuZCByZWNlaXZlIGVuY3J5cHRlZCBlbWFpbA0KDQp3Y0ZNQTB0YUwvem1MWlVCQVEvK0lhTGhCRzBISnp3U1BYR29FdEhpcEVwVVM5c24zdEI2eXJmcjI4S0MNCm5mM05yajRQUkd3ZHUzUlRiNUkyczljQ2xocmJtWXhpdlBMalRGSk11dUo1a0FlSjZ0VjNxMVpodWd5OA0KdUNWRUMwbEF1d0RITWZiNUk4QjhwM3BEeDRkMktrWElKd1lyaXVuNEo0ZTNFV2RzS1FkNmZLSUNycm56DQpxYWlsZ0U2bjRCbkZNODg0Ujh0TnB4L3g1SnMwRlVXSUxVWVdRZ3cvT0kvdkZFd001NjRqQ1A4SnBYMnoNCjZtWm45OXFvRkd2Q0VNaVVhN3F2WTZKTnhtTVFFZVNXNFhldUo1QkNYZHlmeWdjY0JiSlVGbHVEVENTQg0KbTltREY2Mk1zdDMxM3A5c2IrUkFPLzJxM2xraTlIeG43cEg5U29XNmg3YVdSbmozOHBBZzNXYjJXdmdQDQpIV0RsbDRCalNKdHNhdHBSOGFLbnhQN3BVN0JXUndNUjg0dmw4TnhLVUNROU9GdTdzS09HQXVQOTBZOVANCmoyekdwS0pLeCtOdnpDTHVlK2NHTDdqSTZGUitHQ0NqYmVTcWRPSUxPSE8zU1Y1cVFyaWdtM0V0d0RVYw0KQWI5UkxlSlpLVFdweXlLOWNFVm5LdFkwMlozd1hoNjRiS0J3Wmd0ZVNoMkNkTFBoMjFza0R5NXlyRkwyDQptbVh6dWJISWhDVThUa2NHdkIxZ1h4ekV3dTRydllPaWR0M01HbzF2Rk5hY0hZbkVSTHgvaE9pRDJWMzYNCkhKa29yVk5UclhLeWRXYzhRS09CRnNmSkRnb1NJN2RINTByUU9zVDFmWWRVdjRQdG1lTVNMOWI4OG1Vdw0KZWxzUkVxUXVacG9EVGRvVXg0S2tBdzNxc1RJUDRka2dtMzJtM2NaUTlQUEJ3VXdEdmIxMllQYVpqY1FCDQpELzk1WjVRaHBpTWlGSWRoa3lZdDc5S2xnbnMzVS9zQzhSemZFdStHRlBPWmVVK2c3eGpqZHlMYlZZOXcNCjNCa3c3S1R3VjB0eksxNWkySStVdnVhZXRmY3VhUkp1SFZ5MlZlSk9oanhIRGNqcVl4OGVDUFNzdmFlbQ0KSVhYSTFQWkF2RTNRVVFuOVFNWHJPelZ4K3ZTY21YZmR2ZjZjaFpwUDJlWndsdURHanlHZU05aTNjZkR0DQpielBkcXVnLzBPU25Rb2lQaDk4czBhTWsya1FZT2Z2dXJPbmZGM0tBOWlGQVl3aTVLZnNWODhBSXNJUXkNCnVFbDI1KzdMckQyd29reisydVdDOGZkSjNLenhsbHVsSGIyUWJCUi9wRGZzOEJQRTh6dTdKWVdLc2RoVg0KbGJxdFNwdTI5Z1ZRWHRka0xLblUzalhpSmJiT0FhUUVNc3gwZHYyejJBNzlSQkh3WGZZclN5cFJDQVlFDQpsUnlHM3dPZ2tybTVtSGQxenpXQXJkcnVMQnFLQjNITUpDc2p2Y2ZIVU9ZczRqQUNMNzM2UFFUR2NiNEINCmRJaDk4M2x3cE5JVlY0VWN6ckdsdC9qT1daUTlRald3MytBaEFKajh1dmVEbUhGS0U3UTkrRWJNdXRSKw0KekxhUWxCNGc4RlVTZmVBVUZiVDRoK1FyNXc4Zy9PSVR0NEptODNtdDM3cThLLzlaRFBrczlCMmJ5WE13DQptOW9wcWNTTHVUUldQeDkxbm1SU0JVRy9rN0J0R2w4VUpPVXptdm4xMXQ3ODBHMnZ0QVc0UnZyWjFXVjQNCnlzSFFtTXRKdHptei9rTGpBNUlSbGhZbEJWSW1pVFhsMndaRnBuQXlXMzN2WSt2MVRSWlhLVFZteHdIcg0KY25WVWxEY1U3SFNyakRaVzVGcXpMSVpFWXNGZUEybjBreTNrTC9wVkVnRUhRTkx0WDlwV1hLUnVxVElFDQpCdGZ4Yk1GdnBBOTExbVJ2Q2pMRldTaFBTTWwwTUxGb0JYa0tFWDFpT2ZQQlJSZmZGd1plRmV1UGMxSE4NCitXUUFBZjRuTGRJeTljbVUvaHVGNUx5cEJxbWpCSVkvK01IQlRBTkxXaS84NWkyVkFRRVAvMFdQMzYzaA0KSjhFSHpZK255ei8vN3ZUbTl2QTU5SzVOMzdhQllUd3VEWE5RRGhxN29tLzhmbFc4RzJLMnhBNEthbVQyDQpnZjIwY29Nb0tEWktFMmhwOWp5RUVsekc1OGJMRjZ0QkgybzEvbXBPL2M3SUtxOWxxR3N0V2ZrL2FYR00NCm5NU2s5SW1WZ3JEY21wTy9DTlpJVGl5Szh4TWlPcHlXL0VNWWp3M1VralBoUGtvZkJnTWV6ZUEwNHFQZA0KNm5sUHVhcDJacDZ4SjNXL1lvZEZyNTJieHFFLzJyNW1xcU9POWFhem5kN3ZFbmRGb2RvQ0Z5L3d2SGZaDQpMYkxTMGVPTUFrdUlOUjFmbUFFaGlJV3hPMDRPN003RHZZeFZWVUJ3QTdZemJuOHRXWDNNNjRSSEtaWFgNCnJYcVhxQnFwVmhNUUZPbjdPZXR1cG1mTFFIYTFJS0dMQmZ4MU15OWRTalVDZ2NoNW1VNlJvblBwUjlqcg0KT0YvSTd1SXlEelYydXNHSkhFMmRHSDZHUE51d1YxMTZsUVZacVlRK3ZDUDM0V3BoVmJBdXh1Q1FGWFNFDQpxTjBDZ2lvbjRtenB5RFBvTEFyL0FHVU96Zk5tRU5HRzhsQ1ducXlXb0xoY0FZWkoycFhhL25lVk14MmgNCmpOWmsyd0RVS0N4TmEzNTVRK2JucDcvWkRaQ3RKZWtISUt2OHN2Z2xpYVhWalNwUUgvSWlobitmZUxDQQ0KWW0waFZLU2lqMW1hTnI2YnVsMXJQRUdrTzhjN3dlVkJ3bVcrS08rR2xNNGdPWjhKMmdIcU1IZlZxcDRIDQp6ZHhUcnY3WnBtRllCYlNIQ0pSRktQbWlIQnJ3MUxqUzhzNjNPR3FKOEI2ZHppSDJaOWp6RmlnRS9ZWm4NCm8ydkxsNkV3ZmwwNWZBMEV3Y0ZNQTcyOWRtRDJtWTNFQVEvL2VYd1E0YlpTZ285Znp6REFtTzh6bGJaeQ0KRURTM2xGekg2RERiSzJVK1JqTFZHSDZCQ3VFd2hmRFgrS250cjZzcDNsSW5qZzZwelZIVHA5RTJBaGdtDQo3cG5uMzlNRlRiRUxRbTZmR0RCMkhpVmIxdVk3bllUMmt6Vnl0cWFsOEszUDdSenAxRXorQVdJVExJOWENClpXUzVUbFBxN2ZaVXJabnJsVnRMbDIvdTVXT1BxRzdyL0dWRXdQOUp2ak1yc2c4WE9BczZ0OVVRQ1FqZw0KYm9ocnhvZEN6ZG81TVBCZDVxZk5nQ2dHbWpKeG5Fd3FBVGQ4QXhHSU95UStNWGFDMlkyYnA1YWlpNVdvDQpIN21obW5seFdRQWprSXBCRTQwclRIdXdoTkFLeHNFSXhiR3o5TGlJaEduZ3QvMGVxNjlTaXhEMmx4S2INCm0zb1k2Z1dyeklrblBrd0U4aFNnek9uSzR0WmExdzU1K09WQ0NLa2lpWkZNZXNiZEJGem5WMUdBcDRRRg0KanBOcXI4amhCOXhpdTBlYVlkdXlEWTBMQXljOHpIbnBvQUJST2RrQWVsYlc2SFJCc1doU1lZUWZzZVJBDQpOQWszZXpMTHRrRUUzQzE0SmVVK3h6Q1hEaVAveTh4OE9SQnRYWklydXg2dUNNZ2dQdTFQLys4b1BPN1YNCmprRUc2Mk1uVnZVa1pqWVBnREROTUtvUjQ1WWt6SWlUZ0E0OWRFSkVScDVCdklXbGE2Z2tsVWtyVVk4SQ0KZG5odEtLV0Vmcno1TjcvVjFaSmZYU25qMHNoQ0hoRjZNbEFqMFRBenF5K1BuVVZPVWwvUm1McTdsU0NJDQpXanRCaXhpWGxlVnBxcWVoRFMwQVZ6dWNDTVM2TEhqV29TSGdNcVhVQ01BNVAxVUF0dkY4UWFBNGdoM1MNCndkMEI0ZjNacEtuSjRYVjVMOUQ0aHhZSzRuTGVCOGszS1VVRG1sVzVjVmQzR2xSY3BFWVBhK3dUa0NrTQ0KbGsxR0YvdkhyTVFJbVRsUTY5RWY4QTc2Vmt1NjdBNjhzc3NMa2RtRThIS1JpVWNxK0tnMisyZGJyK2l2DQpiSzkvZUIraktJSXpUQUVnMUExUGwyYXlvK2JwaDFodVEwQkVJNHhGRDhMYllrS1RaakdRSERydC85RG0NCk1qL2tiTUZkMFdhOGk1c01CZWtFZklicDVWSTNaMGQ5cHNCbnc2MXhZa0tENUdXZDNMaEdmb0dESGNKMA0KM0psaTgvRThyS0VybXJKRkNXQjdrdnFMaHFucVNsbWhLK2pGNmkvWmNVNmJ4YTd4MllkbUZyOG5qdkVsDQprbTJhYk1wUWNFV1YrMTRKQlFaRXNEY2NDQWZjdVVLRnorZmxKWG1Qc2Q0UEpLS2szOGx4dE9tNmdrcDINCkVRcTlyU1VDRS9qb3plTXViMVprUEhTVXI0ZTRWcjhmVUhodllmVzdKNHUvV1c0c25JVnRSeUhjSDV6dg0KcWZZWXhhSWpjcFk0RVhRVUUyMlRGNUdOejlmZVErWTlXT2c4akYybFRhQURQNmdCdE1SaS96YWdGY0hEDQovOXl1eEpUanhVTmpYcWhzdm1YakJINVhncGRFSlB0RVF2QlhHUDJ5djVCa2xlWUlTYlQxbldPdURqR0wNCk9vTjZydGZ2MXZHWGNuVEx6L2taYUhRVzlaV3dFcFVHd0lUclh4UGNnZCt3Kzl5U1VxS1hwd2tuakx3Rw0KOXdUMWJxM1I1QXIzck9NQ2hReVByRHRnVmJ1L1dRcVAxQ1A4S1RKTHY0SFBSY21JKys4bWlpU2I4cmNWDQpWU3FHZlZ2enR5QnA2RXJMbEhSc0UrTlpuQjB0UWlxZFQ4cG5ZRXcwbVVqajQvSUoydnNESEtSTkpUK0MNCnVJWnZFREhOWU4zb0V2dUJSWFdzUENKWEdITmd4bmhtQ2JSOWxKTUNYU2REaTk5azQzaUluZTNkSEFkUQ0Ka05wNVlzWXVDU1dNM0pVaG51SDF1dUpZQVpxVHgxL2hkWi9CWDJsT3ljU0dRcTFPc0trWUwwdHo3bU5YDQpqRFY0SUdpTjQ1cjU3S2Rna0xVRFRxUC9BWVRzTGJnY21zKzU0Vkh5NUNaSnBPTERGNDZVQS8wPQ0KPXh2VFkNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg==" + } + }, + { + "partId": "1", + "mimeType": "application/octet-stream", + "filename": "what's_up%253F.txt.pgp", + "headers": [ + { + "name": "Content-Type", + "value": "application/octet-stream; name=\"what's_up%253F.txt.pgp\"" + }, + { + "name": "Content-Disposition", + "value": "attachment; filename*0*=\"utf-8''what's_up%25253F.txt.pgp\"" + }, + { + "name": "X-Attachment-Id", + "value": "f_OivxFuNXGYTRUuVjHAXIazllRnAZpr@flowcrypt" + }, + { + "name": "Content-Id", + "value": "" + }, + { + "name": "Content-Transfer-Encoding", + "value": "base64" + } + ], + "body": { + "attachmentId": "ANGjdJ_0BXQyC0svBPYWA46s1t8WzhLrGdATdxlXUISZzptkykjxbJfUUJk0iKSXVXyipZWCPKjmLlXk2EUWix93Hw5hFf0vSYZgT_5Sg7RYr7c0Yc6FS-RfJs67b_LtIl5x6jKzK2Ek4sXdExpLriZl93sF_4oiCBYgom-_W7Tt1jCwdpJv_n2XyS5o_fYCRhod9CTq1T4QLBm97dolY7Mnqg3I3C8NJebK7kEo02qaCfJ_NLdzVqMwSxniuZsb4fYKhk3bx4OMnPSQbQlPGums6ZuAdLxZqoD-t_G6DmacJbCV2ENtZQy6kA-9uHfnhvAfKLcV0HWDdilTSEYLFj4PzLuOSIrsbycy0jMwz28zWGelASipGsDifxeyu2z88bn-qnVnlXOJ0xMBsjvC", + "size": 2277 + } + } + ] + }, + "sizeEstimate": 8369, + "historyId": "1408179", + "internalDate": "1685542540000" + }, + "attachments": { + "ANGjdJ_0BXQyC0svBPYWA46s1t8WzhLrGdATdxlXUISZzptkykjxbJfUUJk0iKSXVXyipZWCPKjmLlXk2EUWix93Hw5hFf0vSYZgT_5Sg7RYr7c0Yc6FS-RfJs67b_LtIl5x6jKzK2Ek4sXdExpLriZl93sF_4oiCBYgom-_W7Tt1jCwdpJv_n2XyS5o_fYCRhod9CTq1T4QLBm97dolY7Mnqg3I3C8NJebK7kEo02qaCfJ_NLdzVqMwSxniuZsb4fYKhk3bx4OMnPSQbQlPGums6ZuAdLxZqoD-t_G6DmacJbCV2ENtZQy6kA-9uHfnhvAfKLcV0HWDdilTSEYLFj4PzLuOSIrsbycy0jMwz28zWGelASipGsDifxeyu2z88bn-qnVnlXOJ0xMBsjvC": { + "data": "wcFMA0taL_zmLZUBARAAjucslyWooO0OKxy4uVhc56QF92itic3kqc-DOxLFl4szMfAhsuYRIkSKkXN4UPKISI-i00xWqQpIZVZl_RldNrlzmvQzJLMIWjSK7Z_aocsaveNO2jj2GEMSNHQ0iYJ9FuUr2LmsAIASJZOzG9cwBNZZO0IxnhPURHUWTJtms8DqDPTIaOpFw4EOk9WwmmKBNqQvgAyGsZA2iS0PrEmlLdT098urhGZcLq9-1K8RSALAN7RHBuqQXmWrxoEmylwNJTlM5vMs5pllV7y2vBVgucTGvRlGbqzhLk5zc8Sf-Bg7Tf4u5Ztd9yEIzGmrVccDc2VQzSpym_fLEbcpgW_-zjlv0yKSlk-TwWIQBF3wPiULGwb0LtUnDveHQd1gGIlPcUSgtiRG3_5gT0qqIQdwvg3dpKNHrCyFi0Ppv8leTYBdeyPjo3snuFHqBTdcGUFoCRGS7NsGBUAH4Zg14F9feRsnTpOsqF36bG-psp8ST6HBgTyfbsgmud5eWEAy_FdUguWEW4-gRHU2WMq9GczOyVlxpZ1Lq_lgvsjLso0QHpbl2Uo90Njnjk4yX3GlXQyNoAZw9WdbEFftSA_TUeuS5yPayShQLvrF3OWV-PdBJRt0BBqKXLC6JRdSeuFJQpr1yEqBgkuNk2J9ZTk72MfCcrN9WmP9t7VCxVwSJSzmqlzBwUwDvb12YPaZjcQBEACaXLHIcl7hEWgGil19LABocL2ofKXbGXxeO2-RAWR4SfqHbk2wNJzWdqBgZVYUuMBai7jTt8ct1eeNs9Et0_eouHYJ-uU-CS6lX0M9dQLieQHGijnb-flD8M_Az_8YI4Ip4ii0OnEGavdjGPE_opxOjC4vl4ZEjgEyXKgwSSEuvuWNQqRDMWlzM3kpZ0B1FhzDIgeJYwpJsVcyE19DIv0y3g9L3TqqezO6oVcboU54u_ZDqbAALUivcPSFvCMiVz_UujnREz8mZHnQd2K4da7MS-UHfiADBOBX6NlPJP6vY-cZVPDAxy6yAKWfcpYxJZK8bvP3a6DpdIPMzNBpaEsmHlBmA7AbG4hkitm1Eh5ic-mYNBq5yphXFUvLZASM2ORdZUflwFML8p1Sr9rc6lGfXiLUjF1lAOvIvUnAE_fnQc83WOYckJLWqjqfF8wFixaztMzXJsBuWHYLSHYNyNMJQIkgmDi10srX10m5gLBMg9mXKY8TISgsKb4WT0ELOvP4qJ3pbcJtflVVc8p1AfgTfcx_CXxdqZuH2WvKdY3meOA1nSlJew9Ca77Qa6UONtM6FcB4bBwPFaLkISKwfcLaJ7sR3ONZJ95rlOVMlSJlT3bAf7ppvrjsvGz-vv-6nda-xusSUvQSmPjbQ8RDj0VyEsKWKRR64f2DU4krrnTb_MFeA2n0ky3kL_pVEgEHQAr2SfCUmlIvOzVLBEI2hYC5jR7gyYUH0p_rVwf2wGEVMDcwqAr2hAOHfjKh6wZjHefIMvqJEXNfCDX7R6JTQSGsyDBRrSvdP4-JO8j_co2Z48HBTANLWi_85i2VAQEQAKCWTOOCwDmo1M_cTNtBmCKDJscFj2nWeRZq5bjtU2hsKGmlQwUPLsYln7FPZIljrOhZUNalj06w9eWcmQP_45dOIebNkeeySPyNGcgE_h7AH4e2dCr0KRM3KtH8MiQMV1tiFlXzSk96jggw5DOf9AFO8z61jfOLhrmqAXuE9GFjN_7aKjk21XDho-ZBFhTAu226B2ghhfVeqC4Qb-rf8EVz0SBeDDB17qy3IXiSxOlMXDD6HuBXFxwF9q75dr7-Ms_pdJTQenh6JHgeNyxpRzvG9Hfb4zkgVbShXhLsa4IkqjQXsqJBhHHEFbTGJvUITyget7Xec6GZ_FRW8lmGOkrkRigx1Hg4wjOSffuJRd1nZ_0njDZNtXkwOi5RMJ5EH-J-NMLNeHwOWo7AlH3atVBpvS67wISXgdI_CQ5SzxQ6_qUQDpOHGKIT_ySdyLsUHl-jnscIAN_bNVYOqwkrXGtC030I8RmSgY44oiMVIwobFNlCwG4r0b4o4sSC3h1l94OIIuxS8TrhZc7Drx2NIvDv0HUVGm0GGPRoII7yUfE3rmtksjZ7IFBjtoAe-zlF2aS2bw__WeoZxO9wH-Dd2UXqsdGW7hLFjXX1W1sZPKT5kv2QObyYdQExcqs7rg86mdnL6E29-mnk6hQ38_pGb60whIP-RLeqR4yRVxdTvPk9wcFMA729dmD2mY3EAQ__dDXObgsBS7ey6Vj0abCScZCw_yfhbpdRbCKDnLs1nLg5CAma_nvWGOBT5R_LlNZcEXmGtdYfJTVSZG0bnnClypn_iWqhexv-tSS3Nxd95cYmdo31SHjqr0tAlB_vnNI94Rezb5ySQUJWwG5e0pxG_xexfciWEo7EpuglqIDfFIA8BPxdLv3mKu3VQmvS8zGsX3bjyrDEoeExtaocqIt8JM-D5IT7RNTvJzTbXurRBrLTNMcOPWS_8R0N4DOPpvWKqxyxi-gjgBBmph_v5SGT4oPh_4a37O0MJmrDwaAdkNB_t2Fz2CHFsghbYffkmyO9YoUyxUhxDPtAeojwi3_BzLMsbN46rpuAe8WhOjoQoaU6jALkDoZZxN3dsY1jFVn62Q-ThWFsHWISMRT3EhFEehnt2U0nI3RhDhIIJGZx-IrGmuDlpo3BiQDECieW78sIPp6_Pz-fv6ZGkakQmXf1E98QO7qVPYplsMicbE5aXskiH9rPo0PzqYkK1HfLwhxHfhFqGNvOfs_qPpdvXw2XARjN1Rld0RYWUDnmyv7Tn5VFGCg48qSPAD2XELPMlk66B4LP5qj1GozxDdbZvoJ--gKGsLoAZkduIdS0aWwpuJZm1KaViK9juDjm809IAPxPSSd60kStSJxywaHI84bPZBsDTco9TJFmIDm_URllIzTSRwHY_qR1p8E47SZowbO0zG8komX36reOn2HHHhhZejSewkdhVVQOUskTx9T2yApIuR9InDxGLFdqNNYtTk9ITNTCe-duCvJK", + "size": 2277 + } + }, + "raw": { + "id": "188722a157fd54a8", + "threadId": "188722a157fd54a8", + "labelIds": [ + "Label_15", + "SENT", + "INBOX" + ], + "snippet": "-----BEGIN PGP MESSAGE----- Version: FlowCrypt Email Encryption 8.4.7 Comment: Seamlessly send and receive encrypted email wcFMA0taL/zmLZUBAQ/+IaLhBG0HJzwSPXGoEtHipEpUS9sn3tB6yrfr28KC", + "sizeEstimate": 8369, + "raw": "UmVjZWl2ZWQ6IGZyb20gNzE3Mjg0NzMwMjQ0DQoJbmFtZWQgdW5rbm93bg0KCWJ5IGdtYWlsYXBpLmdvb2dsZS5jb20NCgl3aXRoIEhUVFBSRVNUOw0KCVdlZCwgMzEgTWF5IDIwMjMgMDc6MTU6NDAgLTA3MDANCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOw0KIGJvdW5kYXJ5PSItLS0tc2luaWthZWwtPz1fMS0xNjg1NTQyNTM4NzAwMC45NzAxMjA3MzI1MDY3NzcxIg0KT3BlbnBncDogaWQ9RThGMDUxN0JBNkQ3REFCNjA4MUM5NkU0QURBQzI3OUM5NTA5MzIwNw0KRnJvbTogRmxvd0NyeXB0IENvbXBhdGliaWxpdHkgPGZsb3djcnlwdC5jb21wYXRpYmlsaXR5QGdtYWlsLmNvbT4NClRvOiBGbG93Q3J5cHQgQ29tcGF0aWJpbGl0eSA8Zmxvd2NyeXB0LmNvbXBhdGliaWxpdHlAZ21haWwuY29tPg0KU3ViamVjdDogVGVzdCBhdHRhY2htZW50ICMzNTA1IDINCkRhdGU6IFdlZCwgMzEgTWF5IDIwMjMgMDc6MTU6NDAgLTA3MDANCk1lc3NhZ2UtSWQ6IDxDQUtidUxUcEg5LUVpdlRQSmowSkJKOXR5VzU3X3J0cmk4N2dVRjRZZ2UtUWlPU0c1YWdAbWFpbC5nbWFpbC5jb20-DQpNSU1FLVZlcnNpb246IDEuMA0KDQotLS0tLS1zaW5pa2FlbC0_PV8xLTE2ODU1NDI1Mzg3MDAwLjk3MDEyMDczMjUwNjc3NzENCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbg0KQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogcXVvdGVkLXByaW50YWJsZQ0KDQotLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS0NClZlcnNpb246IEZsb3dDcnlwdCBFbWFpbCBFbmNyeXB0aW9uIDguNC43DQpDb21tZW50OiBTZWFtbGVzc2x5IHNlbmQgYW5kIHJlY2VpdmUgZW5jcnlwdGVkIGVtYWlsDQoNCndjRk1BMHRhTC96bUxaVUJBUS8rSWFMaEJHMEhKendTUFhHb0V0SGlwRXBVUzlzbjN0QjZ5cmZyMjhLQw0KbmYzTnJqNFBSR3dkdTNSVGI1STJzOWNDbGhyYm1ZeGl2UExqVEZKTXV1SjVrQWVKNnRWM3ExWmh1Z3k4DQp1Q1ZFQzBsQXV3REhNZmI1SThCOHAzcER4NGQyS2tYSUp3WXJpdW40SjRlM0VXZHNLUWQ2ZktJQ3JybnoNCnFhaWxnRTZuNEJuRk04ODRSOHROcHgveDVKczBGVVdJTFVZV1Fndy9PSS92RkV3TTU2NGpDUDhKcFgyeg0KNm1abjk5cW9GR3ZDRU1pVWE3cXZZNkpOeG1NUUVlU1c0WGV1SjVCQ1hkeWZ5Z2NjQmJKVUZsdURUQ1NCDQptOW1ERjYyTXN0MzEzcDlzYitSQU8vMnEzbGtpOUh4bjdwSDlTb1c2aDdhV1JuajM4cEFnM1diMld2Z1ANCkhXRGxsNEJqU0p0c2F0cFI4YUtueFA3cFU3QldSd01SODR2bDhOeEtVQ1E5T0Z1N3NLT0dBdVA5MFk5UA0KajJ6R3BLSkt4K052ekNMdWUrY0dMN2pJNkZSK0dDQ2piZVNxZE9JTE9ITzNTVjVxUXJpZ20zRXR3RFVjDQpBYjlSTGVKWktUV3B5eUs5Y0VWbkt0WTAyWjN3WGg2NGJLQndaZ3RlU2gyQ2RMUGgyMXNrRHk1eXJGTDINCm1tWHp1YkhJaENVOFRrY0d2QjFnWHh6RXd1NHJ2WU9pZHQzTUdvMXZGTmFjSFluRVJMeC9oT2lEMlYzNg0KSEprb3JWTlRyWEt5ZFdjOFFLT0JGc2ZKRGdvU0k3ZEg1MHJRT3NUMWZZZFV2NFB0bWVNU0w5Yjg4bVV3DQplbHNSRXFRdVpwb0RUZG9VeDRLa0F3M3FzVElQNGRrZ20zMm0zY1pROVBQQndVd0R2YjEyWVBhWmpjUUINCkQvOTVaNVFocGlNaUZJZGhreVl0NzlLbGduczNVL3NDOFJ6ZkV1K0dGUE9aZVUrZzd4ampkeUxiVlk5dw0KM0JrdzdLVHdWMHR6SzE1aTJJK1V2dWFldGZjdWFSSnVIVnkyVmVKT2hqeEhEY2pxWXg4ZUNQU3N2YWVtDQpJWFhJMVBaQXZFM1FVUW45UU1Yck96VngrdlNjbVhmZHZmNmNoWnBQMmVad2x1REdqeUdlTTlpM2NmRHQNCmJ6UGRxdWcvME9TblFvaVBoOThzMGFNazJrUVlPZnZ1ck9uZkYzS0E5aUZBWXdpNUtmc1Y4OEFJc0lReQ0KdUVsMjUrN0xyRDJ3b2t6KzJ1V0M4ZmRKM0t6eGxsdWxIYjJRYkJSL3BEZnM4QlBFOHp1N0pZV0tzZGhWDQpsYnF0U3B1MjlnVlFYdGRrTEtuVTNqWGlKYmJPQWFRRU1zeDBkdjJ6MkE3OVJCSHdYZllyU3lwUkNBWUUNCmxSeUczd09na3JtNW1IZDF6eldBcmRydUxCcUtCM0hNSkNzanZjZkhVT1lzNGpBQ0w3MzZQUVRHY2I0Qg0KZEloOTgzbHdwTklWVjRVY3pyR2x0L2pPV1pROVFqV3czK0FoQUpqOHV2ZURtSEZLRTdROStFYk11dFIrDQp6TGFRbEI0ZzhGVVNmZUFVRmJUNGgrUXI1dzhnL09JVHQ0Sm04M210MzdxOEsvOVpEUGtzOUIyYnlYTXcNCm05b3BxY1NMdVRSV1B4OTFubVJTQlVHL2s3QnRHbDhVSk9Vem12bjExdDc4MEcydnRBVzRSdnJaMVdWNA0KeXNIUW1NdEp0em16L2tMakE1SVJsaFlsQlZJbWlUWGwyd1pGcG5BeVczM3ZZK3YxVFJaWEtUVm14d0hyDQpjblZVbERjVTdIU3JqRFpXNUZxekxJWkVZc0ZlQTJuMGt5M2tML3BWRWdFSFFOTHRYOXBXWEtSdXFUSUUNCkJ0ZnhiTUZ2cEE5MTFtUnZDakxGV1NoUFNNbDBNTEZvQlhrS0VYMWlPZlBCUlJmZkZ3WmVGZXVQYzFITg0KK1dRQUFmNG5MZEl5OWNtVS9odUY1THlwQnFtakJJWS8rTUhCVEFOTFdpLzg1aTJWQVFFUC8wV1AzNjNoDQpKOEVIelkrbnl6Ly83dlRtOXZBNTlLNU4zN2FCWVR3dURYTlFEaHE3b20vOGZsVzhHMksyeEE0S2FtVDINCmdmMjBjb01vS0RaS0UyaHA5anlFRWx6RzU4YkxGNnRCSDJvMS9tcE8vYzdJS3E5bHFHc3RXZmsvYVhHTQ0Kbk1TazlJbVZnckRjbXBPL0NOWklUaXlLOHhNaU9weVcvRU1ZanczVWtqUGhQa29mQmdNZXplQTA0cVBkDQo2bmxQdWFwMlpwNnhKM1cvWW9kRnI1MmJ4cUUvMnI1bXFxT085YWF6bmQ3dkVuZEZvZG9DRnkvd3ZIZloNCkxiTFMwZU9NQWt1SU5SMWZtQUVoaUlXeE8wNE83TTdEdll4VlZVQndBN1l6Ym44dFdYM002NFJIS1pYWA0KclhxWHFCcXBWaE1RRk9uN09ldHVwbWZMUUhhMUlLR0xCZngxTXk5ZFNqVUNnY2g1bVU2Um9uUHBSOWpyDQpPRi9JN3VJeUR6VjJ1c0dKSEUyZEdINkdQTnV3VjExNmxRVlpxWVErdkNQMzRXcGhWYkF1eHVDUUZYU0UNCnFOMENnaW9uNG16cHlEUG9MQXIvQUdVT3pmTm1FTkdHOGxDV25xeVdvTGhjQVlaSjJwWGEvbmVWTXgyaA0Kak5aazJ3RFVLQ3hOYTM1NVErYm5wNy9aRFpDdEpla0hJS3Y4c3ZnbGlhWFZqU3BRSC9JaWhuK2ZlTENBDQpZbTBoVktTaWoxbWFOcjZidWwxclBFR2tPOGM3d2VWQndtVytLTytHbE00Z09aOEoyZ0hxTUhmVnFwNEgNCnpkeFRydjdacG1GWUJiU0hDSlJGS1BtaUhCcncxTGpTOHM2M09HcUo4QjZkemlIMlo5anpGaWdFL1labg0KbzJ2TGw2RXdmbDA1ZkEwRXdjRk1BNzI5ZG1EMm1ZM0VBUS8vZVh3UTRiWlNnbzlmenpEQW1POHpsYlp5DQpFRFMzbEZ6SDZERGJLMlUrUmpMVkdINkJDdUV3aGZEWCtLbnRyNnNwM2xJbmpnNnB6VkhUcDlFMkFoZ20NCjdwbm4zOU1GVGJFTFFtNmZHREIySGlWYjF1WTduWVQya3pWeXRxYWw4SzNQN1J6cDFFeitBV0lUTEk5YQ0KWldTNVRsUHE3ZlpVclpucmxWdExsMi91NVdPUHFHN3IvR1ZFd1A5SnZqTXJzZzhYT0FzNnQ5VVFDUWpnDQpib2hyeG9kQ3pkbzVNUEJkNXFmTmdDZ0dtakp4bkV3cUFUZDhBeEdJT3lRK01YYUMyWTJicDVhaWk1V28NCkg3bWhtbmx4V1FBamtJcEJFNDByVEh1d2hOQUt4c0VJeGJHejlMaUloR25ndC8wZXE2OVNpeEQybHhLYg0KbTNvWTZnV3J6SWtuUGt3RThoU2d6T25LNHRaYTF3NTUrT1ZDQ0traWlaRk1lc2JkQkZ6blYxR0FwNFFGDQpqcE5xcjhqaEI5eGl1MGVhWWR1eURZMExBeWM4ekhucG9BQlJPZGtBZWxiVzZIUkJzV2hTWVlRZnNlUkENCk5BazNlekxMdGtFRTNDMTRKZVUreHpDWERpUC95OHg4T1JCdFhaSXJ1eDZ1Q01nZ1B1MVAvKzhvUE83Vg0KamtFRzYyTW5WdlVrWmpZUGdERE5NS29SNDVZa3pJaVRnQTQ5ZEVKRVJwNUJ2SVdsYTZna2xVa3JVWThJDQpkbmh0S0tXRWZyejVONy9WMVpKZlhTbmowc2hDSGhGNk1sQWowVEF6cXkrUG5VVk9VbC9SbUxxN2xTQ0kNCldqdEJpeGlYbGVWcHFxZWhEUzBBVnp1Y0NNUzZMSGpXb1NIZ01xWFVDTUE1UDFVQXR2RjhRYUE0Z2gzUw0Kd2QwQjRmM1pwS25KNFhWNUw5RDRoeFlLNG5MZUI4azNLVVVEbWxXNWNWZDNHbFJjcEVZUGErd1RrQ2tNDQpsazFHRi92SHJNUUltVGxRNjlFZjhBNzZWa3U2N0E2OHNzc0xrZG1FOEhLUmlVY3ErS2cyKzJkYnIraXYNCmJLOS9lQitqS0lJelRBRWcxQTFQbDJheW8rYnBoMWh1UTBCRUk0eEZEOExiWWtLVFpqR1FIRHJ0LzlEbQ0KTWova2JNRmQwV2E4aTVzTUJla0VmSWJwNVZJM1owZDlwc0JudzYxeFlrS0Q1R1dkM0xoR2ZvR0RIY0owDQozSmxpOC9FOHJLRXJtckpGQ1dCN2t2cUxocW5xU2xtaEsrakY2aS9aY1U2YnhhN3gyWWRtRnI4bmp2RWwNCmttMmFiTXBRY0VXVisxNEpCUVpFc0RjY0NBZmN1VUtGeitmbEpYbVBzZDRQSktLazM4bHh0T202Z2twMg0KRVFxOXJTVUNFL2pvemVNdWIxWmtQSFNVcjRlNFZyOGZVSGh2WWZXN0o0dS9XVzRzbklWdFJ5SGNINXp2DQpxZllZeGFJamNwWTRFWFFVRTIyVEY1R056OWZlUStZOVdPZzhqRjJsVGFBRFA2Z0J0TVJpL3phZ0ZjSEQNCi85eXV4SlRqeFVOalhxaHN2bVhqQkg1WGdwZEVKUHRFUXZCWEdQMnl2NUJrbGVZSVNiVDFuV091RGpHTA0KT29ONnJ0ZnYxdkdYY25UTHova1phSFFXOVpXd0VwVUd3SVRyWHhQY2dkK3crOXlTVXFLWHB3a25qTHdHDQo5d1QxYnEzUjVBcjNyT01DaFF5UHJEdGdWYnUvV1FxUDFDUDhLVEpMdjRIUFJjbUkrKzhtaWlTYjhyY1YNClZTcUdmVnZ6dHlCcDZFckxsSFJzRStOWm5CMHRRaXFkVDhwbllFdzBtVWpqNC9JSjJ2c0RIS1JOSlQrQw0KdUladkVESE5ZTjNvRXZ1QlJYV3NQQ0pYR0hOZ3huaG1DYlI5bEpNQ1hTZERpOTlrNDNpSW5lM2RIQWRRDQprTnA1WXNZdUNTV00zSlVobnVIMXV1SllBWnFUeDEvaGRaL0JYMmxPeWNTR1FxMU9zS2tZTDB0ejdtTlgNCmpEVjRJR2lONDVyNTdLZGdrTFVEVHFQL0FZVHNMYmdjbXMrNTRWSHk1Q1pKcE9MREY0NlVBLzA9M0QNCj0zRHh2VFkNCi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0NCg0KLS0tLS0tc2luaWthZWwtPz1fMS0xNjg1NTQyNTM4NzAwMC45NzAxMjA3MzI1MDY3NzcxDQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTsgbmFtZT0id2hhdCdzX3VwJTI1M0YudHh0LnBncCINCkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7DQogZmlsZW5hbWUqMCo9InV0Zi04Jyd3aGF0J3NfdXAlMjUyNTNGLnR4dC5wZ3AiDQpYLUF0dGFjaG1lbnQtSWQ6IGZfT2l2eEZ1TlhHWVRSVXVWakhBWElhemxsUm5BWnByQGZsb3djcnlwdA0KQ29udGVudC1JZDogPGZfT2l2eEZ1TlhHWVRSVXVWakhBWElhemxsUm5BWnByQGZsb3djcnlwdD4NCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NA0KDQp3Y0ZNQTB0YUwvem1MWlVCQVJBQWp1Y3NseVdvb08wT0t4eTR1VmhjNTZRRjkyaXRpYzNrcWMrRE94TEZsNHN6TWZBaHN1WVJJa1NLDQprWE40VVBLSVNJK2kwMHhXcVFwSVpWWmwvUmxkTnJsem12UXpKTE1JV2pTSzdaL2FvY3NhdmVOTzJqajJHRU1TTkhRMGlZSjlGdVVyDQoyTG1zQUlBU0paT3pHOWN3Qk5aWk8wSXhuaFBVUkhVV1RKdG1zOERxRFBUSWFPcEZ3NEVPazlXd21tS0JOcVF2Z0F5R3NaQTJpUzBQDQpyRW1sTGRUMDk4dXJoR1pjTHE5KzFLOFJTQUxBTjdSSEJ1cVFYbVdyeG9FbXlsd05KVGxNNXZNczVwbGxWN3kydkJWZ3VjVEd2UmxHDQpicXpoTGs1emM4U2YrQmc3VGY0dTVadGQ5eUVJekdtclZjY0RjMlZRelNweW0vZkxFYmNwZ1cvK3pqbHYweUtTbGsrVHdXSVFCRjN3DQpQaVVMR3diMEx0VW5EdmVIUWQxZ0dJbFBjVVNndGlSRzMvNWdUMHFxSVFkd3ZnM2RwS05IckN5RmkwUHB2OGxlVFlCZGV5UGpvM3NuDQp1RkhxQlRkY0dVRm9DUkdTN05zR0JVQUg0WmcxNEY5ZmVSc25UcE9zcUYzNmJHK3BzcDhTVDZIQmdUeWZic2dtdWQ1ZVdFQXkvRmRVDQpndVdFVzQrZ1JIVTJXTXE5R2N6T3lWbHhwWjFMcS9sZ3ZzakxzbzBRSHBibDJVbzkwTmpuams0eVgzR2xYUXlOb0FadzlXZGJFRmZ0DQpTQS9UVWV1UzV5UGF5U2hRTHZyRjNPV1YrUGRCSlJ0MEJCcUtYTEM2SlJkU2V1RkpRcHIxeUVxQmdrdU5rMko5WlRrNzJNZkNjck45DQpXbVA5dDdWQ3hWd1NKU3ptcWx6QndVd0R2YjEyWVBhWmpjUUJFQUNhWExISWNsN2hFV2dHaWwxOUxBQm9jTDJvZktYYkdYeGVPMitSDQpBV1I0U2ZxSGJrMndOSnpXZHFCZ1pWWVV1TUJhaTdqVHQ4Y3QxZWVOczlFdDAvZW91SFlKK3VVK0NTNmxYME05ZFFMaWVRSEdpam5iDQorZmxEOE0vQXovOFlJNElwNGlpME9uRUdhdmRqR1BFL29weE9qQzR2bDRaRWpnRXlYS2d3U1NFdXZ1V05RcVJETVdsek0za3BaMEIxDQpGaHpESWdlSll3cEpzVmN5RTE5REl2MHkzZzlMM1RxcWV6TzZvVmNib1U1NHUvWkRxYkFBTFVpdmNQU0Z2Q01pVnovVXVqblJFejhtDQpaSG5RZDJLNGRhN01TK1VIZmlBREJPQlg2TmxQSlA2dlkrY1pWUERBeHk2eUFLV2ZjcFl4SlpLOGJ2UDNhNkRwZElQTXpOQnBhRXNtDQpIbEJtQTdBYkc0aGtpdG0xRWg1aWMrbVlOQnE1eXBoWEZVdkxaQVNNMk9SZFpVZmx3Rk1MOHAxU3I5cmM2bEdmWGlMVWpGMWxBT3ZJDQp2VW5BRS9mblFjODNXT1lja0pMV3FqcWZGOHdGaXhhenRNelhKc0J1V0hZTFNIWU55Tk1KUUlrZ21EaTEwc3JYMTBtNWdMQk1nOW1YDQpLWThUSVNnc0tiNFdUMEVMT3ZQNHFKM3BiY0p0ZmxWVmM4cDFBZmdUZmN4L0NYeGRxWnVIMld2S2RZM21lT0ExblNsSmV3OUNhNzdRDQphNlVPTnRNNkZjQjRiQndQRmFMa0lTS3dmY0xhSjdzUjNPTlpKOTVybE9WTWxTSmxUM2JBZjdwcHZyanN2R3ordnYrNm5kYSt4dXNTDQpVdlFTbVBqYlE4UkRqMFZ5RXNLV0tSUjY0ZjJEVTRrcnJuVGIvTUZlQTJuMGt5M2tML3BWRWdFSFFBcjJTZkNVbWxJdk96VkxCRUkyDQpoWUM1alI3Z3lZVUgwcC9yVndmMndHRVZNRGN3cUFyMmhBT0hmaktoNndaakhlZklNdnFKRVhOZkNEWDdSNkpUUVNHc3lEQlJyU3ZkDQpQNCtKTzhqL2NvMlo0OEhCVEFOTFdpLzg1aTJWQVFFUUFLQ1dUT09Dd0RtbzFNL2NUTnRCbUNLREpzY0ZqMm5XZVJacTVianRVMmhzDQpLR21sUXdVUExzWWxuN0ZQWklsanJPaFpVTmFsajA2dzllV2NtUVAvNDVkT0llYk5rZWV5U1B5TkdjZ0UvaDdBSDRlMmRDcjBLUk0zDQpLdEg4TWlRTVYxdGlGbFh6U2s5NmpnZ3c1RE9mOUFGTzh6NjFqZk9MaHJtcUFYdUU5R0ZqTi83YUtqazIxWERobytaQkZoVEF1MjI2DQpCMmdoaGZWZXFDNFFiK3JmOEVWejBTQmVEREIxN3F5M0lYaVN4T2xNWERENkh1QlhGeHdGOXE3NWRyNytNcy9wZEpUUWVuaDZKSGdlDQpOeXhwUnp2RzlIZmI0emtnVmJTaFhoTHNhNElrcWpRWHNxSkJoSEhFRmJUR0p2VUlUeWdldDdYZWM2R1ovRlJXOGxtR09rcmtSaWd4DQoxSGc0d2pPU2ZmdUpSZDFuWi8wbmpEWk50WGt3T2k1Uk1KNUVIK0orTk1MTmVId09XbzdBbEgzYXRWQnB2UzY3d0lTWGdkSS9DUTVTDQp6eFE2L3FVUURwT0hHS0lUL3lTZHlMc1VIbCtqbnNjSUFOL2JOVllPcXdrclhHdEMwMzBJOFJtU2dZNDRvaU1WSXdvYkZObEN3RzRyDQowYjRvNHNTQzNoMWw5NE9JSXV4UzhUcmhaYzdEcngyTkl2RHYwSFVWR20wR0dQUm9JSTd5VWZFM3JtdGtzalo3SUZCanRvQWUremxGDQoyYVMyYncvL1dlb1p4Tzl3SCtEZDJVWHFzZEdXN2hMRmpYWDFXMXNaUEtUNWt2MlFPYnlZZFFFeGNxczdyZzg2bWRuTDZFMjkrbW5rDQo2aFEzOC9wR2I2MHdoSVArUkxlcVI0eVJWeGRUdlBrOXdjRk1BNzI5ZG1EMm1ZM0VBUS8vZERYT2Jnc0JTN2V5NlZqMGFiQ1NjWkN3DQoveWZoYnBkUmJDS0RuTHMxbkxnNUNBbWEvbnZXR09CVDVSL0xsTlpjRVhtR3RkWWZKVFZTWkcwYm5uQ2x5cG4vaVdxaGV4dit0U1MzDQpOeGQ5NWNZbWRvMzFTSGpxcjB0QWxCL3ZuTkk5NFJlemI1eVNRVUpXd0c1ZTBweEcveGV4ZmNpV0VvN0VwdWdscUlEZkZJQThCUHhkDQpMdjNtS3UzVlFtdlM4ekdzWDNianlyREVvZUV4dGFvY3FJdDhKTStENUlUN1JOVHZKelRiWHVyUkJyTFROTWNPUFdTLzhSME40RE9QDQpwdldLcXh5eGkrZ2pnQkJtcGgvdjVTR1Q0b1BoLzRhMzdPME1KbXJEd2FBZGtOQi90MkZ6MkNIRnNnaGJZZmZrbXlPOVlvVXl4VWh4DQpEUHRBZW9qd2kzL0J6TE1zYk40NnJwdUFlOFdoT2pvUW9hVTZqQUxrRG9aWnhOM2RzWTFqRlZuNjJRK1RoV0ZzSFdJU01SVDNFaEZFDQplaG50MlUwbkkzUmhEaElJSkdaeCtJckdtdURscG8zQmlRREVDaWVXNzhzSVBwNi9QeitmdjZaR2tha1FtWGYxRTk4UU83cVZQWXBsDQpzTWljYkU1YVhza2lIOXJQbzBQenFZa0sxSGZMd2h4SGZoRnFHTnZPZnMvcVBwZHZYdzJYQVJqTjFSbGQwUllXVURubXl2N1RuNVZGDQpHQ2c0OHFTUEFEMlhFTFBNbGs2NkI0TFA1cWoxR296eERkYlp2b0orK2dLR3NMb0Faa2R1SWRTMGFXd3B1SlptMUthVmlLOWp1RGptDQo4MDlJQVB4UFNTZDYwa1N0U0p4eXdhSEk4NGJQWkJzRFRjbzlUSkZtSURtL1VSbGxJelRTUndIWS9xUjFwOEU0N1Nab3diTzB6RzhrDQpvbVgzNnJlT24ySEhIaGhaZWpTZXdrZGhWVlFPVXNrVHg5VDJ5QXBJdVI5SW5EeEdMRmRxTk5ZdFRrOUlUTlRDZStkdUN2SksNCi0tLS0tLXNpbmlrYWVsLT89XzEtMTY4NTU0MjUzODcwMDAuOTcwMTIwNzMyNTA2Nzc3MS0tDQo=", + "historyId": "1408179", + "internalDate": "1685542540000" + } +} \ No newline at end of file diff --git a/test/source/mock/google/google-data.ts b/test/source/mock/google/google-data.ts index 706f5045f14..9b3cc1bd03a 100644 --- a/test/source/mock/google/google-data.ts +++ b/test/source/mock/google/google-data.ts @@ -216,35 +216,42 @@ export class GoogleData { return msgCopy; }; - public static getMockGmailPage = async (acct: string, msgId?: string) => { + public static getMockGmailPage = async (acct: string, msgId?: string, htmlRenderer?: (msgId: string, prerendered?: string) => string | undefined) => { let msgBlock = ''; let attachmentsBlock = ''; if (msgId) { /* eslint-disable @typescript-eslint/no-non-null-assertion */ const payload = (await GoogleData.withInitializedData(acct)).getMessage(msgId)!.payload!; const fromHeader = payload.headers!.find(header => header.name === 'From')!; - const fromAddress = fromHeader.value!; - let htmlData: string; - const htmlPart = payload.parts!.find(part => part.mimeType === 'text/html'); - if (htmlPart) { - htmlData = Buf.fromBase64Str(htmlPart.body!.data!).toUtfStr(); + const fromAddress = Xss.escape(fromHeader!.value); + let htmlData: string | undefined; + let processedParts: GmailMsg$payload$part[] = []; + if (payload.mimeType === 'text/plain') { + const textData = Buf.fromBase64Str(payload.body!.data!).toUtfStr(); + htmlData = GoogleData.htmlFromText(textData); } else { - const textPart = payload.parts!.find(part => part.mimeType === 'text/plain')!; - const textData = Buf.fromBase64Str(textPart.body!.data!).toUtfStr(); - htmlData = Xss.escape(textData); + ({ htmlData, processedParts } = GoogleData.getHtmlDataToDisplay(payload) ?? { htmlData: undefined, processedParts: [] }); } - const otherParts = payload.parts!.filter(part => !['text/plain', 'text/html'].includes(part.mimeType!)); + const updatedHtmlData = htmlRenderer ? htmlRenderer(msgId, htmlData) : htmlData; + const otherParts = GoogleData.getFileParts(payload.parts, processedParts); if (otherParts.length) { attachmentsBlock = `
${otherParts.length} Attachments
` + otherParts .map( - part => ` -
+ part => ` + +
+
+
${Xss.escape(part.filename!)}
-
` + ` ) .join('') + '
'; @@ -253,7 +260,7 @@ export class GoogleData { msgBlock = `
Mock Sender -
${htmlData}
+
${updatedHtmlData ?? ''}
${attachmentsBlock}
@@ -275,6 +282,19 @@ export class GoogleData { `; }; + private static getFileParts = (parts: GmailMsg$payload$part[] | undefined, skipParts: GmailMsg$payload$part[]): { filename: string }[] => { + if (!parts) return []; + return parts + .filter(part => part.mimeType !== 'multipart/alternative' && !skipParts.includes(part)) + .map(part => { + if (part.mimeType === 'multipart/mixed') { + return GoogleData.getFileParts(part.parts, skipParts); + } + return [{ filename: part.filename || 'noname' }]; + }) + .reduce((a, b) => a.concat(b), []); + }; + private static msgSubject = (m: GmailMsg): string => { const subjectHeader = m.payload && m.payload.headers && m.payload.headers.find(h => h.name === 'Subject'); return (subjectHeader && subjectHeader.value) || ''; @@ -292,10 +312,44 @@ export class GoogleData { ); }; + private static getHtmlDataToDisplay = ( + partsContainer: GmailMsg$payload | GmailMsg$payload$part + ): { htmlData: string; processedParts: GmailMsg$payload$part[] } | undefined => { + const htmlPart = partsContainer.parts?.find(part => part.mimeType === 'text/html'); + const textPart = partsContainer.parts?.find(part => part.mimeType === 'text/plain'); + if (htmlPart) { + const processedParts = [htmlPart]; + if (partsContainer.mimeType === 'multipart/alternative' && textPart) { + // consume both html and text + processedParts.push(textPart); + } + return { htmlData: Buf.fromBase64Str(htmlPart.body!.data!).toUtfStr(), processedParts }; + } else if (typeof textPart?.body?.data !== 'undefined') { + const textData = Buf.fromBase64Str(textPart.body.data).toUtfStr(); + return { htmlData: GoogleData.htmlFromText(textData), processedParts: [textPart] }; + } + // search inside multipart/alternative + const alternativePart = partsContainer.parts?.find(part => part.mimeType === 'multipart/alternative'); + if (alternativePart) { + return GoogleData.getHtmlDataToDisplay(alternativePart); + } + // search inside multipart/mixed + const mixedPart = partsContainer.parts?.find(part => part.mimeType === 'multipart/mixed'); + if (mixedPart) { + return GoogleData.getHtmlDataToDisplay(mixedPart); + } + return undefined; + }; + + private static htmlFromText = (textData: string): string => { + return Xss.escape(textData).replace(/\n/g, '
') + '

'; + }; + public storeSentMessage = (parseResult: ParseMsgResult, id: string): string => { let bodyContentAtt: { data: string; size: number; filename?: string; id: string } | undefined; - const parsedMail = parseResult.mimeMsg; - for (const attachment of parsedMail.attachments || []) { + const { html, text, attachments, from, subject, messageId } = parseResult.mimeMsg; + const parts: GmailMsg$payload$part[] = []; + for (const [index, attachment] of attachments.entries()) { const attId = Util.lousyRandom(); const gmailAtt = { data: attachment.content.toString('base64'), @@ -307,16 +361,36 @@ export class GoogleData { if (attachment.filename === 'encrypted.asc') { bodyContentAtt = gmailAtt; } + parts.push({ + partId: index.toString(), + mimeType: attachment.contentType, + filename: attachment.filename, + body: { + attachmentId: attId, + size: attachment.size, + }, + }); } let body: GmailMsg$payload$body; - const htmlOrText = parsedMail.html || parsedMail.text; - if (htmlOrText) { - body = { data: htmlOrText, size: htmlOrText.length }; + let mimeType: string | undefined; + if (html) { + body = { data: Buf.fromUtfStr(html).toBase64Str(), size: html.length }; + mimeType = 'text/html'; + } else if (text) { + body = { data: Buf.fromUtfStr(text).toBase64Str(), size: text.length }; + mimeType = 'text/plain'; } else if (bodyContentAtt) { body = { attachmentId: bodyContentAtt.id, size: bodyContentAtt.size }; } else { throw new Error('MOCK storeSentMessage: no parsedMail body, no appropriate bodyContentAtt'); } + const headers = [ + { name: 'Subject', value: subject || '' }, + { name: 'Message-ID', value: messageId || '' }, + ]; + if (from) { + headers.push({ name: 'From', value: from.text }); + } const barebonesGmailMsg: GmailMsg = { // todo - could be improved - very barebones id, @@ -324,11 +398,10 @@ export class GoogleData { historyId: '', labelIds: ['SENT' as GmailMsg$labelId], payload: { - headers: [ - { name: 'Subject', value: parsedMail.subject || '' }, - { name: 'Message-ID', value: parsedMail.messageId || '' }, - ], + mimeType, + headers, body, + parts, }, raw: parseResult.base64, }; diff --git a/test/source/mock/google/google-endpoints.ts b/test/source/mock/google/google-endpoints.ts index 6587f11f8cb..afa33dc3ca9 100644 --- a/test/source/mock/google/google-endpoints.ts +++ b/test/source/mock/google/google-endpoints.ts @@ -3,13 +3,14 @@ import { HttpClientErr, Status } from '../lib/api'; import Parse, { ParseMsgResult } from '../../util/parse'; import { isDelete, isGet, isPost, isPut, parsePort, parseResourceId } from '../lib/mock-util'; -import { GoogleData } from './google-data'; +import { GmailMsg, GoogleData } from './google-data'; import { HandlersDefinition } from '../all-apis-mock'; import { AddressObject, ParsedMail } from 'mailparser'; import { TestBySubjectStrategyContext } from './strategies/send-message-strategy'; import { UnsupportableStrategyError } from './strategies/strategy-base'; import { OauthMock } from '../lib/oauth'; import { Util } from '../../util'; +import { Dict } from '../../core/common'; type DraftSaveModel = { message: { raw: string; threadId: string } }; @@ -40,7 +41,7 @@ const allowedRecipients: Array = [ 'sender@domain.com', 'invalid@example.com', 'timeout@example.com', - 'flowcrypt.test.key.new.manual@gmail.com', + 'flowcrypt.test.key.new.manual.1@gmail.com', ]; export type MockUserAlias = { @@ -57,7 +58,10 @@ export type MockUserAlias = { export interface GoogleConfig { contacts?: string[]; othercontacts?: string[]; - aliases?: Record; + aliases?: Dict; + getMsg?: Dict>; + getAttachment?: Dict<{ error: Error } | { data: string }>; + htmlRenderer?: (msgId: string, prerendered?: string) => string | undefined; } export const multipleEmailAliasList: MockUserAlias[] = [ @@ -217,13 +221,18 @@ export const getMockGoogleEndpoints = (oauth: OauthMock, config: GoogleConfig | } const data = await GoogleData.withInitializedData(acct); if (req.url?.includes('/attachments/')) { + const foundAtt = config?.getAttachment?.[id]; + if (foundAtt && 'error' in foundAtt) throw foundAtt.error; + if (foundAtt?.data) return { data: foundAtt.data }; const attachment = data.getAttachment(id); if (attachment) { - return attachment; + return { data: attachment.data }; // Note: data (or quoted) field must be last in serialized JSON } throw new HttpClientErr(`MOCK attachment not found for ${acct}: ${id}`, Status.NOT_FOUND); } - const msg = data.getMessage(id); + const found = config?.getMsg?.[id]?.[format]; + if (found && 'error' in found) throw found.error; + const msg = found?.msg ? found.msg : data.getMessage(id); if (msg) { return GoogleData.fmtMsg(msg, format); } @@ -342,7 +351,7 @@ export const getMockGoogleEndpoints = (oauth: OauthMock, config: GoogleConfig | const acct = oauth.checkAuthorizationHeaderWithAccessToken(req.headers.authorization); if (isGet(req)) { const id = parseResourceId(req.url!); // eslint-disable-line @typescript-eslint/no-non-null-assertion - return await GoogleData.getMockGmailPage(acct, id); + return await GoogleData.getMockGmailPage(acct, id, config?.htmlRenderer); } throw new HttpClientErr(`Method not implemented for ${req.url}: ${req.method}`); }, diff --git a/test/source/mock/wkd/wkd-constants.ts b/test/source/mock/wkd/wkd-constants.ts index 91953c4d31f..2250cbe9d95 100644 --- a/test/source/mock/wkd/wkd-constants.ts +++ b/test/source/mock/wkd/wkd-constants.ts @@ -92,24 +92,6 @@ nmusEeYtrrMytL4oUohBVZk= -----END PGP PUBLIC KEY BLOCK----- `; -// only.on.wkd@signing.test -export const onlyOnWkdPubKey = `-----BEGIN PGP PUBLIC KEY BLOCK----- -Version: FlowCrypt Email Encryption 8.3.2 -Comment: Seamlessly send and receive encrypted email - -xjMEYwSypBYJKwYBBAHaRw8BAQdAemcNzRPSZIEa5LnljFUCjpDaYKE+NIzb -8/HdulmYTlbNH1Rlc3QgPG9ubHkub24ud2tkQHNpZ25pbmcudGVzdD7CjwQQ -FgoAIAUCYwSypAYLCQcIAwIEFQgKAgQWAgEAAhkBAhsDAh4BACEJEPtcd1B2 -gxxRFiEELyOUpuDorKxUIF1D+1x3UHaDHFG6bQD/QhRpAMQf0XNWcICs4yGj -buOprbmk1jbXveNvjM3xm68A/Rw4xKpYTcBwvnnFk8DRk8UUd1Tyby9nCUM5 -Rxyj75IKzjgEYwSypBIKKwYBBAGXVQEFAQEHQAeZ33tlMW1POXw7duxkZreg -+m8aHebGrIWdoAt0GSUMAwEIB8J4BBgWCAAJBQJjBLKkAhsMACEJEPtcd1B2 -gxxRFiEELyOUpuDorKxUIF1D+1x3UHaDHFH9AAD8DbMt2efR80LWUse6Zj9L -wWzzLlqxcoNz8vHQegOJcwgA/1YymI8CeDGKXCmext6mL6295e5tjUySwItc -lU5tXucF -=zRyT ------END PGP PUBLIC KEY BLOCK-----`; - /* // use for signing or decryption when defining tests const onlyOnWkdPrv = `-----BEGIN PGP PRIVATE KEY BLOCK----- diff --git a/test/source/patterns.ts b/test/source/patterns.ts index d4baa8f711b..f84c841ccf0 100644 --- a/test/source/patterns.ts +++ b/test/source/patterns.ts @@ -26,7 +26,7 @@ const getAllFilesInDir = (dir: string, filePattern: RegExp): string[] => { }; const hasXssComment = (line: string) => { - return /\/\/ xss-(known-source|direct|escaped|safe-factory|safe-value|sanitized|none|reinsert|dangerous-function)/.test(line); + return /\/[\/\*] xss-(known-source|direct|escaped|safe-factory|safe-value|sanitized|none|reinsert|dangerous-function)/.test(line); }; const hasErrHandledComment = (line: string) => { diff --git a/test/source/test.ts b/test/source/test.ts index 2d6ce922e0a..71125e7899b 100644 --- a/test/source/test.ts +++ b/test/source/test.ts @@ -152,6 +152,13 @@ test.after.always('evaluate Catch.reportErr errors', async t => { e.message !== 'Some keys could not be parsed' && !e.message.match(/BrowserMsg\(ajax\) Bad Request: 400 when GET-ing https:\/\/localhost:\d+\/flowcrypt-email-key-manager/) ) + // below for test "decrypt - failure retrieving chunk download - next request will try anew" + .filter( + e => + !/BrowserMsg\(ajaxGmailAttachmentGetChunk\) \(no status text\): 400 when GET-ing https:\/\/localhost:\d+\/gmail\/v1\/users\/me\/messages\/1885ded59a2b5a8d\/attachments\/ANGjdJ_0g7PGqJSjI8-Wjd5o8HcVnAHxIk-H210TAxxwf/.test( + e.message + ) + ) // below for test "user4@standardsubdomainfes.localhost:8001 - PWD encrypted message with FES web portal - a send fails with gateway update error" .filter(e => !e.message.includes('Test error')) // below for test "no.fes@example.com - skip FES on consumer, show friendly message on enterprise" @@ -160,7 +167,7 @@ test.after.always('evaluate Catch.reportErr errors', async t => { .filter(e => !e.trace.includes('-1 when GET-ing https://openpgpkey.flowcrypt.com')) // below for "test allows to retry public key search when attester returns error" .filter( - e => !e.message.match(/Error: Internal Server Error: 500 when GET-ing https:\/\/localhost:\d+\/attester\/pub\/attester.return.error@flowcrypt.test/) + e => !e.message.match(/Error: Internal Server Error: 500 when GET-ing https:\/\/localhost:\d+\/attester\/pub\/attester\.return\.error@flowcrypt\.test/) ); const foundExpectedErr = usefulErrors.find(re => re.message === `intentional error for debugging`); const foundUnwantedErrs = usefulErrors.filter(re => re.message !== `intentional error for debugging` && !re.message.includes('traversal forbidden')); diff --git a/test/source/tests/browser-unit-tests/unit-Gmail.js b/test/source/tests/browser-unit-tests/unit-Gmail.js index 2407bbbc34b..c9029aa58f5 100644 --- a/test/source/tests/browser-unit-tests/unit-Gmail.js +++ b/test/source/tests/browser-unit-tests/unit-Gmail.js @@ -19,33 +19,3 @@ * the async functions. For the rest, do not change the structure or our parser will get confused. * Do not put any code whatsoever outside of the async functions. */ - -BROWSER_UNIT_TEST_NAME(`Gmail.extractArmoredBlock helps detect bogus PGP message`).acct(`compatibility`); -(async () => { - const gmail = new Gmail('flowcrypt.compatibility@gmail.com'); - const extractedFull = await gmail.extractArmoredBlock('17d7a337b7b87eb9', 'full', undefined); - if (extractedFull.plaintext !== '-----BEGIN PGP MESSAGE-----\r\n\r\nThis is not a valid PGP message\r\n') { - throw Error(`extractedFull.plaintext unexpectedly equals ${extractedFull.plaintext}`); - } - const extractedRaw = await gmail.extractArmoredBlock('17d7a337b7b87eb9', 'raw', undefined); - if (extractedRaw.plaintext !== '-----BEGIN PGP MESSAGE-----\n\nThis is not a valid PGP message\n') { - throw Error(`extractedRaw.plaintext unexpectedly equals ${extractedRaw.plaintext}`); - } - return 'pass'; -})(); - -BROWSER_UNIT_TEST_NAME(`Gmail.extractArmoredBlock detect inline bogus PGP message`).acct(`compatibility`); -(async () => { - // original message - An OpenPGP message starts with this header: -----BEGIN PGP MESSAGE----- example - const gmail = new Gmail('flowcrypt.compatibility@gmail.com'); - const extractedFull = await gmail.extractArmoredBlock('17fbb5f1cd2010ee', 'full', undefined); - if (extractedFull.plaintext !== '-----BEGIN PGP MESSAGE-----\r\n\r\nexample\r\n') { - throw Error(`extractedFull.plaintext unexpectedly equals ${extractedFull.plaintext}`); - } - const extractedRaw = await gmail.extractArmoredBlock('17fbb5f1cd2010ee', 'raw', undefined); - console.log(encodeURIComponent(extractedRaw.plaintext)); - if (extractedRaw.plaintext !== '-----BEGIN PGP MESSAGE-----\n\nexample\n') { - throw Error(`extractedRaw.plaintext unexpectedly equals ${extractedRaw.plaintext}`); - } - return 'pass'; -})(); diff --git a/test/source/tests/compose.ts b/test/source/tests/compose.ts index bd4eb5b93b5..3b7cdef3fee 100644 --- a/test/source/tests/compose.ts +++ b/test/source/tests/compose.ts @@ -33,6 +33,7 @@ import { } from '../mock/attester/attester-key-constants'; import { revokedPrv, twoKeys2 } from '../mock/key-manager/key-manager-constants'; import { flowcryptTestClientConfiguration, getKeyManagerAutoImportNoPrvCreateRules, getKeyManagerAutogenRules } from '../mock/fes/fes-constants'; +import { Buf } from '../core/buf'; export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: TestWithBrowser) => { if (testVariant !== 'CONSUMER-LIVE-GMAIL') { @@ -1403,7 +1404,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te 'compose - hide reply all option button for signle recipient', testWithBrowser(async (t, browser) => { await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - const appendUrl = 'threadId=182263bf9f105adf&skipClickPrompt=___cu_false___&replyMsgId=182263bf9f105adf'; + const appendUrl = 'threadId=188722a157fd54a8&skipClickPrompt=___cu_false___&replyMsgId=188722a157fd54a8'; const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility', { appendUrl, hasReplyPrompt: true, @@ -1970,7 +1971,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te /* eslint-disable @typescript-eslint/no-non-null-assertion */ // get sent msg from mock const sentMsg = (await GoogleData.withInitializedData(acct)).searchMessagesBySubject(subject)[0]; - const message = sentMsg.payload!.body!.data!; + const message = Buf.fromBase64Str(sentMsg.payload!.body!.data!).toUtfStr(); const encryptedData = message.match(/\-\-\-\-\-BEGIN PGP MESSAGE\-\-\-\-\-.*\-\-\-\-\-END PGP MESSAGE\-\-\-\-\-/s)![0]; /* eslint-enable @typescript-eslint/no-non-null-assertion */ const decrypted0 = await MsgUtil.decryptMessage({ kisWithPp: [], encryptedData, verificationPubs: [] }); @@ -2048,7 +2049,7 @@ export const defineComposeTests = (testVariant: TestVariant, testWithBrowser: Te /* eslint-disable @typescript-eslint/no-non-null-assertion */ // get sent msg from mock const sentMsg = (await GoogleData.withInitializedData(acct)).searchMessagesBySubject(subject)[0]; - const message = sentMsg.payload!.body!.data!; + const message = Buf.fromBase64Str(sentMsg.payload!.body!.data!).toUtfStr(); /* eslint-enable @typescript-eslint/no-non-null-assertion */ expect(message).to.include('-----BEGIN PGP MESSAGE-----'); expect(message).to.include('-----END PGP MESSAGE-----'); @@ -3396,24 +3397,23 @@ const sendImgAndVerifyPresentInSentMsg = async (t: AvaContext, browser: BrowserH await composePage.page.evaluate((src: string) => { $('[data-test=action-insert-image]').val(src).click(); }, imgBase64); + const acctEmail = 'flowcrypt.compatibility@gmail.com'; + const accessToken = await BrowserRecipe.getGoogleAccessToken(composePage, acctEmail); await ComposePageRecipe.sendAndClose(composePage); // get sent msg id from mock - const sentMsg = (await GoogleData.withInitializedData('flowcrypt.compatibility@gmail.com')).searchMessagesBySubject(subject)[0]; + const sentMsg = (await GoogleData.withInitializedData(acctEmail)).searchMessagesBySubject(subject)[0]; if (sendingType === 'plain') { - expect(sentMsg.payload?.body?.data).to.match(/Test Sending Plain Message With Image/); + const data = Buf.fromBase64Str(sentMsg.payload!.body!.data!).toUtfStr(); + expect(data).to.match(/Test Sending Plain Message With Image/); return; // todo - this test case is a stop-gap. We need to implement rendering of such messages below, // then let test plain messages with images in them (referenced by cid) just like other types of messages below } - let url = `chrome/dev/ci_pgp_host_page.htm?frameId=none&msgId=${encodeURIComponent( - sentMsg.id - )}&senderEmail=flowcrypt.compatibility%40gmail.com&isOutgoing=___cu_false___&acctEmail=flowcrypt.compatibility%40gmail.com`; - if (sendingType === 'sign') { - url += '&signature=___cu_true___'; - } // open a page with the sent msg, investigate img - const pgpHostPage = await browser.newPage(t, url); - const pgpBlockPage = await pgpHostPage.getFrame(['pgp_block.htm']); + const authHdr = { Authorization: `Bearer ${accessToken}` }; // eslint-disable-line @typescript-eslint/naming-convention + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${sentMsg.id}`, undefined, authHdr); + await gmailPage.waitAll('iframe'); + const pgpBlockPage = await gmailPage.getFrame(['pgp_block.htm']); const img = await pgpBlockPage.waitAny('body img'); expect(await PageRecipe.getElementPropertyJson(img, 'src')).to.eq(imgBase64); }; @@ -3429,19 +3429,24 @@ const sendTextAndVerifyPresentInSentMsg = async ( } Message With Test Text ${text} ${Util.lousyRandom()}`; const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility'); await ComposePageRecipe.fillMsg(composePage, { to: 'human@flowcrypt.com' }, subject, text, sendingOpt); + const acctEmail = 'flowcrypt.compatibility@gmail.com'; + const accessToken = await BrowserRecipe.getGoogleAccessToken(composePage, acctEmail); await ComposePageRecipe.sendAndClose(composePage); /* eslint-disable @typescript-eslint/no-non-null-assertion */ // get sent msg from mock - const sentMsg = (await GoogleData.withInitializedData('flowcrypt.compatibility@gmail.com')).searchMessagesBySubject(subject)[0]; - const message = encodeURIComponent(sentMsg.payload!.body!.data!); + const sentMsg = (await GoogleData.withInitializedData(acctEmail)).searchMessagesBySubject(subject)[0]; + const authHdr = { Authorization: `Bearer ${accessToken}` }; // eslint-disable-line @typescript-eslint/naming-convention /* eslint-enable @typescript-eslint/no-non-null-assertion */ - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: [text], - unexpectedContent: [], - params: `?frameId=none&msgId=${encodeURIComponent( - sentMsg.id - )}&senderEmail=flowcrypt.compatibility%40gmail.com&isOutgoing=___cu_false___&acctEmail=flowcrypt.compatibility%40gmail.com&message=${message}`, - }); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + sentMsg.id, + { + content: [text], + unexpectedContent: [], + }, + authHdr + ); }; const setRequirePassPhraseAndOpenRepliedMessage = async (t: AvaContext, browser: BrowserHandle, passphrase: string) => { diff --git a/test/source/tests/decrypt.ts b/test/source/tests/decrypt.ts index 3837c988e49..49068245a9d 100644 --- a/test/source/tests/decrypt.ts +++ b/test/source/tests/decrypt.ts @@ -5,16 +5,21 @@ import test from 'ava'; import { Config, TestVariant, Util } from './../util'; import { testConstants } from './tooling/consts'; import { BrowserRecipe } from './tooling/browser-recipe'; -import { GoogleData } from './../mock/google/google-data'; import { InboxPageRecipe } from './page-recipe/inbox-page-recipe'; import { SettingsPageRecipe } from './page-recipe/settings-page-recipe'; import { TestWithBrowser } from './../test'; import { expect } from 'chai'; import { PageRecipe } from './page-recipe/abstract-page-recipe'; -import { Buf } from '../core/buf'; -import { get203FAE7076005381, protonMailCompatKey, mpVerificationKey, sha1signpubkey, somePubkey } from '../mock/attester/attester-key-constants'; -import { ConfigurationProvider } from '../mock/lib/api'; -import { onlyOnWkdPubKey } from '../mock/wkd/wkd-constants'; +import { + get203FAE7076005381, + protonMailCompatKey, + mpVerificationKey, + sha1signpubkey, + somePubkey, + singlePubKeyAttesterConfig, +} from '../mock/attester/attester-key-constants'; +import { ConfigurationProvider, HttpClientErr, Status } from '../mock/lib/api'; +import { ControllablePage } from '../browser'; export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: TestWithBrowser) => { if (testVariant !== 'CONSUMER-LIVE-GMAIL') { @@ -22,16 +27,57 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te `decrypt - detect bogus pgp message`, testWithBrowser(async (t, browser) => { const threadId = '17d7a32a0613071d'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const msgId = '17d7a337b7b87eb9'; + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitForSelTestState('ready'); await inboxPage.waitAll('iframe'); - const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); - await pgpBlock.waitForContent('@pgp-encryption', 'not encrypted'); - await pgpBlock.waitForContent('@pgp-signature', 'not signed'); - await pgpBlock.waitForContent('@pgp-block-content', '-----BEGIN PGP MESSAGE-----\n\nThis is not a valid PGP message'); + const plainMessage = /-----BEGIN PGP MESSAGE-----.*This is not a valid PGP message/s; + await inboxPage.waitForContent('@message-line', plainMessage); + // expect no pgp blocks + expect((await inboxPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(0); + await inboxPage.close(); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + await gmailPage.waitForContent('.a3s', plainMessage); + expect((await gmailPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(0); + await gmailPage.close(); + }) + ); + + test( + `decrypt - detect inline bogus pgp message`, + testWithBrowser(async (t, browser) => { + const threadId = '17fbb5db49ddc1eb'; + const msgId = '17fbb5f1cd2010ee'; + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); + await inboxPage.waitForSelTestState('ready'); + await inboxPage.waitAll('iframe'); + const plainMessage = /An OpenPGP message starts with this header:\r?\n-----BEGIN PGP MESSAGE-----\r?\n\r?\nexample/s; + await inboxPage.waitForContent('@message-line', plainMessage); + // expect no pgp blocks + expect((await inboxPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(0); + await inboxPage.close(); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + await gmailPage.waitForContent('.a3s', plainMessage); + expect((await gmailPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(0); + await gmailPage.close(); + }) + ); + + test( + `decrypt - backup message rendering`, + testWithBrowser(async (t, browser) => { + const threadId = '15f84afa553d8a83'; + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); + await inboxPage.waitForSelTestState('ready'); + await (await inboxPage.getFrame(['backup.htm'])).waitForContent('@private-key-status', 'This Private Key is already imported.'); await inboxPage.close(); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${threadId}`, undefined, authHdr); + await gmailPage.waitAll('iframe'); + await (await gmailPage.getFrame(['backup.htm'])).waitForContent('@private-key-status', 'This Private Key is already imported.'); + await gmailPage.close(); }) ); @@ -39,8 +85,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te `decrypt - show remote images`, testWithBrowser(async (t, browser) => { const threadId = '186bd029856d1e39'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitForSelTestState('ready'); await inboxPage.waitAll('iframe'); @@ -61,8 +106,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te `decrypt - show inline image when user clicks show image`, testWithBrowser(async (t, browser) => { const threadId = '1850f9608240f758'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitForSelTestState('ready'); await inboxPage.waitAll('iframe'); @@ -78,32 +122,41 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te `decrypt - parsed signed message with signature.asc as plain attachment`, testWithBrowser(async (t, browser) => { const threadId = '187085b874fb727c'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const expectedMessage = { + encryption: 'not encrypted', + signature: 'could not verify signature: missing pubkey ADAC279C95093207', + content: ['flowcrypt-browser issue #5029 test email'], + }; const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitForSelTestState('ready'); await inboxPage.waitAll('iframe'); - const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); - await pgpBlock.waitForContent('@pgp-block-content', 'flowcrypt-browser issue #5029 test email'); + await BrowserRecipe.pgpBlockCheck(t, await inboxPage.getFrame(['pgp_block.htm']), expectedMessage); await inboxPage.close(); + await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, threadId, expectedMessage, authHdr); }) ); test( `decrypt - parsed encrypted message signed with signature.asc inline attachment`, testWithBrowser(async (t, browser) => { - const threadId = '187ebe3cd1fae41e'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); + const msgId = '187ebe3cd1fae41e'; + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${msgId}`); await inboxPage.waitForSelTestState('ready'); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); - await pgpBlock.waitForContent('@pgp-encryption', 'encrypted'); - await pgpBlock.waitForContent('@pgp-signature', 'signed'); - await pgpBlock.waitForContent('@pgp-block-content', 'Check'); + const expectedMessage = { + encryption: 'encrypted', + signature: 'signed', + content: ['Check signature'], + }; + await BrowserRecipe.pgpBlockCheck(t, pgpBlock, expectedMessage); expect(await inboxPage.isElementPresent('@container-attachments')).to.equal(false); await inboxPage.close(); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + await BrowserRecipe.pgpBlockCheck(t, await gmailPage.getFrame(['pgp_block.htm']), expectedMessage); + await gmailPage.notPresent('.aV3'); }) ); @@ -111,8 +164,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te `decrypt - outlook message with ATTxxxx encrypted email doesn't show empty attachment`, testWithBrowser(async (t, browser) => { const threadId = '17dbdf2425ac0f29'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitForSelTestState('ready'); await inboxPage.waitAll('iframe'); @@ -139,8 +191,7 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te test( 'decrypt - encrypted text inside "message" attachment is correctly decrypted', testWithBrowser(async (t, browser) => { - const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); /* eslint-disable @typescript-eslint/no-non-null-assertion */ const key = Config.key('flowcrypt.compatibility.1pp1')!; await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, key.armored!, key.passphrase, {}, false); @@ -157,25 +208,27 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te `decrypt - render plain text for "message" attachment (which has plain text)`, testWithBrowser(async (t, browser) => { const threadId = '184a87a7b32dd009'; - const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitForSelTestState('ready'); await inboxPage.waitAll('iframe'); expect(await inboxPage.isElementPresent('@container-attachments')).to.equal(true); - await inboxPage.waitForContent('.message.line', 'Plain message'); + await inboxPage.waitForContent('@message-line', 'Plain message'); // expect no pgp blocks const urls = await inboxPage.getFramesUrls(['/chrome/elements/pgp_block.htm']); expect(urls.length).to.equal(0); await inboxPage.close(); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${threadId}`, undefined, authHdr); + await gmailPage.waitForContent('.a3s', 'Plain message'); + expect((await gmailPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(0); + await gmailPage.close(); }) ); test( `decrypt - outlook message with ATTxxxx encrypted email is correctly decrypted`, testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); await InboxPageRecipe.checkDecryptMsg(t, browser, { acctEmail, threadId: '17dbdf2425ac0f29', @@ -185,466 +238,656 @@ export const defineDecryptTests = (testVariant: TestVariant, testWithBrowser: Te ); test( - `decrypt - without a subject`, + 'mail.google.com - decrypt message in offline mode', testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['This is a compatibility test email'], - unexpectedContent: ['Encrypted Subject:', '(no subject)'], + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + t.mockApi!.configProvider!.config.google = { + getMsg: { + '17b91b7e122902d2': { full: { error: new HttpClientErr('RequestTimeout', Status.BAD_REQUEST) } }, + }, + }; + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '17b91b7e122902d2', + { + content: ['this should decrypt even offline'], + encryption: 'encrypted', + signature: 'signed', + }, + authHdr + ); + }) + ); + + test( + 'mail.google.com - "auth needed" notification is shown when processing armored blocks', + testWithBrowser(async (t, browser) => { + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + const msgId = '17b91b7e122902d2'; + t.mockApi!.configProvider!.config.google = { + getMsg: { + [msgId]: { full: { error: new HttpClientErr('RequestTimeout', Status.UNAUTHORIZED) } }, + }, + }; + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + // Check reconnect auth notification + await gmailPage.waitForContent('@webmail-notification-setup', 'Please reconnect FlowCrypt to your Gmail Account.'); + await gmailPage.waitAll('iframe'); + await BrowserRecipe.pgpBlockCheck(t, await gmailPage.getFrame(['pgp_block.htm']), { + content: ['this should decrypt even offline'], encryption: 'encrypted', - signature: 'not signed', - params: - '?frameId=none&message=-----BEGIN%20PGP%20MESSAGE-----%0A%0AhQEMA%2Ba5zJlucROnAQf%2BJc3kkQPIko5gnq0bN510e16pk%2FBNq3w00BWZZmqe8QZ3%0A2CDi1i8mJCTf0ax9zCjJmNEoK4sonX88ZtQ3nDX819ATeu8gi6cWTaaTrdtfI5wF%0AGoD3IgRiwOGJf3NAUSa8YB77%2Fpx6AL35je44uXHvstmmWrt4LMQBQaRUGHG51vxf%0AQKNx9hBHLOv83wGjjKoDOByb0Lf2sGIlECgeOHGfowKG3fH4NNO0kWbaLcVvM9Dh%0AgWjQQWWAWhZCuFmpYdIktYzC4CN7JaTRdGbyuK2syrsiWyc1tty%2FlV1XM06dwYO8%0A7xgdXTDbmVwujEtQJW1bJuOoI8DiuRbYfEgGSGADmIUCDANLWi%2F85i2VAQEP%2F1qR%0AiYLG5IMS60KJf89GK13PNeo1QzbNNYrNjxWyiEZOy7n0qZ1X7JWfGrRSx2Wqtesh%0AvzY5Dt%2FWQWVES%2F4sl54GO8Pjlhi6YjIn3wFyZryftOF4eXjoQ7dbbpoOsHhOizcD%0Ap3l4zXPRng8hC4gF%2FZ6XxCsFRHLXgDRsJKu5bZ8VEJvK2m1soG%2BCDl9s%2FDifjf%2FU%0AJVc3DWh7lQPGy%2B8TxkvHtvaD1ZbNSjOIfdmsybBS3Hk%2BSoaLb3MI%2Bv2clHMYnSKs%0A1Z2zEn21SBxrLd%2BYKWD5mBE9UZGyarANvvbMkiPGVkHzzUrfu6NjF9sVKoNLDJmu%0Aegjr6RWNv2CrHr%2BREQWRaQ4004Xfu2WRZkcZH7DLaOvIMlvi8mHNW1EplL2SrvF9%0AoH7YMev0j2x0BLEkrOWtFfRG7NpgMU%2FO1bDz3DD7uDHIgi32KJ%2BUhSYXqiMOlIPK%0A8wB39mCqgY1vD5bkw7l%2FVHX%2BfwU7QTAK2Lg7%2BUGD29VmJhso46Mpz1pbL0HZiuCY%0A9JRr1Cxi%2FXwKWXgng8ijIUhQ8%2FsDdUxuRIx%2FxgLCn%2BNy69MrjZnXE2T0W5%2BgBpuX%0Ac7KUdJwCUEkdiB%2FWlz4izdPUCBUnc0QAqCt7Ixx4S4Hn%2BU1lNfrECqJI14kbf27r%0ALmLiZqEB5WJHLBtUkegyFWr6WwHmqQFxtuu2Tg%2Fz0ukBkZDzODNz0eVQANEb%2FkWn%0AxaaH%2FDhvkx%2BDxKeyhi6LDfAtU7oOOo8C3%2BiTFzk%2BSsr2Tl6Mb6fuSSxxVc%2Fi1YZb%0AEOWEuw%2BTLGhH3nzWG1reM7N0q7lNVy5mz3V9cXRcvRUj7wYBhxf4LyBRtCq3lOUl%0AhfHf7U3zk6ZpIUCq146CbWVAy83jnKbJwzmlOCWoy1rVfbRg6%2BemShml3ugOCjfp%0AJVViuW33ZUEGYIeDHa8CihGn3ai0aN4CHQiuDe%2FA9tljFseYi%2BIdfVhIz10VRPBO%0AbRTW%2FnFDkVjI9E3Bd%2BH5%2Byj4LEbGFYfcSHMjgoMjS578p5dmbl%2FVeNt%2FwS9dxPF8%0A8iRV2tcSu5HbLhWGZJ1l%2Bcn6N1PwW6Rs9NrdfsMD7QNsyDU71hOz10asOgebxYNM%0AgFhhw%2FlxHig9iuNwO8GE0HBDmRv%2BHKxLXue0pHPWt9Ut%2FmY4r%2F%2BruXloxRsU8gjG%0AhzSamV5IdvfQy0xCog2bWDCL4rCngh1IkrFi0CtNNl1mPskhoZqMZjso290yNaUc%0AHeFIdyPyvjjxyoHd9K3BuXx6fPvYbZzFRz9YikMqHxz6AyHAiMJnl8OPFH6XOTki%0AO1liU9LI%2BMsLCmeDqGliNap9VMvpBkJK6lWoC0RDtqHM48sI4BqHBgW6nUwnGv5H%0AtKbDTgFfMZw5c%2BklOWIUHME4eFNyRej69uoofFyb2rNjXBqvKlL2g0dUXbm2nmYG%0AUW4JPHWria6djv6zg0h037c%2FP6%2BDhVdm2O8in8b%2BBgqsdr7ChYPp2jUX8rouFNwd%0AU4xAXYo7iLoDN7AXHUb%2BG19qrx3c%2FXBrb5msVllfjDfKspX9ftTBukl1%2FJv2QdE0%0AG0kEVzAVB3amt9KHNX%2BfMC28rBla60gfxmpEJ9Q7fZCAOqTJPPcS1D9AKVm3wpoh%0ANWNJXYstblVGNBGuYeJuvHyjcGfs23RPgy1PI%2FAqJJcumUCcGb8Aa4BufsyZLw4L%0ACkN6yaCuw5DdmeNklkm%2FNVDJJJpvkLYrTRr6V5VIeO1usvmTYwAg5301DjG%2FI6qP%0AVRJQ7GeUXB9G6r6g15KbNfIALz0SUt6wKrFn6H39aVlBXzFO5Y6EmmD%2BYapfJH0o%0AhOHiIbWHXqU9rPToLC2Pn9WDq9FIUMx%2B0wL0En172e2%2BUOfEoPrcoykVFXemGCVp%0AIbB9HsIUVrsYyqvs7HLQfMdR%2FSjw%2BsFilKzIIBFjgNWHiyOwshVMkHCUHohcw6mJ%0A3cx01xWgJaG42ggGSYvkb4BvZEfgKmslwIV79pbwQxuayKNNqCpPwHuqA1fdlZ2E%0AhR8Dn%2BShq2eP5lStlK0V%2BGYT9fBcfuqApdUKNmJA1Pks%2Bj9h0CzseWYA%0A%3DHRui%0A-----END%20PGP%20MESSAGE-----&msgId=1600f39127880eed&senderEmail=&isOutgoing=___cu_false___&acctEmail=flowcrypt.compatibility%40gmail.com', + signature: 'signed', }); + await gmailPage.close(); + }) + ); + + test( + 'mail.google.com - failure fetching raw message for detached signature - sets attachment status', + testWithBrowser(async (t, browser) => { + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const msgId = '17daefa0eb077da6'; + t.mockApi!.configProvider!.config.google = { + getMsg: { + [msgId]: { raw: { error: new HttpClientErr('RequestTimeout', Status.BAD_REQUEST) } }, + }, + }; + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + await gmailPage.waitAll('iframe'); + // no pgp_block + expect((await gmailPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(0); + await gmailPage.waitForContent('.attachment_loader', 'Categorize: net err'); + await gmailPage.waitForContent('.aV3', 'OpenPGP_signature'); + }) + ); + + test( + `decrypt - without a subject`, + testWithBrowser(async (t, browser) => { + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '1600f39127880eed', + { + content: ['This is a compatibility test email'], + unexpectedContent: ['Encrypted Subject:', '(no subject)'], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - [enigmail] encrypted iso-2022-jp pgp/mime`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['ゾし逸現飲'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?frameId=none&message=-----BEGIN%20PGP%20MESSAGE-----%0A%0AhQIMA0taL%2FzmLZUBAQ%2F%2BJgpmkgscJEB9uAiFT6TbeZsBqD%2FrRDInab9OevrRBWOZ%0AwQ7UxS4OkM8M1joflEgtP1ZjNkCCuOG5RXR3JZFkUeQbvtMc4mpx%2BOOjYbwHwNNE%0A05wbcIHn380axNPWMYqe8%2FiCK9wFWhMDwtpDfJ0PzLKAhnjFhymMWjmXB2avejaS%0AiaKQRelmUiNt5Tk6FAu8UnOAbr7%2BuLvFBzzjyELL3pGzDBLkawhUT2QZ2nqrC1Ns%0AJ8HEXnl0TBI5T9rlK5i6YQi2i26SWk8QkM0ov5OWVK1qISf15VHeP5uLXch3MfHu%0AEfQEubo378Jbka9QMo1%2FE%2F8ublGQReMpsvbrWto9HqfPSXUGe3hUQcIRi3nKuQBx%0AnbMWonnNE7UEhBFytLL2w%2BMmBDlkePa7zDngOjQwLpYNVvrxJnCjk6Skcrn%2Bx20D%0AYkGziEubqhquMRLxJht4UTLuRSLI8j1NtIRZ5Q9Bi%2B1krSJz527cbq%2FIFBU%2BEmNV%0AfCcR1nYbF5%2FhyTwB7aZQyxCVlRWKlYfwv4%2B7q9cj5wCBuLCY7ZKucEbzodehRcEt%0A4C8Txg2KkD7%2F8%2BTt60KcqjvyDtQkQYNSaubugsG2BAmJpYRU6KFVGDlpNe6gGEQI%0AhnVQq5UaZ9z0DcevE25Xr7fg2mLN7yHRRSauvOGlMnP98d3gDluQlbvAzk5qOMqF%0AAgwDqn0MG9%2BUHywBD%2FsHF58ogxK3kAbITjA453U15KkR4bAqcH343mPfjPOPTyAb%0A3IMoYbQV9SbHuptav6t9rhtrGEkNVunLQLrGYNbwrQx253yqgN%2BdRYD8mn101yJM%0AFcN3R6PDCxAL4hW0cXjSspaqe1mx8U7pz%2BLn1DrC4X8O9HHgMrPvUl18Uc14fAkw%0AZm%2Bwk5vzVYxHp8WsQXb9xpe1imlew7jPuHZkNSA4k6YDoGn%2FwpN3mEOKE3BYq6Ro%0AhnTaapIe%2BJIzsa%2FH0HXKcD0ztFeRUEyyjd%2BdE3vdJYehZrEQIjsM0ocqbn5tcf1W%0A9DP0OXGylTfNbBMT6PQ4N5gfyQDext9Z3QOT0c3HcmUYHJd865jR5nXHGzsGW%2BUr%0Ad0Z6AaCsSCP8WPUNixLzgCdB7EQ6Z5PB4etj9%2BFmKYvEbFiaOr9hrY48ny%2BiOJjq%0As0dudhgZkE8XpA9jcJaGnM4UZdFnssiTydlqaFWYwjVk8d4CsjrsTx%2BJNRWOSVHy%0A9WBbUFQc1eH01rv1sfL467Eyzhh92SCfHooHN9lLtF2mDh43ZQu0ReW8aBd7RzHc%0AKJC8E0wcslzLqfF%2Bx7rh0Vt54Y3i0PS9H9RDWATssCx0V3ySwbnxqme6zIa5qKUN%0AkbSqkucmzZKnaksb46S0zJyOB%2BQV%2F8ntYErmLsX1pGFvPFBm0%2BGQ%2FyQgpUiJhtLp%0AAW8jKCFMyQBHhBKyG0k8Dn9f5mO8rE0xG982m%2BnGwlMKJunn%2Biiyz561V%2F2ebb5e%0ARPCj12RUAIzKicPqRaPCaXhEyD30y1rDCHO7vpCB1CgnbVfRcPvTOOuUlGlrMYWa%0AZlAyrc5RkAiSCLUJab9ZTf%2F%2FT34dmP1p0bmIN3Mnwu3XsbEdZnoQxqPSl0UyfqiL%0A4e5uGe2Za%2FrxykM9CuG0f8vtFWsoNhJkTugdZjfKUZdnyfdsmZhNbKlJcuB7prvb%0A0Gl0%2F3fNns6qv%2B%2BR%2FEGNHbZhSxw%2FqZXGBwGa0Y7hwwsA1Q6ObXgnZA1TDqFUhFk6%0A%2FcDa8FlRD1jj9rKyeuwwLryRy%2FLhoq1LL%2FWV%2BOiUB%2F%2FSldGaHkqXv9%2BCJNhmNwEU%0AiC5mZYyhGGbsVcBxuQigilyMpDQJJfcUiqfN8KL%2BN8ICpnuPGgaMQ97SLeHq2Mmm%0AehcEZwVQZGlCnQJNKmhbqqxJB7WmdBRKTDiBxE5qz5r3grB%2F5v%2BMbyM6G6MyAnkP%0AA%2FUKX0QUZsPDR41XVWhZPTDo%2F%2FZ6aIKJwlgB3E9vak2JkD4%2FpdgzyAM28HOTUyJ%2F%0ASfBVLd%2B%2FjxHIVlm1IaLUAzvJjG0NFlXvD7Pkzs5pXmUf%2F%2FbTdFXNA3uh7VBSGQMl%0AkaeyuemQwiW2Ray4tYbUq%2FFCzl%2B8862JBY98w38natrA%2B%2BWMLHIox0rhMIG%2FvoyK%0AU1%2B2KKgED414MsC309jn%2BP6WCZGKt34BXSfDp%2FRbgwP3X0QIxSYOxtmX8fjKlVPR%0A9FPmkwFvIYsE14MSB16y2vxSEt8JFKoGhXRuVxlGoYuuZrpERfhynnkwSLkw0zln%0AMNUUihw9AePivi6H0qy%2B7DpUy%2B41CW8nxkx%2FdePcdbAq84Y71FyfM7gbLu04EPZ0%0AhTzzgSLDSWvLc7vWRGbqI1erQhfadQwiUzMd0YAyImWmnm003dxfRNNC0oCYDE8V%0A3QGFqOmr4AqcbMGIWBGiP0LajmehJEv%2B8GkIkuDwQRtkgaAkHwDMigujFtraqGEn%0AmduYmYBW88YDsXD9Jv24d4Pt2Ce7P4lc4DEAU3vqUMZFdIwHanjKSNr8O6aXXd0e%0AwrFjc71tUTNGF0suNi%2B74ol0rlS1seQNiijulEW53ngK8z5brNSd1N56H%2FwcYx81%0AqSyeqnGYHphNbpwhBTqHkURBlwygxI2%2BCuMSR96j49ko9AZZHYl6DBAqHLKYWHGi%0AvqvpG%2F%2B%2BFFy0AMSxjs%2F%2FCe5lTS3y3skfneaZ9sgH7o%2BUXCJ7Op%2BmtLdHGjn6%0A%3DGAOS%0A-----END%20PGP%20MESSAGE-----&msgId=16f66f1da9d50d05&senderEmail=michael%20&isOutgoing=___cu_false___&acctEmail=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '16f66f1da9d50d05', + { + content: ['ゾし逸現飲'], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - [enigmail] encrypted iso-2022-jp, plain text`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['ゾし逸現飲'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?frameId=none&message=-----BEGIN%20PGP%20MESSAGE-----%0A%0AhQIMA0taL%2FzmLZUBAQ%2F%2FembFGVPRuVfiUujhLesQa6a4sbp%2FPOQcAsy%2B%2BO6tD%2FVA%0AwrQtPhJeniYVFeOs%2B37MWy1PkOUn6AAvgasHtlMCVnthxavG1onImCJWyC0NdgYn%0AhrIN9aPmOY7UGhVzpU%2FGTxE1WHJHGMMGShmKbt%2BJThtAvmufuDK1DSho3kcjGEs9%0AwpY0DU0%2B9I7xEmobgQqK4jyzLBLNx4aHl2qurKSmjghmk1ZMW4oluckrDmmQ3AWT%0AZ%2Fq7bnbP1GDNJV8cxR7ed4k6HCzkrX%2BBxL308E8soLtg87occ18QoJAIRAHU0kx5%0AJlS9%2Bfh%2FjNwKanZJjCWv6hqZKz9iUocRZD9iPqh9dhjsKalqkRaxuPM2eJkZY%2B91%0AjG8tsHYTLeY33A4aUpdA6FpNR8Uyz8Agv%2Bx8%2FaFp8GxSNIuUumf6bSIk2Oudt%2Fa6%0ArWvZO%2BM%2BUK53a4k4ibxrkv4zsE8CbijjCP8BvUrA37023GEWkOHIyMoFFy0o06W1%0A56wTP2bLmKbujeES%2Bdkzjrr1r9X6oDBwpoPABKSAjIKFQKcxWvhMgz4WO3w61g3F%0AE8U0Rlx4lB4Ce1I0qzu8S4hkaZ7sYcKJ%2F211pzsaf0BfxZQdrfyu5kse275YgTUA%0AbObnoW2sAWg8fX9JwuL9JVArnJ%2B6AOQjvNG9fr%2FuM4thV%2FzwqBUWfQ0sasDjjxSF%0AAgwDqn0MG9%2BUHywBD%2F9bMrHNk%2FqirxpfIRa9vZcZssXv7A61XUZy2IVum9%2Bp9c4W%0Aswd23kQOfC%2F82Fx75CwMQ%2BzzdP7%2B5tqeNfm3%2F4vfObLCmszf1%2B%2Bj3nVxEEX8sWpC%0AmgHobD3uZPwgShvgcy6ZHkfz%2BBrxqqTJIZ6xD03VgzmNg2cuAHD1YVUKbTHGYcKM%0ACY0b%2B1VG6lv4f78xiB0v8aw%2FaPTvtx0rY2g0YZHaE0JXT59cMNTMORNiE8h8guLB%0Alf6hcwctRN%2BsJw5oW%2FsaXpgFJSzVbQrwp0a1b6Ftzqv%2BqyJL2%2Byay83RaPX%2BR7LR%0AJy9jPrwBbzwCVbJBBSfeQ0zXkeNAOso83rE13UjxPsl%2BkU0ajxy55K%2FP%2FcLO6KKs%0AKtFN7UGo2jGelpqDoGU5FwOoGeEaYW%2BInrZryyV%2FA2bjw6Zmfbh0GMzls25fK%2F9O%0AOJp%2FD0yqEmnkU60O6eDwwwxY7VNqmtuOTZ4z8PIaV9LWuftVOeOG99%2B9g6280CKF%0AYYHAxgb559v70V50bk%2BZ91rdA1SnxSq9wOkUu2K1BmkTdqEO5jxWf04MGrvROZUA%0AdIKQ%2BPYibnRo%2BSObBUn4Otlfhel1tJ9wWWjJLpGJ1Zm3FaoCVH%2FMnnvhF48Q5JNR%0ASDnqTg4wWd51Tokcnz2PoPrxRN3jacI4d0GZiAtsmB28mcKjdB5UYoXEy2MazNLA%0AyAHzCHRtOJ7eOcStwltwnbh67%2FRCK9OCegaiSOMAcsEciVXUpT%2BhVl8oMl6IvJDk%0AFq1CwOL8t3Oj3W2igPkm2EejHl1dkz2JXPHjfHqt24tTtWRa3xuotoSvMAy%2BtfKT%0ACwg67nQan%2F13hl3eF0XXLCD%2B%2BaotGSahUePsgZU79oedY2vmcofUf743sZ%2FN6aMP%0AgELzwyLm7LzcFLjeokhNUDYpBgrH5%2BFcFZqpiTQhILONSvenncP4k3FDjC87DG5J%0AyIckBN1KeU219vaYHEkmSmU3egfEYRMw2HznFAaiMEAnDoGs0ZTqNOx75ktZLpfS%0A779APSTDmS%2FhsXXo7D8%2FmyYWO5RMxFzGL7SIcXkosqa%2BTS3FJ5198epH0xLNrDhM%0A1lMO2ZU5qb2TNA%2BWvSviiwWsZ%2Byj6kD1rzrvEg%2B%2Bq1b67s3oogP08wwHcfX%2BUiND%0AvdGeVd2YFPX0kszhtfJDEYAkJ8ERe5RKQqeNXdk8XMYq2irp3AVBTBDkgTgMDPSU%0ACI3g89S3eldT%0A%3DP4O8%0A-----END%20PGP%20MESSAGE-----&msgId=16f431a0b9056562&senderEmail=&isOutgoing=___cu_false___&acctEmail=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '16f431a0b9056562', + { + content: ['ゾし逸現飲'], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - iso-2022-jp, signed plain text`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['テストです\nテスト'], - encryption: 'not encrypted', - signature: 'could not verify signature: missing pubkey, missing sender info', - params: - '?frameId=none&message=&msgId=18024d53a24b19ff&senderEmail=&isOutgoing=___cu_false___&signature=___cu_true___&acctEmail=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '18024d53a24b19ff', + { + content: ['テストです\nテスト'], + encryption: 'not encrypted', + signature: 'could not verify signature: missing pubkey 73A5534E5887BBAA', + }, + authHdr + ); }) ); test( `decrypt - quoted part parsing will not crash browser`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['point to them directly', 'free cert through', 'will honestly soon', 'dropped significantly'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?frameId=none&message=-----BEGIN%20PGP%20MESSAGE-----%0AVersion%3A%20FlowCrypt%206.8.5%20Gmail%20Encryption%0AComment%3A%20Seamlessly%20send%20and%20receive%20encrypted%20email%0A%0AwcFMAzBfgamu0SA1ARAAuHXRxM9k%2BXfQ8iPNconAE62s5pP1PdO5iS01%2FOB%2B%0A3%2B6xUX5oWemiwXjmKetzMvYvSA4ltQ7fWxwY%2FRznfUqxiWQAMQflWINMlmrq%0Apv1iznuVrkdXiyhSLvHuhN3F6ZrWFBn3UL5xDHPHYaFsg2azvqgF6QXK9i37%0AwYbZZzJ9OU5yqAdzdTAk2Il5V%2FG7dh0Su9qrY7NAa46DIqbgdlbLYy6qLcvx%0AiI1yaliUg%2FmCbiVj%2B6kgb%2FFs87peaHg0z%2FpcngOB0a7x1ofbIW%2FrcTbhsEjH%0Ag6I%2B7XST3RmKcOv0PgCtEDU6HnRINbbKrwr9M%2F7xjjBKN8iyDs0Z%2FdOXDKKC%0AFuUmD10ut8%2F3d4jJfTIb5FEiPUNsChM7lidHadKjMoEg55iQgUTp2FeWXyIl%0AF0UlmWRZziljUURdDU02z0F%2BNg9wJkCNrdaCHZeULWfU4%2Bzhvobb%2FaTQfS9C%0AIDC9Qo1jPw1U1nojFMQdBMQQ8P9xsD8vHkeG0f3FOzvj8xWm2oJEvBDpsP6Z%0A3tGf5vV0uRFWuTE2xWbV3cMdvsL2rVJanmGnsddJP4p2WS5at7UDdm7DxyKR%0AzUJnuvITlydd78pSXmqUrw9W%2By0oOdIfwWz1A2V9pdaYwBolPGt7UKUeSK6A%0AMYELv6Ac6Yt9TBJ2B7pLu%2Fw0Wtvjw8IGGA%2FYxKX2t4rBwUwDvb12YPaZjcQB%0AEADRrSJiXzDXVdM%2BGbHBW%2FrdKcDoHq6n3f0mUSbwumiz51pQrtKmNgWFQZuM%0ArkV2O76foEDpUn8m3Gwcoo0MvCxJKWQN3U7dzrMzKd79egDQr8mCQIUqPDbJ%0A4gxVCy9pMAI51oIFM4bOD51MdOgrU1uITZDtaapswiIMywmjxYGRGLDsQ%2BgB%0AVaGF86QgHSgH2M7KdWtN9MSqDs28z7N9kdr0bVWAmVauSchqBeGEZAOq90d%2B%0ApXET%2FbEm0Y0l%2BqpOFEfkbWGoAsjOdOa0rSmBcfZoSh%2FtYWDpPwJDT%2BIp4XLp%0AC3C%2FFSQ11gPt0%2BAb8%2FYouGYmICTzMVUkiHxHGs24n6Tww26qBwQFDzXUAwxL%0A7LENsgsebLDOW8RjCn3EUuH0vZID7T13Xa9R1YQQHmIebVN4%2Fgrz%2FqGDYaZ0%0A4Ub%2BpMWpNYIhDWiQRkj3u39m4hCWa2Lo9d2avgUqmdghCDKZkfMtNRAMyLt5%0ALSDnh16yrl1p4P4e7IMDFp6Yt%2BeSCjH55HaDGeq5Z%2F3PhlbD%2BVFY17v72cBN%0AuyqsecJpTacESxX0Q4Psgahr7htG71KvIjaRBeN05I80IXjrMcTY6c8r0qhz%0A72rW2rfNRuwjIGtJOUfFK6vAovR%2F6kMJMTM4elJ4Q%2FEZIN7zd0OY5z%2FzZ%2BkP%0AoyC8hwFHgwhhx1%2Fu%2Bj8Ira7DXtLMIAFT2PriDTi4aGUjforTVKCh9DifU8Bp%0AUvpEUJl71EdFZ5ic%2B%2B6pkGKhyAFbNvJS3dvZWE50%2FCf%2Bm8iUvZCs63aikTON%0AdjBOpQgE32ig39oM9ggHit0zIZPtZl6XTJHytxNoydnT1bp2qJNj81ZyTlQB%0ANTusbMcY3usDMzIbgFdiNFLrRTaZ6KPuXIzljP7Xw2Lm%2BTcVFGRUmDkadFF9%0AY4RC7q3isJz9h8i5Q6sbaWJu6Ylc305FDKH9XensyR0lXGEX7ishe5Mg8MBp%0AOeSyw20GEejrxUHOp5daUA1XKFX6%2BvZbekqZ57Z%2BJFrB%2BU3cWN2b7ADHkxol%0AhfnCymupqLmoOj%2BU8sx2omWE5KBehRiSpWIF01Mx3j0KKwVpJo8wisB9WXg4%0AG3V2LduE%2BBTZves%2F0A0FTUg0m5ZWeqUm1MAOUkQOdf3%2BC8sKVEUUUeW6%2FchL%0AyQXhKCfgpDHFmYKiTUr7ybPmQZ%2F2hll49a0xkndGPi92kmne5dz3X7tHtPH2%0AcgRAluAt2GU7nPYxu3jqWURfeIZvGRLPd4Ty3CfQDAymEQr%2BmMvkgFdfn2pj%0AlhDGntJgUmNzgwmpD60y4eEZhYCnDFQUdEACHb8OTFZ7sZhKO41po%2FCV7Sip%0Apv9ryn%2F5QJJkoDPD1Yy56NqzoaAZxSfm5Uh0mr1wqCjk4yBHrvu8naYpnQMw%0Af%2B0NM0BffntPx6jUr58uUh4GF9bwThLYtFY8SRVMRbz2R2Vfgn5nxnD3EwrV%0AGZo4YnzXXkryrD2V2uwTc8iOhIc47h8LcN7Riz4mvg6wlc2B04skZKknRgBN%0AwtPXB0cjKy5vi5%2FmBTnyHGnCVxhGAtaCsGFBLNmIAoVuu8Te0o0whDyA%2BNly%0A9aBJunBjkfLWol1Xc4wO1PKOE1xQAS9EzE3B%2F%2FGujyzoL6311HgABCjMQeCL%0A3Nv7YQSgp5meoBXX3%2BCqKiPDEaKY%2B%2Bftr8YomcIYQJyDUuRhXoHynv7LcepI%0A%2FQUdYKxem7XECg9rVsjkz%2BP0xtPtTCW1%2F9wWFBkZJP%2Bl6V5zV29Q4ROAIKhN%0AuNmcekI7gUYKhpMp2AGt6MalswUoqhV0aMIpRPdVzN2xrygGtv3LEfOXV%2FlR%0ABdW3J5I%2Fh0AcbR1cteMVZfFX0DInDtJ%2BeOUj236HFWuJ7%2Bc5%2Baj%2BfN%2BIAubQ%0AEinGN1n7KPRtd7s1W%2FT%2Ft7m3ECTCt2bjOGu4E7kcetNuROV0cRpISC40KylC%0AWDhCY0T0jRheyP0n0QA46UHCMvWsFPc8wh03MI9dvDuBf4olzFX3UfCd%2FJC0%0Ap9KlzxRG6CMlJZaDykP3rbCMatUsioMcCubma63ZGUJ0%2Fs8zaOhh5wM8fLLg%0AVJJ0z0cxZJOOaNyulIrCcMonQ42IAiqNr3lQO9dQ4TeR2qCrai90UK%2BDbyH%2F%0AptuxG3Z1D7RWn3KTMoL4lybbcD82HsQvzayNKqFKs3ePRpJ2bHyrb1ehhfuR%0AD1tBuLY3qjk9Ah%2FbPvck%2FwWpzui%2F%2BwanfLRHkl0n7TtZIqA6U87OSQCIGQpN%0AOZfhNSzyFYHwfdHTXon2lyyBXwRAm4WVvb4hYU%2F3ZtVheUevqjDW0gau4KSo%0Aa%2BnbXYYziOrWZ1HtYJYuuDS43I2f%2FfmNpv8PC01OO4b2FOt9QNuHnFzTPnI8%0AgFy4dXj5W9WU%2FwS6eLTBZqftSa5zM8lxEM1ZLQHOtgH3FUwvNJOddujHtJ5V%0A5rsXxFNNYV9WKPxVa1fB9tWvmtXHVLr39djsL92rQTGTgniViHNJRAGk2eCC%0AMoheMqVnBHwv%2B1fIy4YoeWZmmbWnpIq%2Fl7Zi0aKmhsgu5EeJ66R7g3zL2srC%0AIu9OVyVCiCzb1j%2Bm4wSTiLzLlc8iPREdsTt%2BF1cpbB1b9euEDA1l4OIIEcLa%0A0oxZICpvBcrrZkVxayPjsPzz1y%2F3%2Bm%2B2ylEZbew30kaHFxet0abd3NWRYzxO%0ADRSNl%2BZGG6ThAqKcmxPrHNv2gUIqt%2Bvo8O8f6REaPMqRpZRdCesBc1XD5FMi%0AJREzoOCLrFdMO%2Ff6SOe6w7Q%2FtzQqVR%2F7YQJJ4aafqCgclckF7DW%2F%2FJKkAo2x%0AnV63%2FnHrv7zCeurdFLs7iYu7Zrjd9%2FZEZ0DWzI7MKCf7rulwLr9Z1M4s%2BzJy%0ANeV2Qx5HIZ7DBxQxj7PE5AVKgQntVyS4fYIfc4giUDvFb3%2B%2BaTJ%2B%2FPxEW8o0%0AW7kd%2Fb9Y%2FUoIwo1gTA1vL8OQtAmN5%2FizO23APj2%2Bk1Yxa6seaVbGUfgtehde%0APko9tgcRBPr%2BnQMFuiWxzgUb5HFH%2Fiibg1sXZ32re%2BrKJkD6eUQBZF5gFdCS%0AO4UbO9GCEvOCNoAFlatkYEOhA4i25cRW9FmBfmJyCZ%2Fot4vqR5bHYvkddZLp%0AvUCYx9XQn6%2BTsZwaRB6MDPFABqAqFrsJnjzOfjO%2Fwchn10vo9zf3x3dQcKc1%0AGwJECb4v%2FawAayNzqQgmAjmT8JqkcHDGrbUvjVJYvfVA57V3L7Ohd5iceicO%0APb4VEPh2X6%2F2xQKsXgpDqF4aC%2BT9mJ96olqTnFsqKwib%2Bm5%2BdJa9PCAKEKxB%0AuPzU8j7llXBChJt7qwzPNShVV5kYTWpnrUJLyvjCP9qBZ%2BH%2F9UACHQvsrP6Z%0AJERvjq5sUuLpSOvqdUcTACHyEZWHZjXArGLmpCdTsyeHv2UF6%2FG2RVXrwDVk%0Al8xL4pBQkgG1HSA%2BCh2dDTaFyNZcZuF6EtwjfGOyJ0a2dX7sOTSXVggIpXwf%0AHxLB7KZg8GOTr7LRgjMl3h2bCOQJ8K4fOCYLw8yAK%2BMw8dQHwvtYUKcB8jCl%0A2eg3NAgDfqquKS0V06usPmSbXjgYyXTwYFM8NkOglAidnMKE%2BmzJRPsmInxs%0AB90SL2vu7%2BR5%2BX8tbLfCf2AMDd96cgCDB3TCxgaUbo3SU%2Bm6d97ALpiF%2FY6I%0AAUkl%2B5fcUdk8pPXkWzs%2FGyy%2FzpSmSF3I%2F6O0%2FS5RkCGVZ70Ig5%2BfeU89RZCW%0Ad%2Bjz0r8plMUn7lDBmouUkHGIkmXYHM%2Bzf6q9C17VWBwJCx%2FXddGmYTsPHmnL%0A9uHOIVNpDluf6cUvp%2FJlZ7t28f4fCqMFLF1Ebi87zVJBXmyvgue4WEcHVnAD%0A8ZNTpVvc03ZGba9UchGdWt5Y3kauldSFPN%2F4ziCPOeC%2BL50M84irXUevO5Es%0AwAFJtm%2BRI6FycBz7CLlZKjxz8I97%2BXxsjA7ZyuvUNRhORwv9HZx2BJ0OFM01%0Az%2F60Keq%2BQTXPzpzL0xAJNdrrYi3CtWf7gC5hTUlO8ocnx4qnwGOPyo%2BRmMGk%0AqKXLCeeb6OkS%2B%2FPfoGXm%2B9mBpPiskdMhhDD6gEfP6Z6oX%2Fhf%2FnlI9JEMKECN%0AQpPzOcFqDPyBjyBhTo3VSQClqBV2K1dQNL5GLgXa8tkHaXlPtVJR4S0WHCVh%0Aa3vcT%2FossJijMIR01HrM1jhbj%2BmFo6wc0o2XTG003IZih9T6ZZvCnGV6v31%2F%0AJZ2LOWfBReStcSrFZ5ZinS7fWcG%2F5JbuokKZVUxWqJq3jolD6nKpfEcBPaga%0A%2Fc6SujlXKQ2Gr58cmdCrN7JTty5F7lFtZlZRcG7QHtr01RXrrqCGU%2B%2B29%2FB7%0AcS4jpPvX8of3zwaPiBsi68YfkfAlyhQhbWIYYmWFjtyC2aduiGGcPudnRzVk%0AYG3li130yRvD%2BxeS4f4oficXUdB7SvloRbYvNuT%2BtaCPJ15ncSUXwLLOFWk2%0A7PY5r5h6PwPVxhxEtmUgcihbBP59WWViL%2BijxPCBoPxDknREjeJOgKxoswyK%0ALuOj5R2D6SU0Zs%2Fv4kWwXCz3wTTdU%2Bph019Z6SvLnm4XFbJTx1MI90XYzydD%0A2HFYgMuAEae72Hmv8qDO8SOat%2B3EkNw9e4DAT%2FRGOmwuPR95gMucqJLcP%2Fu2%0AJxLNQLSUnlfABSGiAA68Gym6ykDKYMrt4v2JOFNE7j457Iq0U6fKKRxVGNdc%0AnF4KmIyA08QIc1YKoR794%2B%2FgNYmb78PCsBQbXOmgldOAKQQl8%2B5Cz6Y2Mu1U%0AduXWUmcAi%2FIEb1w815jTzedtoIQ2GdW5gGIcWSLiLztV%2Fz35gDPxXb0HUGuO%0AJ6THAR4mc87euWzcBhUBxdfNaEiTdUgcfx5M%2Fh9YFuhS5VJjK1rjX9I2jwP%2F%0AgUBlWVwmG3mE0thoVxpSFHICI7uw00PjTNRA3qiXe1sEB6D9%2FWRuqUvKfkak%0A6ukzJBHJA2buKyZqOGE1R9ZJniRImpJN9sPVF2joSvHPB3cSb1JWENeF2T5H%0AgXMhFY2jbgpcXucMHapqDLJ3WMXCCR6R0pCGxWnYcY0O8klv2r%2FTPfdptVJO%0AaEib8XRAgxR7FfctRKmfrf0d%2F9UQQRYsBnN7fn3baHFG1UUVUEYHTr%2BiXpMM%0ACFontBV4pK%2BGl1bYAvYWLVXeL01drpVTgU24FZp4yTPC%0A%3DqLXa%0A-----END%20PGP%20MESSAGE-----&msgId=16b7fce1c1589c0a&senderEmail=&isOutgoing=___cu_false___&acctEmail=flowcrypt.compatibility%40gmail.com', - quoted: true, - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '16b7fce1c1589c0a', + { + content: ['point to them directly', 'free cert through', 'will honestly soon', 'dropped significantly'], + encryption: 'encrypted', + signature: 'not signed', + quoted: true, + }, + authHdr + ); }) ); test( `decrypt - [flowcrypt] signed message inline`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['Standard message', 'signed inline', 'should easily verify', 'This is email footer'], - encryption: 'not encrypted', - signature: 'could not verify signature: missing pubkey 06CA553EC2455D70', - params: - '?frameId=none&account_email=flowcrypt.compatibility%40gmail.com&message=-----BEGIN%20PGP%20SIGNED%20MESSAGE-----%0D%0AHash%3A%20SHA256%0D%0A%0D%0AStandard%20message%0D%0A%0D%0Asigned%20inline%0D%0A%0D%0Ashould%20easily%20verify%0D%0AThis%20is%20email%20footer%0D%0A-----BEGIN%20PGP%20SIGNATURE-----%0D%0AVersion%3A%20FlowCrypt%205.0.4%20Gmail%20Encryption%20flowcrypt.com%0D%0AComment%3A%20Seamlessly%20send%2C%20receive%20and%20search%20encrypted%20email%0D%0A%0D%0AwsFcBAEBCAAQBQJZ%2B74YCRAGylU%2BwkVdcAAAfAkQAKYwTCQUX4K26jwzKPG0%0D%0Aue6%2BjSygpkNlsHqfo7ZU0SYbvao0xEo1QQPy9zVW7zP39UAJZkN5EpIARBzF%0D%0A671AA3s0KtknLt0AYfiTJdkqTihRjJZHBHQcxkkajws%2B3Br8oBieB4zi19GJ%0D%0AoOqjyi2uxl7By5CSP238B6CXBTgaYkh%2F7TpYJDgFzuhtXtx0aWBP9h7TgEYN%0D%0AAYNmtGItT6W2Q%2FJoB29cVsxyugVsQhdfM8DA5MpEZY2Zk%2F%2BUHXN0L45rEJFj%0D%0A8HJkR83voiwAe6DdkLQHbYfVytSDZN%2BK80xN%2FVCQfdd7%2BHKpKbftIig0cXmr%0D%0A%2BOsoDMGvPWkGEqJRh57bezWfz6jnkSSJSX9mXFG6KSJ2xuj30nPXsl1Wn1Xv%0D%0AwR5T3L2kDusluFERiq0NnKDwAveHZIzh7xtjmYRlGVNujta0qTQXTyajxDpu%0D%0AgZIqZKjDVZp7CjKYYPzvgUsihPzlgyqAodkMpl%2FIhYidPMB135lV4BBKHrF2%0D%0AUrbb2tXMHa6rEZoj6jbS0uw%2FO1fSBJASYflrJ1M8YLsFCwBHpMWWL38ojbmK%0D%0Ai1EHYIU8A%2Fy0qELPpKorgnLNKh8t05a01nrUWd%2FeXDKS1bbGlLeR6R%2FYvOM5%0D%0AADjvgywpiGmrwdehioKtS0SrHRvExYx8ory0iLo0cLGERArZ3jycF8F%2BS2Xp%0D%0A5BnI%0D%0A%3DF2om%0D%0A-----END%20PGP%20SIGNATURE-----&senderEmail=none@flowcrypt.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '15f7f5e966792203', + { + content: ['Standard message', 'signed inline', 'should easily verify', 'This is email footer'], + encryption: 'not encrypted', + signature: 'could not verify signature: missing pubkey 06CA553EC2455D70', + }, + authHdr + ); }) ); test( - `decrypt - [gpgmail] signed message will get parsed and rendered (though verification fails, enigmail does the same)`, + `decrypt - cleartext signed message detected in an attachment`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['Hi this is a signed message.'], - encryption: 'not encrypted', - signature: 'could not verify signature: missing pubkey, missing sender info', - params: - '?frameId=none&message=&msgId=15f81b5e6ed91b20&senderEmail=&isOutgoing=___cu_false___&signature=___cu_true___&acctEmail=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '1885ded59a2b5a8d', + { + content: ['Standard message', 'signed inline', 'should easily verify', 'This is email footer'], + encryption: 'not encrypted', + signature: 'could not verify signature: missing pubkey 06CA553EC2455D70', + }, + authHdr + ); }) ); test( - `decrypt - [gpg] signed fully armored message`, + `decrypt - [gpgmail] signed message will get parsed and rendered (though verification fails, enigmail does the same)`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['this was encrypted with gpg', 'gpg --sign --armor -r flowcrypt.compatibility@gmail.com ./text.txt'], - encryption: 'not encrypted', - signature: 'could not verify signature: missing pubkey, missing sender info', - quoted: false, - params: - '?frameId=none&message=-----BEGIN%20PGP%20MESSAGE-----%0A%0AowGbwMvMwMVYfy8j1GPd8g7GNXlJHCWpFSV6JRUlcSH3akoyMosVyhOLFVLzkosq%0AC0pSUxTKM0syFNIL0rm4gISCrm5xZnoekEosys0vUtAtUkjLyS8Hq9VLzs8tSCzJ%0ATMrMySypdEjPTczMAYkp6OnDrODqZDJmYWDkYpAVU2QJVTh1Tmeb3HLhpxtYYQ5i%0AZQK5goGLUwAmYl8mwDC3yqJ3RqXeax2n108b42sc%2BI29zE1fLvdgq1Tz3ZL0a2Z5%0AXSTDobXyoiGnj748k%2F8iX7dJYc5C%2BTTmPMXtPmYJKmd7V7v2x6675BfR%2Bm25ednr%0APfEB9k%2B47iQ9yNsgu9TG8NC%2FhhccalMkT1UUcv7V07mW2ZRbfvSop1ZSU%2FbXm3c%2F%0A8nd%2BZShfmrHQYMMfe3Xmildmbhs2f7S6I8G%2ByamhrH1XsnXKlc%2Fca63S53TU7u5e%0A%2BX7vil97zTc3cDgtP%2Fuw6GB6mmTo8mqlb20GytG1LuYzZftP55XYL7XyO5M8Rzx2%0AZcLBPTsfzs8o6bgxt0fBucIlds7nzLOyKld%2BG2u%2BuSqzuj9wgpeOSX149f%2B8y7N%2F%0Ahl5nbXIo3qL3QXaWwsXvh7fITVp155%2FbxSXKX65fuLmh%2BET24Z9C7V8iGf9M7v76%0AtI%2BjSNRu7cnAttxlX4tOGHhtuMH%2BTU8nNv1cPEc1X%2FH1VRv95mWabl3lP%2BHVmou%2F%0ArkyN1%2FsWl7tS%2FfZP3vVlp3MSPvqy%2FP6T3VKhXSYdWFzhyblB6KhqzAbBuuVf%2F2bY%0AKRx1239v9uZrM3yEZOc0JtzNz7Lh7xb6e89tIne4blx81aRT7b86YroUHGfe0PF4%0AsHjRnQWdmeU2kgcmH%2BLUEdxd4bJgx%2FSQwPrb%2B6zieQ0mLbDsvZm7gHFPeq5ZW%2B%2Fe%0ABU8%2FcNc2bd49KWrdT8%2FzKpJ9KmvV9uz4AQA%3D%0A%3Dr8So%0A-----END%20PGP%20MESSAGE-----&hasPassword=___cu_false___&msgId=1707b9c96c5d7893&senderEmail=&isOutgoing=___cu_true___&acctEmail=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '15f81b5e6ed91b20', + { + content: ['Hi this is a signed message.'], + encryption: 'not encrypted', + signature: 'could not verify signature: missing pubkey 21FC55064B1DDC75', + }, + authHdr + ); }) ); test( - `decrypt - [flowcrypt] encrypted hello`, + `decrypt - [gpg] signed fully armored message`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['hello'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?frameId=none&account_email=flowcrypt.compatibility%40gmail.com&message=-----BEGIN%20PGP%20MESSAGE-----%0D%0AVersion%3A%20FlowCrypt%205.2.0%20Gmail%20Encryption%20flowcrypt.com%0D%0AComment%3A%20Seamlessly%20send%2C%20receive%20and%20search%20encrypted%20email%0D%0A%0D%0AwcFMA0taL%2FzmLZUBARAArdbyWcgwf3B0LjUD0ephMVsbwKMqETPnpCZiXnuk%0AXWEfNv0IbbuH3Z3MT%2FDmMQuzjltFOx7ggKAg3z452JZI%2FZ74vxaMtiWL%2F4NB%0AbDERSYIsLe%2FqaG0r9bLSFgju2JpToUGY6yiEYg9ciE1vitUwzurx%2BwFi7WIq%0AsO%2Bzra46rp76rUKk%2Fvss6CtPlqScNyJTBmv%2FSz%2BL4zbMESkdiR5qBVqm5ah6%0A65TXO1KIH2ZjdOBmLOEi4p3%2FJM6IQ2iPQQIsxWHjqtMQyOZA9Q40GpRT5kQ7%0ADCUXsRsGB5YjfgsBw2r8HUt2eLKmUThPC%2FQZlu8yLO1AAIAPJJtwAw6OOJTR%0ATxBTwMAhcJxtFRKPYtUD87xuydctGhoLy6mJiPk3q2Z4BP5hctnuSsaUQPl%2F%0ACsZnSyobQIde5MnS3GyEQ%2BMUc0oq94aTS8OdXrX3EJJU1EU3Zy1P38n3V%2Bgy%0AW1qH5CR1D8otQ8Ed9Ks%2BSRiNm%2FQPBo8hu3df5RGQycwVe%2Bbmx3EDCSBq%2BzbD%0ASbaViUJaKxJnqJ%2BUKEruouuhli1EkzVgSj%2BnpQjJ1EcVIjPGNE57BDC0qIF9%0AbcHcCsyT%2B8VMtrCB9aMAUGNXr%2BbyhY8SIv0xFdTshjx5M6PWu7e6yFrRiT2d%0A4mMUJjYMWcEyXd3RH9pn1QLEWZK1Fpaclb8oPi4PwHzSPQEeLXuhArWpS%2Fsv%0AkqaG2U1x8qUu3yM3vkxWWRRMtmRuPTvFfLhoJRqxGV%2FihBIEQXwlKvgG5qcW%0AjP%2FPXN0%3D%0D%0A%3DNyoF%0D%0A-----END%20PGP%20MESSAGE-----%0D%0A&senderEmail=flowcrypt.compatibility@gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '1707b9c96c5d7893', + { + content: ['this was encrypted with gpg', 'gpg --sign --armor -r flowcrypt.compatibility@gmail.com ./text.txt'], + encryption: 'not encrypted', + signature: 'could not verify signature: missing pubkey 7FDE685548AEA788', + quoted: false, + }, + authHdr + ); }) ); test( `decrypt - [flowcrypt] encrypted utf8`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['გამარჯობა.', 'こんにちは。', 'Здравствуй.', 'Chào bạn.', 'Dobrý deň!', '여보세요?', '你好。'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?account_email=flowcrypt.compatibility%40gmail.com&frame_id=frame_CdqnkNWgHP&message=-----BEGIN%20PGP%20MESSAGE-----%0AVersion%3A%20FlowCrypt%205.0.4%20Gmail%20Encryption%20flowcrypt.com%0AComment%3A%20Seamlessly%20send%2C%20receive%20and%20search%20encrypted%20email%0A%0AwcFMA%2BADv%2F5v4RgKAQ%2F8ChgnbhGZoPWlurgYIIv2QrY19hjaUs3cpuKMDlDu%0AVEtRRktKtX2aQ3Uoa8Uujc5xbP%2Ftj4PI2Tq7Hq2J6e%2BevJ83QOkKhT9zjfaJ%0AMqutNeP6TFDdtBsumdoLMEPXeGRL5iQ1QpIlifenIMsGI0JRRYZnZJIa%2Bezf%0AAhp%2FKrwK06bnT7mopm4zNRai2JRDppCbs486Xk9ErOMtCLEzWDZcVPD76agC%0AoTiRQjX%2BHeIyPgAqYTFgS4n5OyOl24alwHwPAvYV9uMEmKfoWZAOc87lZ53v%0Amqmyj14kWMtHwNhgQ8AncozGbv%2B0j52%2FJATK9U605cF6f0%2Fuc4wvd2jqpfWY%0A%2ByJw8E1wLR93oHvp0osyrHPq5TFeQO2CyLzOhhZsT50kyXJuD%2BQfgj7buNed%0AQQY2Ve4nrkYPgHIMukfXQDj8W0ZCluct3WCg7M0YWJizDnI9GE2UN9VN4OHn%0Adfle%2FAjBCijxWLxQqWCSyuwNmZl2QaHS%2BTrGj7%2B27GtsQc3JPu26D50a3PRg%0AHZ9srOYHVRR18PgoSfunySNio6FuMCreg%2BtPds0dN%2FYapCkXnOSrIWUGhOv%2F%0A5XalIpMK4ICa7mCmtgGV7C9BW%2FlvDr2jL4o%2FE0jyJHMF7eUimylGLU5ETu0e%0A3wJFemlLMlClcfsoo7Djpv%2FZLv7M8SvBLwSzr8%2FkF1nBwUwDS1ov%2FOYtlQEB%0AD%2F0YG4QGIkkxLjK5pHLlWGD9k4VJ0vxMjgP3zI5hLG3V9j9mR3dm7zmiULpN%0A%2FyeDlU7v1sdmh2s8x4yJZ5xJaiL6gDPGoxKg017L1GyNzqvna9qoDc2HxBMj%0Aegs8RR6Do8rqk9p8EBXiI3FlHHn%2F5hG49Ni%2FLNNxcqf6dOextTWpm4tFeMHx%0A9nA%2BPO2MoF6oGkrgbOMDUtKZwnQGCxA3%2FYXgv7wya%2FoAS1HYVvRx6Lbl1YME%0AHM7e4nYiAOflwU2getEtSXfu1CD8p30F%2FAkO%2BqKaitZF2LXmS%2F41yIjD69oQ%0AsY5ERKRdNQTBkr5eUhS6rFXII8SXtJVw%2BDY29AAelZTIxIJ%2FzLW6AiPydRSp%0Amu4vi1%2Fy7YWTQ1bWlvyIjHWDRpwVv4K7VMWIk8wUq3uRF5%2F2%2B4h%2FemcXc7pG%0ALuX%2BwiqMWw8Hjv34%2F8HlltrQRG38JtsTKC9DPKTqezrIcdPvv4PkVXGHLxYg%0AdFyfkYr%2Fb3mKiGVpptGEE1rCPzg0TCd8JNQgFr04Xq5gElPP6XBcvs3J5%2Bh%2B%0AuHlaFsoPMzthn8%2BeNmvxiCHpd92VIbl9Vq6%2FZtSPcJn4drrftn3V1zvUC712%0A4LNp2iipdSAynfkBQE0FJv7m9mbunCa5aAEVQ7bxhgNX1CqAtRmeshd8w7SA%0AoyTwxN%2BVsQUhx8OMKB%2FvQ4SQNNK2AVgaKnVXEtPWJsyj0HUlwHB9jjV5L4I%2F%0Ai4OoVEy5ANL2f09cPeHGkbaKb8s4LTqZAU6Zz%2BLfDfTjzPrRD3qVcn3Kcwj3%0A4eCvkBIEt8NJ5%2BZVIKhN3lGCCab%2BFJOtlXaCL0oks7JGlQn57IPmtmWCaGKa%0AVRhp4WU3oIVZkKjI23sIWdt0l0z1H1xKhFVF%2BLE4kiQ%2FCIwifGYJ2R5eQi5I%0AqtFxVWy8T4Y4aWPciv73P%2BRL%2FnDd3JU%3D%0A%3DwmSW%0A-----END%20PGP%20MESSAGE-----&message_id=15f7f5f098d6bc36&senderEmail=&is_outgoing=___cu_false___', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '15f7f5f098d6bc36', + { + content: ['გამარჯობა.', 'こんにちは。', 'Здравствуй.', 'Chào bạn.', 'Dobrý deň!', '여보세요?', '你好。'], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - [flowcrypt] encrypted thai utf8`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['ทดสอบ', 'นี้เป็นการทดสอบ', 'ภาษาไทย'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?frame_id=frame_vsaWCVStjY&message=-----BEGIN%20PGP%20MESSAGE-----%0AVersion%3A%20FlowCrypt%205.7.1%20Gmail%20Encryption%20flowcrypt.com%0AComment%3A%20Seamlessly%20send%2C%20receive%20and%20search%20encrypted%20email%0A%0AwcFMA1DaD5CEIgc5ARAAoUfZ%2B9NZCeiIQKQK25%2BdSvxB085gOTv0XnoAlqPE%0AjdhKp7XXojq7ccUSaeEW8DqTel5P74FZ8GwuhFNj%2B6G8ZEcOaxo%2BVKgoOkfX%0Azh%2B5BsABuCDRxoEUivVVM3%2BC2SBBGkqgbj47RJUFOWYkQIlwBhSA%2B4bVXaIC%0A7TEYLxNy8845%2FtTLDoSjQyMA2qXx5KgFaiD%2FZNDQeWM6wcYeHCczbRBLBJ9z%0AOvHy6hDdo%2Bs0P1N4jqGCUKpORrrCyqupKkViWIYwhkrNE74BGzSGtWp4PD4d%0Au0bSgCcKNJI4D56vOl7VPpNlqumNaM1DFgWCRdGcQdfeHyw10PuLrWB8QmSI%0Atzhv7SLxGQBc0o0tveTKfugVZlDq3Fi3eo6GDzKHW%2B2NkOjMoR7mNCvI8Zrg%0AcZVFwmSEClNTnBV5QwDSevEkOYdhc6TEi8p3Gngv%2BOMLZmPO1TSAQ15KgzeH%0AK6BzTff%2FeTJggXvR4gbYOvySIrow2eUQ8F%2BLJV2jKfmOJIJBOUKEh%2BRQCuIW%0Ac1TUxrANDM6Q0ZMPrQ9uvKUQuDjORmizBqXo1YvjDEbGHh2%2BdwaTSNr603%2Ff%0A4RDOgaSMhMWNvTx2MXk%2B5V8uqoAqZQZ3tSLkPGtGTumlCnLivR%2FcKTeL0wIb%0AueEVTDW%2Ff7nQfhuPXL%2BfVL4i2HItQgl68YQQg1PxuCHBwUwDS1ov%2FOYtlQEB%0AD%2F965w%2BTY6hqEtzgQaHr0S2AyNdgLU2HkKI26%2F0iZ6m5V9S6Kd39r5HmVOcY%0AuNLDlNwlXjK3ohbmEg3VmLirLt4tiq8meN6wpCKLv29GL1qkNXsrfA01dd8M%0AizYFXmf0c7d7HkV9JQmUr0xbl3Iy1mNl3qcXooR2OociWykK0Z4ESLKNV2Do%0AUAP6z7X7jVHLstri5BOqMKTRihvFB2rMGdJTIzH6XuMlSnJXSa8LBHE3FZZr%0A%2FSqxSV4pseg2VXouscdDkMq958ZAaLteptrQT7rqO2qcJoE3Xoon5RJaFv%2Fl%0AM%2FVSzfgfcXCfJF34HMrZGjrHddeAGG%2B7k9E%2FiEGcZ%2Bkxx4ToruzdxGdenANv%0AQ8W5l3AkT1qlvV5GSB0uwpJm1FavoAtiwQfLX0f%2BDC1jI%2FwL658%2BnzNp70BY%0AlL7MXN9PgLLY22wSIYXG7ZHlbWAbs8WD67gBw7W943rw0%2FmCzuhQGH6sJSLc%0AEMhoCA%2FePk3oL2LqU9F1Im04tz%2B0FBP%2BtPZDey%2Bo96Tl%2F0W8wBUxLCq0SAdv%0ARoG%2Btm%2FqfFpJnCvKMOlW2UMT2dYxFGAsTdgHU2xWBP7v%2FnsUsRBM%2BF2mGcxh%0A1OOVzxs01SvYqza7jPhfW3NYBW5QhtnIx6w4b6h8aFrwOwgH0B%2BhuGvDrppR%0AL5TgtK3%2FJqomOtbk5n7T2YID8dLAIAFzuBmdFwMtyzU3NFucc4ekf%2BZYLiR3%0A0edmsPhzAFhHxbaaUimCfe0ipXiuWMyOTgGr%2FeQHKT5Tax9QbGq6j5XVzAr3%0AsAJ%2BYho2XvA%2F%2Bj0XdVHDw3m68HJcJzcJfESIHod8asikJSpr6l%2F2a7e7P7yk%0Ao5sQ7owhi%2F7DXTPdSyjB7rIO389WrRy3AHBy2T70qEcXL%2FZcRX1Hg00dqNZ1%0Az6r8N1dCp6En71mie9jxN37iejGJgD7ygyr%2BRm4Q8r0dsL8%2B8wfDcbxWpJZu%0A2Zmv7a4MdPYJ6bFiVJYpFau26zP3%0A%3DaaqE%0A-----END%20PGP%20MESSAGE-----&message_id=1645e37647db32f8&senderEmail=&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '1645e37647db32f8', + { + content: ['ทดสอบ', 'นี้เป็นการทดสอบ', 'ภาษาไทย'], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - [facebook] encrypted utf8`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['Сергій Ткаченко'], - encryption: 'encrypted', - signature: 'could not verify signature: missing pubkey, missing sender info', - params: - '?account_email=flowcrypt.compatibility%40gmail.com&frame_id=frame_CdqnkNWgHP&message=-----BEGIN%20PGP%20MESSAGE-----%0A%0AhQIMA0taL%2FzmLZUBAQ%2F9FG%2FDQ01YvjE9jIzCRSPJ392q28yexjq5PIyFnmUb%2FSOk%0Aboeh8Xs1zMmsgcT2rtMN2Fw79MQdqhhsSS8GSU47MJ7MdMLaWBdrF8oR1ChpsCMp%0AwMAqdy31b%2FRE95Pzp78VJnmZp5qDqqCNbnLVD%2BZzev4ElGan58YhpfnMFsdz0tk%2B%0AgTr6CQVDKOprvbskaFanG%2BjpLWo%2F9LzPu1eWrX%2FQ5SwUVcaVKSdbLm5DVRSU1qnt%0A%2FItTiRueMaOPwZgqXJS3GeqT0C%2FCVxCDd0ZKwfP%2FBuhVTKv77l%2BqnxuNj83I%2Fak1%0A0CJw1J5jTe%2FNEwU8ZdcJO8hDWo900zU90oqUoYUsH1yf7SKL8qSJ8%2FGMW9GSz3cX%0AFhsbE1FiJZ0CG6sUAYtMFWX2rhMwuz8vPLXlj3q6iYQ6s%2FCxqJvuHSbIK26XYMWX%0AnsCkuJjKm3cKe3KONeyxOyizlQaA%2BeQB21U33Bap1FSFdJ0APK3HVJ4B6ZICsLiF%0AVX0iml03ezvhC4qRv%2F0Xb2AdYZm%2F1HSgVUuCvX6bnoLDpRYq%2Baiy%2BHeO79%2Fu2Z0T%0A9Dv0YUAopO5it8cEAWBz1eQvKmkNMQC1W%2B3dZ04Z8bZZ95UwQpcVZLLlvxc8ubwK%0A%2Fh55B8g2ExlAFKtkuEfTtsDzAE%2FPUkgzZ%2FmcyT6clvPrGG4NZGpHxEvl%2FshWRjzS%0A7AHgElrFBgyBD%2F3EhQGy3Lb4pf0helGHuMFjEWHb0NocxyKhLLi63rLVZrDPSPWb%0AM4gtE44bMp0HZ1kF150X8F%2FfXX243M7EVf88zv7uFJaKThbK6tqhl%2ByuegUFiDUO%0ADXOwDkj3aPKM5tOpkkR2ECOOsNZiHQXkfvED4yNhx4sRGAEiw7iXuIJp8mRYQKxW%0Afrmbl4yxUSgWii0s8VQOagwRjcYq9PL1Qn2gujfeNDk6SSfDHh2vIEr6by%2F9y6MG%0AeIvbI9VVke%2FUWtZE75yn4XlVROou%2FUmfERyR6%2BzsQBoMp%2BPy3bG%2FZ1pS42jk%2B6YM%0ATVoGz5SEpch1RH41Kokgn9gRvlbUN64jwsAHbWi3CDEtik81TXNhE9GbPidbB49N%0Aihy172mP0U0MoeAdF5T9Y8GEdDu2%2BTBJYzzpjhGszi6pHjyh%2FqFE2stuNCV44YDc%0AJRnWW35gzD1PU%2BgVOWcx%2FPEAMLmY1VN3RMuuFW951BlNtjg6B1E7GBhMHm%2Bn9l8R%0Aw4%2B%2BzjnV8t6ZqIo6OjJgiQkEh85pOq4yq%2BqGrQAJYOwpnJ4hZ65IB3rsqUrlCeeh%0AXU9n%2B8DCgtfmxuodQWqcRDjwADXc8bWFYifHvTehBly1pIrFLvNq%2BBfrE85vbJmv%0ADn%2FGIa%2Bcu9celM8%2Fuu9pKN5Um8sK%2F%2FHRWo4vFzTXRkBUDuK5p0xWMM%2FYVtSV9PN4%0Af51wBMyaY20YOXLYdyAy31%2FNGh61vSRd%2B%2FzjuzresZ2ghvlecZdQy9fnSqUSvbIt%0AJLYa1tK7H7UjmzauZccKcQqKgaXXAQJt%2BXYZYYlwGcCBzHzMCD65fMwcHit%2BH5Gs%0AjMKjBh%2FitsQP3FV50zO%2FkFq6k4fy9j7ib%2BREQqFyeb0JZp3tnqTxpUPPV21wa%2Fws%0AZ87kxWPN4ckwVClciZMDXtESxRXm2xmlwvQY76Kjw5vvvGgizxEBvMafD59bB%2FdO%0AFwa8tlPqlwCnI3SSB5WHEdV2Rfu5O9SU1ao5X%2BzFpZLSeMMgnysY5VBJzFa6EdEP%0Apu16Hl94RX3aONOD4Mq1DGZQg0ZZ5qFZ9ZXCgf%2FJ6mqFo%2BaHCnT4ETNRotN4bIvO%0AdQROF7yiZxKl%2Bue74pfAfgDLPyYBSmOB00IA11dPsml%2FeI%2BVU4MpDdKNWHI6a4lw%0ArqoeoxaKaSg8lx58SeLW5VuRiEZ2PlNnf1aFzfew5lb%2FMBmTrNQLikTkKgRNUzUe%0ApaobFtSnXDabV0Yqg4A2AYoCKErk%2F0R0lyrUitaUgAl6s3e76QRzf4Ao7r5HTXF3%0AsnwFAD4O6ijuQQz0FnszF3VjHwO%2B%2BfxZRoUAVhovPMN8sUxAXbPUq4Lui9vHbGHO%0AxN0CAY%2BAj3qgtrZE5nUt8rTRwiW%2FkVCyDDLY3kbPdZwdOvyeWkSNOijRcdy99ZZG%0A3OXoT8ja60yMmtRvbrSvXQ2KoyM1%2BeLaFOqap6elGGmkZbKvuDR3b4KZElZCvB62%0Aryd4v%2BtsEcCMsTTpo7ekZqtlcs98LA%2BjCFjVUWGxBz5SavUmcVWCy6QzjG0RaXMx%0AImDGQWiom%2FXD8hACE%2B41HYwGrTvKsW33yM%2FJEsDb2dRN%2BrbCQ6RGTjX7tiRV8BGk%0A0MIY3EejIgQkZMZRAzh4ZbGbZhBUZgfUUzsTmNu%2B%2FfppZPQtwRsXvunF%2BqFCvXWT%0Ag5ZVUcZeBqd6awLJe2nr4i1sYKfHLztKjSXnxbN1Gofnvh4NbPRN%2Bh3Q1vB%2FhCgg%0AfjPjdojEiHk1QcUG4Vw3N5IUSWdeYnC%2BCGsO%2FRX9f0u00TnVpgkkQTfj2FPOE0fr%0AYd90TYhegXykYtzjigAkSMgnasd7zg23MLH0kZQxQCdj7%2BEq5JF0zB%2FgbGbKPdId%0AxxWhSPoAU3y0i%2FlyN0541uqlHxX4i%2BcXdlsTSrAg1QBAquCf3we7b7IMaku72aBp%0AXInSLj1bbnWeRmeuKWh%2FIDnk0xvPN7eTIzi%2B0wYkYfuwKLd5QSn6CGLgk9VRHzsC%0AY2PwwSX58Yo0JK%2BYE9DCvMVMNUeJAxpdIkq%2BV0jwjdER%2Fzpv%2FLUy6MKh4X62dKMh%0AyU9MpvqeMYkfFjbVnFlV9bJnWutYKbtNpzRegY5wIGEOXtpRxuFuhQoGkGH423rD%0AcWDEzNuQ3CYqxY%2ByVATpElBiEYbfx3KKZ1%2BG8aLajv0tI6NnN9qkmCIbjv1e%2BFlS%0AuA5WutrCrIgHrMhREC1R6woUh%2FtlcwGpn9gumNZvmvqUY1GY3jQ5UgY5VFgwBycv%0AvM4kbEbk241xt1%2F8%2F9FZBwvjfW9Lyt0CSw%2B9dqYuRAEbXSaAvvqPL8mUUjG2%2FYuD%0A%2FeStuJYwOn1e9gNYX%2FiUYJD8SqPx89DgGSOcSPOefcURbqLF2yQGl5si2PonVNW0%0AjCsLc6iREfLO%2F28qn9Wd1ORBI6VdcRKHmAxRf517IZDAzO4aay45T04hU5xFL2eA%0AUZ9TC8kx56rdNFvrL670XfOa1er7MaprUBhWfdtgbIQ%2BYTYjzVVi5954ivMEV7J%2B%0AyBLgCKUUJYI%2B%2BvWJ%2Bi7X07Kzt0ZHXebLRCCljiM124dkhncGVUM6QXb1qK4hQG5Q%0AFhxrOjGUrNq7zExBPYEihmd4zf3e3kQXPb1DmldTrwRz%2BusBSB4kSi%2BKjW%2FiKrte%0A0%2BGXgDaJUIL28XLPTYZHPwE3mB7tw4YImSxeSfC9FnRw66JF%2B2Eoae%2FO52G7BoEl%0AqPVRTvVu2DgXxb%2FDljorSrWa00iJSZKeasXDrHSCKcUexkZ21D8Fmr%2BNib3KhQRY%0Aa%2FzgNO9lg%2Bg4JWu2KbVyjECcjToS1sS1TOXWFpGUFMJ5WXMUgZGD1Kk7m09fZF%2F2%0ARbgm6mDWFzG4gNbz%2BqpRmZUCfKwvEDEWtCw7lc0AtAZitjZW1OfATo7oCuqSYQyb%0A4A%2BPibAme7a3kJ3pn5puGQ11hYY33iYv0Jk5%2FMEWVztwkwYc4rweS71YxatIrJiT%0A6SaD2jSzZwAvyqeEWZbYOByIZaRmm6rTmGpE0yGB%2B7zWJ0ZpbCvqQcyTrCZBMlp9%0AkselQeRaxDpkcmlP60Hb0b3emrbDtRliVrTpw3WJbafI4kMSv9kuozBqAavPkhjm%0AKH%2FR6bvuuYzG0fhr9O1CT7wdn85hILepQoIAiLkkjpx9t0x2GS4els2LQm3fRU9h%0AaXP4YKsIoe%2FJjSmdyvs5orSHbNEIsS8MpLBRTKzpl9y7SOFaGp82Vz8%2FLh6yrey0%0AXV8Oz1tQZguU23%2FNkEkgSFjWeJwEB6LCKzMnBOXmFPi%2BFqx5S7JphhAJdu6sCTXK%0AZjYkkNP%2FUGsbWIFCkqzId9CRPzR2Q5Db16bkjJmxNzSnYXUP%2FRzI%2FILbvFTtA5uU%0AS9%2FYPTcTXyVQWuU0uPUl504M6Vz7uMtj6XFFbU9yAOlBrimZpJPYHygFvkS7MoNu%0AuV5pwAADkNFxzoW9GxBeZW9fwouL3KrHw52Nl1AkFWmoIshdXqTOpNgi7Xxj8XqA%0AMF56BJYMjxRbQtnGHZoj8jrIwUTDTIYvms7xxJHm5YOv%2BtvAlcBMcaRX%2FpKYtoz8%0AQYrOZATUQs6OjXuWWzydltx4Z334iZqtJPwlJ4tp9AkLVPjhHwB64pAdrVLOwlDz%0AoYXccYJsqWPZhp2ygkQ06IMPT%2FSVKs0poKdchaaHTo8BRDvzC1PoudjoB4SusL5F%0AWG0mZrv3N6yPk7V%2FCajURwrf2i14SV58swwiS05xZDhUX4IOVBFDQEF4EEHbjWvR%0AbiYyr48NZCqQKIUUX7Ol5aO4ogv7ZFW%2FLsviCh7iYENRHcF0RKRXCLnpFNdULXFA%0A%2FAIm3TOX0vp%2BtjpM%2F19%2BH7wmqj1DLTGWk8xX%2FrBsgTbuqhPaT4otQxcwkA%2FzppMh%0AJ9iUYOdWrnHs4DLX7cHoKjwcHkemF7GT6F0ufyQI4MimLp9YJioy0Vs7seZiGBnA%0AyBSFIFn827tgGN%2FbEqNT5JAUcRn3VClhmgA25mPeHtJ0Qm%2BrF2rOddfXJ9yLGJcd%0AcLQK6yPf3T1wqd1rWdgJ%2FLCj%2BNrWWfOgp%2FL9qDrzdTJoTOQZtSw5KVnQ683Y%2FJr9%0AwX3j5B2mgMwT5EfJb%2BQzDiD%2F02Pnitzn42v9FMZct9260HIGWsnfVu2dhXPwbE69%0Ajh8ccj6E1Pz%2BfRcheJCnyMD7YDNO5palOGNQgjtMaFIoMORiX4UYyWsgQVkB7gDw%0A%2FH8TdhsYCi06Z8LCj1XF4qkiTVseikyih3Ro9sypUUeln9QhNrEglpj12xrUcNZ3%0Arap4C4inie%2FMrxZ3IaEKP930QkaGWmP8IdQ3gykz8%2BWVBXwu1OyJdZERjbsoZVTy%0AiO1eE%2Fo2jSpol9KcBD0s9DobHWcFlDhzExdk%2BVb9pS%2F6a37lrQvj59bBQ2aVt41b%0AbTngwnCrMeOWYChecnu078YEeyRVlOItsB%2FTl5qbq4HyLPYfMj53nJtGh6IbDN%2BT%0ABgbKJbmrjpbiXUEWryNJYVNu%2FE1CS9X0AXb3or%2BBBzVqdwioO07m3GUYyMV2hlnm%0Akk0o6Qlxb1VR7CB3PuJOgeUK%2Fn3cqzZcG7q3EdYobjfkM1bGiuXpuIzkOPsD8Gbn%0ADYKjvLts0yO3CF4EdYEKBGnZ7Mo4IL4G0xZjAKqg6jVb9DhiWyVp5R3dcoOBZik2%0AqcQ3iY5cE40SddK0jQYgWRhPFyi9V8n0fElhef0OJL2jLKYRHbxpLM5lgKpnmH9Y%0A2ti%2Fv8l2n5z7wSVBIpHbpYq5LrRdlAwyvSITglf6IHFXiagyJTcL3mx7eJSfscQT%0AdH9RYoAO650vDfhXZd%2FrVgbZsUjr8vHf5SHIS16yZE2mXxIPSBpKJZpTMXJwc9h5%0AYAxwukFXP0k2SUZN%2FgoKg%2BQ7rtL5LbgmOAcPInVxQILv5HqSsgZFwunQ3v8TWtzx%0ARYmdHDGQSyfpAmOEJ5Kpnzqxon59tUdudNSgut9FL8SCy9nC0sB8SxPKO%2FqtLM5i%0A4n%2FPqMutwPsqTW4ugiFuBKvwDQbLhUtlr6BuVP61dhv970TBNZfrfO5mptxdxjey%0APrj%2BP6uKi6RODHHdE8jVvZSrxGRowBYyPN8GpY7pfchKdU27AfGP6p%2F95oboSnQN%0A2MTOmCYO%2BW2aaqVO7xaBHB6slY8OZ0a%2Bb9fk7w5m5zE28RfJIp%2FFNRZXzUmvR5Ek%0AXln%2Fx141yHEl9go1RnWX%2BKuRjptFPN293SXQZCubQqJ7MMAWixTGcyKb8L6V2KoZ%0AWMqzP54Ud%2F%2Bt3ddHC7BxSPkVAgDY%2FrWqu5kBJOTbuHFCrTTFPEQBEs4WZRfiR1FH%0AC%2BKZH3GWBoi6tVGVCVjapGQR9pwzTUpWQ9txN7XC3a9A%2FGUxCgCPDSDKPjjuoBwY%0AreJvP27UiyWnHR2QjcCXAC4lbAC41Gc7Q6ejTfd0HZ803V9bDTrcvsb933rM45%2B%2F%0AYM5mbp2VkugZbSQ9fTNXP%2FiSsZRjhk96I38n%2Fw2ZH0np6m5YcfCdj%2Bd15tYQKe9M%0AyjqTsaxEvncLT9M9RcRgzgnq8gmetEf4ntUC0P6dk4TcSfhqCfg03KgixRNqJEOk%0AYTR7t%2F%2BiV7efS42ppR1XwJXAOVy7S8EGY5iKnoJtxSKMgcWBKUng9v7cPLvuJJ7M%0A%2Fw379Bo4%2BpgXtRJKEQX5wBwbs%2F%2BV67rZAppCJfyrA%2F0k3UwqF7s6%2F1wG%2FPHjpAlf%0AWco17A5UW%2F4PAL4ASUzhSijcdl4P%2FulalCyL7zz0CE9szDTxvGoQcUjyFz4X7k9d%0AQ4h6mFdJGXnAc6KxXUo8hgKzcoP1uUU%2Bb%2BZzMV7iaX6JIA1bq0l1wCqogF6A7Xqn%0AMXzZXfOO3k3w6FWqSIpSwGMo%2FZgdApvQdzsLdcI4WpKQYcvv1kkNQHJsMzp0Av3p%0Awf3e5Yi3cS9c6D68CPiinSKaz5Hh4TWhYdEogKehW4cBYchjst9Q5PpC4%2BlC4gRP%0AvBT5QW6i9XTDprdUhHZxeNtefsZz57kgJTr%2Fhaf1kbiH1ZTcGOsM1R%2FQtl2RB85n%0Ar0RNRxFC%2B6S0B6HbTQFjD0Kfy%2BcuYJY9%2FtvevLRLSlGFjqgOjJmBjr7fmUCCJSIP%0AZkp%2FLF7jBBt%2FtaoUjLNOGQfSYBot9Fhi6DMoQYQ4SJZL9FXpTA7SsugjSvULxXPh%0A6AAmevooajrYvrbQfTlZ1uKoUwZXb4%2Fz6iGgtDuXtilmx%2B04SO%2F7j507HDm4WooP%0AH191ZiH%2FPYEVt3BLERNzVqg5C1orr8yMpeuKvib6YQRk1heXiGPpJEWiSAHKYx5r%0ASkRtowOSymL4PfUdcUzeWtNp7kjpBDX548KWZbmROBM2326ecxKzr2UdaLcYi5Tg%0ABpmJhxP3pySowMOBQOg8Qgls6LJZwLePLBpDS6h6kI67pZlR2P%2BMVpzfN8G%2FDd77%0AG5yC0rMNGhCaLGAbNZYHhHq8z9EqoxCzvVKEyeqh9OTDGUmuytRLnKSijukxEuvy%0AGHXRpkO%2FJWTc0z6IgLh6uvGaHxcswLWd7%2B%2BPoUsU%2FWuFLyt0VtzcjkMFfriRhYWm%0AHmbSVDfZsz3JEJGPRFJb0eU4qgc0qj%2BzFmpSGSeDroZhwFBqVwu%2FXp%2F9dPYJRebd%0AlwFJ9fTjFJkkv%2BsWE17wAjRcHDqdbWk1%2BXjjZ1lnLRCPGLalK9IB%2FIATibk%2FmMe0%0AoQnVGuYABhvpa1CldSy8A907jt1grqx2foQfJLvCMUp0yCmTjdtO3b3fLwySrHh8%0AwuD4V2RxRjjjkzivPyBBA6Cr7rkwra%2F6MofokiUXFNrZZq8PQaoxifwcKMXmmqtA%0Agv18sY%2Bc7gCeQJcFz3VTLCrI22RYoKYuQHCZ0Pp8tQlAkMjcpkxfWR0tQLxpDNqe%0Ajvtqf3hNNW2qu5amEUGXs0Mq%2Bv5v6aRfr9Xy%2BLb0ZNhz8%2Bks7eAax%2B4IsaDbrGs7%0AeIzvp413pFwO%2FunARcBXn%2F%2FE9AVXWXARVqIWFHrYO%2FH2ll9GR0Pe%2FOAPwuEGG0QH%0A907r7dbHe%2FaWQw%2BmMdK5j53PbDYinm%2BFVcTEUklzJ5n1rc%2FvMIyqseGl6MoT%2BKXu%0AuBlSIedJ%2FnNwsu1Oa9l55lklFtV8bHOg5NPj530BIAC4tAnbRhdtoWa0O%2Bz8SYmc%0AdXUdf%2B2vF6BA%2F63YjinYUOX8PreIJVnD8qFpJCtBTT5HRBhaHYV5L6A60lq1%2B1Mh%0ANWmNckKVG6pZDZrNAYfkm0tdYJ8wJOR5XjAstbHFRwbRqWWNJU283v5wuZQtpMt2%0ANXWbUCjMVsO8IVh2VYwftrb1HV1mZYrN0%2BxdGc7mjPlHGU8G12ci4K0BqMqNv9Bq%0AXtu7RO3iZHNc1Ir2Xy9FJBd9ysr3SoZc6C0NmWzFOQ8oMKtg%2BC5HK6joO2Wced8v%0Ad16ghltn0WxLck8%2FloqUMaJZ58GCaJws%2Fxip45PQeWBAWJRvXlqWkQfdiPGp1G2I%0Act29btIAixOGMplReIuwPlCg7R5RaFn28Mt7QFk8NK2kVBd3pWzWtgodeGyo6jG5%0AZG8uZpg872hENmTZYKg4TQDdlCSzX%2FjEAX5VBPFTNUYKSw73%2FCAHZgtHWE%2F3Hdv9%0A5rSokViBqIOrmU5Xpy%2BDfOsRaMEkv%2BpSzElKU7wBY%2BVRDV%2FCBis7bOei70IBsaUw%0AwKfoz9NemxHR7gTi46l%2F5fBjWtubx8TO%2BbtZWd0845hvvSTroP5E0KtUWiqCwq9h%0AWV%2BkBlpu06aHue6abPcbQ2P%2BEXLEVg8r2SzKMq6br%2F3O3NF2uiUIygM6OV81yiqR%0Ad%2Fs7Op8dnVXlnQ5CYViOGMKjuFHReQNCeIUx2TDtlKm61F2%2FzMrqIOopJqbZrQrp%0ApeZNe0YSUlPGzxlAV9%2BlbACf3ZCO6pigogIdoGELUqg2aStQ8482FHupSeSubSD8%0AwIVVJC5bX%2FEB2xY2EImJ%2BqS%2Bv5VjGRTwcW8srEJL3qq2zgn3Llc%2B0k7nabjZTPVg%0AW%2BI9YphTDpfAvXE0rUAocquP2bxjHavW3J3tVLQ8HFCQxxcWFGg686JNDxVqleJ2%0AIBmraou9mLQMU33YLJP1Yc8gRvkOyhP9NkK52mvQDeshYkb7Q%2BmjGnHAD%2FMiAE5S%0ARncixlzbGkGWXFZ2Hk2NQqvWnflt98zU8RDHeqTGss6KL%2FeffmpM8gxK3WIvvnWW%0AfNHuSVUgYjEKhnuouaAY%2BKSjvUhxeF1l%2FeCHYcvtWABl%2B4Q6y4EhzGfubgqbcIav%0AVNF%2B2yF1q5m4c9stoYjzalg4oExlepAdzQ%3D%3D%0A%3DzHlX%0A-----END%20PGP%20MESSAGE-----&message_id=15f7f5f098d6bc36&senderEmail=&is_outgoing=___cu_false___', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '16180866d0ae26c3', + { + content: ['Сергій Ткаченко'], + encryption: 'encrypted', + signature: 'could not verify signature: missing pubkey 6859679E2F20BEF4', + }, + authHdr + ); }) ); test( `decrypt - [gpgmail] encrypted utf8`, testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['Prozent => %', 'Scharf-S => ß', 'Ue => Ü', 'Ae => Ä'], - encryption: 'encrypted', - signature: 'not signed', - params: `?account_email=${acctEmail}&frame_id=frame_CdqnkNWgHP&message=-----BEGIN%20PGP%20MESSAGE-----%0A%0AhQIMA0taL%2FzmLZUBARAApSOEoWZSpvBNMFPgyhbnMd3Jdv2%2BsQRSs3iX28z6TsOp%0Axq7Gqm1xh%2F27EeJfisCZH9Af1aB9OSQXDzfZG9NqvXXQcsMsp6GcqyzUhxp33VDq%0A5xWRAoS8M4WvEMGOKx2q4ChoBhpl8wloDQtPtnk7cDv3YRgxF0JSkwTy%2F%2Bs6wAOJ%0AX%2FULyAayJ8MgETkRpFgzYpWaWTmrJsdsy91ASJAP%2BKujGn6BNss0LdufWrzOZmxw%0AJ3sX%2FSasurMwwaftRcQd9CVzckrAFeuwn4fCsr4kFdR%2BRDSM7GRPM5rxWnTiulgh%0A9SRTyekvJlpnwbn9K6qPO6oiXVDZmB5Gpl3OuBl5V%2FPazSHpm%2BzPzNxiwlQOobgN%0AP35PfbpJAi%2Fq%2BpSEra0dmU1Jtek7s%2FNh%2FsRebJEgAXwZvuUiTBu2zdIygW%2BItsaa%0AQqvffyZqcrY85Q0KF%2Bz5j7MOYXL0E3bkhEtpou0pjdOEJTsbNlAsFu64oxRjUjkD%0As%2Bfpgv3hnW%2BvYHQy98B1VEz1Q%2B2G3sxmArepnaD7Kylj6mNE%2FI2QPYCl%2FDqxBdZv%0A%2FSKL9D5t6DKqj0cu6TsitWNbT8SOq1oJP97ZUcr%2BNg9YHDYnb6v3mXdKZ2UxtqVG%0AmXzGU9rc2QW%2BltQINpj0uYzKNQiYxXnVaO0eYF4wJQ5EkJeixLltUQKSTlarQKOF%0AAgwDBlAx99b1mtYBD%2F9yAcmyrvlAGEvn5bScQXV0k4KY0n2gpXp6A81uyJAv4iFo%0AUye4LdRlZEdx9WOxpujfLCiGAKaN4tfDoDw4G%2FAlLelOwG87AcuK01EYQOmtVWmO%0A0jPkQJkmQe68Z68KRUlS7BpsLriC%2BfSjbT9wOlhVA6xaA0DQfig%2FhMkvZp%2FA2vCT%0Ax7OE49siG6lyWHhTQXEmXflGm23a3Eza1%2B16Ln8TDUEt3uFiPFAg8Wk4arb2NMth%0AlzPOvLtDjOmVjpbPDtGjmUeCjlt3m%2F3IB2HrII9KZrT%2FnXBb29XenXa4z3Rv8ziF%0AtBNWOXqKj4E0aYzXJKNDvGtK7Ddn4gMgdLfsSeJ4zL9vwam%2BL%2FJi7WPb3SGSew6H%0APKGnOJj2fBMXUnWxzLDf7KZs8Z6ON69P26kYrwd%2BMpL2hkhEi5fYkpHDam7vBUUb%0AYwBUpGF2Msx2YH7suCwaNVeXX%2FakNzeu6%2BxgyocPTDlIPN3C%2BJsZIeglw7lsWs%2Bn%0A3EcTvS%2FC6zIOLTH0fYAES5dzc1sSIYPJ%2BE86nhC8snxnSIsJyaB8OJxSfVUreMmO%0Aw1kiBdMuAtUPOUs3ME9Xaqic2zQrcX1G%2FKSNjsXCNEf%2Fj%2By%2FNpeVP8jtyGFmHdi2%0AIaBFez6rMOQWmEimThz8r7805jvfYHlCWRN1ADSvxtd6pjzUgrdnmGu8mqfZ39Lq%0AAT5PwLztaOjaI%2FhCOdPzjb7%2F5OLvAh8voc6EbEXEHRvg0Ut7viWnSlLw2VrgHXM4%0AuBEEMUtRTaFQr19FKyp698V%2BnMoi6i00aoxVYx5K0fhR28eTiyZFRAYLpo4jV4p7%0AG5wuS2Bl%2FetLDZ%2BKlWjN0OdZn13OIMV0hO12RibB7ixK0dR6aFxsrDvL05RIl6Cx%0A9oLaBTQs%2BQcHTGL88%2BJ0dxY9Q09%2FBkz8VJcIdM8BIJSPDj2Z97FsMPgo21NNR7EW%0AaKY%2F17%2FztFHXXsh4LPYxr8xe%2Fjz8i9PYPCo3VTe4E8lW7r0XbXCsinFtmouO%2FawX%0AZF0pgMCnSfT%2BFaji6THxfeMCQEXH%2FA7HLe32l7B%2Fnhl9q7Hb6vEIJrav7yfSSpp4%0AW9P0Qoz5xXRtphcqE78TXGNlMYGOZjZtMKk9qPeRAfBlf9o0B1TAPAVb%2FcaYbph6%0ACe%2Bd2mRPSHv%2FFZlHtk3aVhLbEVBdfbwculi8OY%2B13EiUuzGahrjWXJU8%2FVj38U8V%0AGt8glmUkshZDX%2B023YJ4e%2FBg3m1ClnavXnW%2BoKDsUfvHOjIBwH1PGjkhnaEqqXw4%0AhHM%2Bqn21KViyDemgxhiff9ruvNq0w0fWk%2BdD1bCuS9JJM3Lrgpq7EduBhP0924Dp%0AlQvDNHMOXqdm5x6cec4ZDJUJVKNt0RM2hi%2Bz1ZWuZKsNnm2WkV5VMjE5m4kVkLKW%0ARzJOpZ%2B8CzMi3oYO2R9BRYpcNjNETXN86mYaMJOBxXyUM1p%2BcNVtqjE2L7EMhy%2BR%0As6sKiDPX1VHX%2FUrIoBiscAJsROzFJ2DoLS21omL6V1opCp5yg66t9P4ksnZC%2FPTT%0A5jndqWbNFVzCsyaGjH9skHwHlFbgwnuonvhwShJIfjEnG9CIKUlsIsHIHxuUKO0j%0A4dmCmfpQVUYgWNsw6u6FZ4mXaTwx%2Bg8e5BjP0xW%2FvQkmsOltZnxt90zp8aujtGyH%0AM741rzKAp40wR7mmd8qiAim399yyLthNSrJOGI4LYbixIMEk0IdiU7BoHvOkNjqF%0AE6cZBgHIstClOz6rYIJmzMeJSD5knjHBO3O4OIlFOtOa47jOrU5yCV2MaUtLcI8A%0AS1YZ75bgznVQZEHS6qNH7lfuLw3DPm5otvYJQwX9Nf2EfNhdp4XKiSyN9GslzpxL%0AtR5FMA2%2B97MAC4rUg6IrEF%2FsvM0I307g%2FEKGCJp9K1MuuVmrUvOuRxDcbdzwTRMA%0AYs7Bjf9jasO1gw9CXE%2FoWPQCERlZMse%2B39DmJkfWpc3jxYLo29OqwKNzyjohr97z%0A%2FffM98dwmkLJYr8Hh%2FSVlKrvq98kA400%2F%2FYo9ZhOqvXhxAC51dn7IdlPL0hrRVE2%0A7E4cHZQ6k5RBi6mRs1v6s47qgUekQAFfhOwNUECvKzuKBFYDtUpwgS32RkytdcRf%0AMwhqau0F5rbghdWpJCY9vffiw3qpTh3q2bMVm0ZRR2SCUtJ9L%2BRC78PStbNu9xr2%0AnvCgqyXJUl0p5%2FQbqLUdtLr5ZRsOsPnKo3Cqmedpkv9p75Uda0VASisOVf64Fc35%0AMa7MzfqLTrPSQSpNfLLc%0A%3DoKrd%0A-----END%20PGP%20MESSAGE-----&message_id=15f7f5f098d6bc36&senderEmail=${acctEmail}&is_outgoing=___cu_false___`, - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '161b2ac5a73d4097', + { + content: ['Prozent => %', 'Scharf-S => ß', 'Ue => Ü', 'Ae => Ä'], + encryption: 'encrypted', + signature: 'could not verify signature: missing pubkey 9BBE40BC1E8CE4A3', + }, + authHdr + ); }) ); test( `decrypt - [enigmail] encrypted utf8`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['TEST, ПРОВЕРКА', 'C увaжeниeм, Пaвлoвcкий Poмaн Oлeгoвич.'], - encryption: 'encrypted', - signature: 'not signed', - quoted: true, - params: - '?frameId=none&message=-----BEGIN%20PGP%20MESSAGE-----%0A%0AhQIMA0taL%2FzmLZUBAQ%2F6A7g5vt9ji%2Fp17TEtJ%2BN0SLKj3%2FSVCBGsUB1OPoG5jXKd%0AURfKPDZ1wwlANopiaqnPOFmXQa3mfLnonvoHlR4oK7LBBJnqxaDR%2B1apxXeKJd9M%0A9zb1QTHmGioOGegJicc9b%2FOtL%2BXK%2BkB8kby0%2FyYVWItwghf32VjFB76UVfTnMvh5%0AI%2F%2B04zxLJ8yelt9m2c6TEpjP8lYjn58ODQgdXr7oYGfqNro9uNKDFJf9mwog7W3L%0AGaA1fGePWvaTnwpu9UZ72qsRn8ON8vmI27gqP%2ByW1drlUYl0gPjhlWy9xR6L1ri1%0AkOD56gLhL%2Biy97Eaer6jTKtuy93esvehKqRldBmIB%2BisQFTR1TV8Ugf3EzTlTW5Q%0A0jWgx9%2Bgl98B%2Bk5Tzh8VoCok%2BXaQxfkKK71LEqNTtAjFIHpzEz1QfSWP49kYBMiZ%0AQ8H39NKYPjLc8vfOWgdDkK4twNUApbjC6plIa1hfQoiktFNN7iRNp0sDiSh2BY3v%0AkDima3Pl1IBlLSZyjZRVlslebzxtXorJSgDHdoZLiyPLDEuzuAHT5vD32HUmBVBM%0AjsB0N2NlvPu9AIZvLtYbSeviTDxri5biy1n7gBNaO6udql%2FF0HObIinm6W%2FAdK%2BJ%0Anh8zmW%2BWEh8xJiTuocrmCIobq7%2BNydhAONV406X5%2BvLWNbEq4NOp%2FgO83vrPeFaF%0AAgwDuL%2Bybr9GbWQBD%2F9eWIom%2BopCTOYs3emdQtp3SzJgTGgYecUpdc09vrZRGDl5%0AUDozj7xeulXkT6A7hJlg7se505CYEtZNGdoZVBHKQxQsqyDBXVReNDS%2FDOf1BIP3%0A5gUIm9SDOFc2sro7U74HThSPePFPslIcl9WCF7%2FZbhwIQ%2FX1gk7EbdREct7f1nxh%0AEsH9EldrNFT79Lt6gZZ5jmeE2YdgSCuFof64cImReMU%2Fs8y5JI6x65IEwxTNHiPG%0AJw%2FR85Bh3bl0N8VlxJKgBW0ZNyJiF8%2F7JuBvsZ3u8Sh9jH9qSE0f%2FIXYvZEfMm00%0AHzMax7jF%2Fvc%2FtW8rTfZzHLxgYCJaIJHAeqnksmf2mfgiiCryVU%2BkOYMNOVYv4PYn%0AEaQLX%2FY34DkoeFDQJnCnC2Vny9CGW6qz1UuaCKes%2FnbQr8sphpfvF7%2BO1dVFqib1%0ASz25tTWQqfnVqoiZaVnQp9RbRN2LlQ6j6YmVap8hLMXPtu2enIvraH9tSKkEiZu1%0A4615OybnIVhYjPSgzrZjihYz8hgxl9EznCKnJ%2BvDTUMl4sxxBnwF%2Br4rDtAs%2F%2FWU%0AeG7QfruTyLZ%2F40tTg16WdrjK4AWHwcQNuf%2Fy22YHP13G3OuhWaFLYLqpgwO5CwF%2B%0AlkROtXdIZcmD8dV%2FjFy%2FmurMIulyRCAHKDGUJcjklA03CW%2FUTe1A%2FX5sIA5GLdLs%0AAXfkl1lNVHQFyGoVqSXW0zUKIi53EkUAC3fbEIK%2B4ljf3Owj9I4M14YbF62Dn1fz%0Amk6KGPOyApO8jH3q5pST2cWGnlAl2Jrwmm2mMPtYKWMSbIHaufMDX68suWS1ZN3%2B%0A1t9LehxG9ruTCrg80t1H9Llaz4rHpho9vXOmIFxPHmREN%2Bqo6dq0cwVb5TkLAalT%0AU795tmmmiI4n%2BSQA8ouPbu%2FvndFQGX1IJC6Z1bln2h%2BxS2HXzS8WT17sWxGKZYiq%0AviL%2B85QMH5oM7mQGW2g%2Bm6LxmAibjmcvYIEPcsOJp5WBMtv%2B6U0%2FHMXJkLWS4NTU%0Ag2beKjmRI9wyT0THkQEBWJ0lcY1Cmbv3k1y7TuhO80FSBh6MUlfFKROsbbgJ50G1%0Ak6%2BuCw2UOH3xWivj30%2FvBU73f%2BFLt99fX8l2xfIxRut3ud68tjVYEtq7j2m5iJ4E%0AZmZdjPbfWa8zpJrSiL%2BTmJUTtrIzp3vuD2YI%2FvZ70%2Btw%2FciRUnCk8%2BvsNz%2FLKG8m%0AwKz9nmnc4qWmRGk3TqEjC47o3N9r0LLTnYh5npena0ns0AIX33w45afjkb0Q8Csb%0ABwzuedgOjruUvOacUo07mNrgjUVDmsGOZJLuQA4KpYA9o2obZw4FhGXrdMgYmp4p%0AnDfTr9nPasfg7Lw%2Bqn%2Fxkwcpc090BBJA%2FAzuCrzYtiKTEH%2B7FojBR6AUaOfsJSvb%0AVvYv8N3TikqYT2gTkQgrwd%2FFtCSkGU4%2FrCIPQzcNdNauL%2BwvayAFVSJE1l0AClRh%0Am1%2FUNvvJ%2BkzSyuRTjWZUHZ10O%2FXdldtLbw5FERuLTI%2BNV2ju1Uh%2Byb%2BPBT3W%2BWZP%0A0kcDFr9MFu0Nz1xg3H9ur1dU%2BQaNIR0vhEvCbQwsthddIu0irX38Gp%2FKbL1f0LhG%0AW%2FCizRuU3IHcnE6FGqAirbMU3M0z0bF7uf10bdCx7Q5obEr6UcvHZbWEp0zuHSzo%0AVl7MxnEJOZaqs79faTP2N3ZXPruZK5O%2FU8s%2FFvm0QOAhnNMGzCRw3tKOPFJYi%2BoG%0A2jpflyaA7PW5aPHRMZjXPqN9pcVNr%2BoCECNFNn1btBCLlqQj4aJ60XQPZPKq4lH9%0AEicKmhnU25%2FP9U7hWpLjSVqnGtJWLsJUqyw%2BQnLh75Zt%2Ba%2BU16q6G9MaYIB2bEkp%0AjLPtUxA0RYVfXn9dvwrq6rLGRXo6dg5VckRkAVN%2FDxi5ZSFfhw%2FpmLRwD%2BwTAQ2W%0ACmRkoMwEpvSAB1trZeZ0iKTP7vl%2FwL5daCgg%2FmpqEj5Fsl3ufXZcWrA%2BqqgTKiK%2B%0AKshS5ZFnPnkC6SWB7XERizeKUDx8V%2BXMGD%2F74FBXlCzw0%2F7wLU2Wal5eRRSaKeCf%0AM7emi7iWR7X0pBQoQCHK6SD7pQsRNowjC54zFmksNM0u9tcwQmOR7hwn65nKmMbR%0AIV2DLHuwb%2FC5%2FYCqgNScENvnq5WRO5TWUKdc5vhpDd%2FuLsrSKB8DgqwTnwKxLiyR%0A7Z8abUs2mdoaEBSFQj4MmZHP87vk7wm8MDkZ%2BZ8yC5PNC9aEqFvNVavoTvfSzO%2B8%0AHIjKrCqZ56QnEFlM2qCfERERzvlVV%2FWYaj95KEV9N2neJrCh8kpwHmaBis21I6KJ%0ApZsbQV9YKEj2sEBtndETXWr9dsaNzy%2BlaUUnRzbrH7OcOq1JQ0GxW4sGHmoky0GE%0Amnuo%2FYTBLzPqhTrnAWaSMoRhUDlQbHdz8lyNyQEmSNAEbmB8zfIzV9Qw31NIa6Qz%0AFISoYR1Teo%2BkbXRvABGqvlaD0VnS2gdgSoCW92PvEwgBvfdKNmOan80PELFaqujG%0Ah76Rt08g0UGcP%2BGnU0iCydjbmTOtXBypFOpXQh7phd0RlknlLhro7fhMlNtHO6Jf%0A6o2y0zcEEu2CzmNiNS7G4k4Op0o8txZjBfCRk0JRmzl8IBiWEk1eaUs11AHlVun2%0AhP9iVyF1PAaD%2Fx2siEi7Y6P%2BMUmLIpZUHQtSartAIsudhqtkbyh9rTWT4N%2B1ya8o%0AQha9O409HLCdVk1J%2BDj9RMDhw4o5oVZ0HryHvw29l%2F7CUe34%2FwRz0fp%2F97Slryc2%0AV85wzRiUEjWNDqOlrgruShywik1i1YDK0ZoUDy2V5otgrWRN%2BFnV1ezbbkp8V4cZ%0AlOPbnRTr0QQQcoHyb5lHolRlhhjHNy8FwEi5y7rtYued1lBBc3tjiNt1AW2QrqH2%0A3QHCaURQVknS%2BW3kvUlfFBSkWHVXeuL2MtKZ204%2Bjyk7t4hz5zJI7P0ZMsITPCfZ%0AVgl7VTEYyTBVDI13T5bAxXzyBLafc7KOqWmo7Rmwhh5ksomEKA3s98CbSATcRem7%0AH%2Fd0CWpBIWYDQh6GhQUwAfqoqFMb%2B2paJoySD3I7oukQ7Mjf61N9ZUsvb85xfDog%0A6E0X7ocyPMsOOJuZUT%2BIO13WDxIOAIedJ9AZ1%2BdqQSDSdYd3R7bfBJaJ831ESR80%0APer2RlkOm5KwHmPBj%2Biby2qX1NFtfUwFaIiZvilDipiwO3vdiQN8tqwCQGUXUwc%2F%0AcgjIUfwsQIZID%2FC05aFh4TOHpxEHGh1zihw%2FjOKmgntZAM5BBxFKRoLRb%2FizmxXg%0A7WpnPwYPqh3NZogB%2FLzT1v4Gn4LfDXB49%2F%2BPpWiymqyitepjfCCLI4Iezgpz4DNI%0AftIp71gI0GCEHH2ZV2fWkZtiMmCuX4BRq2Ck4E4d55AUamlj0Op%2FH%2FzyJeacIZzr%0AgMk4geKO51112xGw5hCWF0VRu0HyoqH44foOsB7JDth2k8WoS%2Fz4aWXGi12aT036%0Agtpqww3ZDXjb9mW5QdsRQ%2F00Hye1%2F4iCEJ97rB2K2XrWBDqz2AZQDC9uXfdyOFDx%0AMGTqwdcQCN8vDtIDOZGXoIj39HKD0KjCwNxzFMbdQngo5y9cBXrBhA%2BAyKOQCNoW%0A1Hq7OROolPfreqheIIqv2zZKNBzkJysEuJbMgHgPJKreBJa%2F7mK6yORaS91OofM6%0AzUOingcNjR0QmLWdxPX9PcoIHsIpQPA8k8KEe%2FtIWhQSciy1ZyyqWrL9Pt8LeupB%0A%2BZo%2BASgwoPSuQpIKdBOcnmqZfm%2FR0V6caQ2f80bIKwafA%2B7KgAiYmi0URiraITSk%0AzAV6BR44Ijn6dBR4MJFrxY3VWXwaJr07EfGuOkkY7YMndQNovHtlZNWtFPmH6kBh%0ATHBhNuHRdpL3Z31gYSEv4bKaXjfkXzG5fotUL5wDUTnit9jtAzgr%2Fk3i1JlGAHmp%0A0AQQquEQQf8aKY0gCLxB13t6jhOSGAriMAm%2B5BYkEIPTditnK7vCG1y4%2BhO7sHYL%0AXKKkm4yoOart3%2FUUtjZSxrIjz97Hd61V7He85zbFmevanXQ7BLBU%2BAh7ppyK4iMV%0A2vWcZGMsU11iO%2FSfsbuqotZYQLQtacpTP7IYtNflWevS%2BPILb%2Fh13DmL3OW%2B9ebS%0ArwRsP59hNFLesJKVh%2FPWa1Orz3rybOhskM4T%2F7jT9OH2DyGgaMnGEL9EISkZ5m9q%0ANTVD%2BHmejta1yf%2F3AMhgYS2rzGqJrjBIfY%2BxciOERaTmV4o8x8ranri%2FsUPEDdUr%0Azk%2BcnTsfvurwjZNyrfRpB5Jcg7v%2FTtAkmftCQKZWPXCQFLwAO9HsLLaQ5PsVPZ6O%0A8OKXKqrARyhuH90OB%2FaeRBqZeisfMpF3CgP1%2BhUksncMGmufhDtTW%2Fs%2FZyIpKN1E%0A87Rd34EG8%2BzcIm7YtlEqJjJKsxohfm4bx6OqGbaUVrOijqK0G43ZWdXZtF1%2Bm4n4%0Ab9NZWbG8l46%2FIRg0LrlNAaNwyJVcmzLhF0DOv1J8%2FmrVs7fXJWKgRw6u5BlxmvC7%0A0zJsarwyqQNhcINF%2B2sxoVNMi0stcN3h6cUlamfX8Q%2FrrRxJLIkU1GzTr1JtEQzf%0AUHxL2%2Bl%2BcTiYTKOFU%2Bi5pIPLo3K0eH%2BWdiG4n1juUUN9ufhAzw1j1eDyxZ8PmKbM%0AmHIpZrao8r1lghni8eFTJwnh8K0KLQcp2DEYGHa%2Fx%2BqzZOZWWrgQTwFRZ4wdp2DH%0AsM5XX9MGu5wl1HGF3bzKNQC%2FSoyWFsrpCESFdTOOMAjBC0BL1Ap6pLtk2AsMlnWT%0APoxmlZ%2FbejCkLRDCJMgcDKXJL1uHf16cjyjTbstDPDNxzcVMISsfBxuYhcPDICse%0A%2BXJ4rxQL8CWym05JEG9OspenjHuuDK07mLNkyDcv0jruFhy%2FVftJnGnmwheMGk2b%0ASFC2LMqYEduYIlc5vSQYajFZnWjzOtxh6CmCDyKPDhhP3jbFEKJix0m8jeFlxlmO%0AqsXNVAO75FKZxTqpBxPpiN3%2BLj7Aa9k2JPGZ0BCT5TdqxLmIUzyKWyIVB7D%2Fg1c%2F%0Aa7qLLtVhwQV3l0ckc7txHVXXMPyhvJK%2FTC3E8Qnmhwb9t0AjdcQpW0mhdQqB6d4I%0A6NfoWETjuyxiCxnJGdng1%2FJhxlRAkGnyOcuWIycv14nfXyyZTR3WGsiCNrv8mrLB%0AdYRi9jMBH%2FSNh7wO4xxYJL5Izpa9uCGPBJCER6LadV%2FrjWn0LOPSq1HT2ZqzgZGQ%0ANtZBuQu%2FB714SU3M8yL1ySEPAqmwAtvke6y4oMdJogSSUMiYGNj8w1SnC58Kin5j%0A3NT%2B%2F1O58EbZ7u%2FkaubgmgQx6kMs7aRO9Ri7Lcalgt%2BA6FkAeCnyiuQ2xbehX2oz%0APZ%2F6DIejX5dQ362rFD1RMemLhi7bh5mIoyQgDz5DziVj4SFIioNv5%2Bn6Im6A3iYb%0A8xsgxlKBOb2REdric6RfUPuIX8tq7yhTGVH7a%2FIXLxhaJHUYJQUQVmhQmLVaQvB4%0Au8zpwVmdr0YJ6B8IaguDwoF7Zr5m3fUVZH8%2Fu%2BqVE%2Bhn8XGzWNcxuUwbU8aNE4G9%0AdAKZ%2FTxCrh%2BBibsTA7LkT%2BODaL3T4inJYrF0xcJa8h1SSot47mc74Ixz6iUoZIeX%0AJIRbI9wcwoJflQvSOy55vHEGBVcYoowab8V1WY4%2BPmQfpZKkSqPuhqToq7PvpSpR%0ARGeHL1v1H3f5sQIbZCKf7a%2BCvoWwcEdsLhKU8mVyrDhLbVj6kLy%2Bi3xADBLZ0y68%0A9kMdegb4bppAMJnFLgHvogqMKrXRTzRLGC09cllK90i4Gp05ez%2FacciXD3oVecvo%0A0icQ7fz3sjpqhghxotS7WqXHYJuogXdeFjSUFKg2biMRPZNEhtoN2ybgpZcWL5Yi%0AeTFzCvIP0JA7U3eMuBpFbZr6hEzzFbqoPcS%2FeOks1h9NiMLggLcZUWrrb5ZSs05I%0AKgKFNLqkQNTeK0r2X%2FP03qFb7YD4Sb%2FQxGqZaan0cNj8mL5BclwBZKM3QouEsbeN%0AqUQ0mdPf7dqRu7KO7rCQFYWYU7nIDOrsppbJ8m4r2sOKXP%2F7YSxoiK5gtX9lTDpy%0AlUGmkR1P3yuSupp0%2FI%2FfPdRQZmVV6yizFNPluDkWC83TTjk39Wd44QV2ZFwAGI2x%0ARn3%2BTZoxunxYWPaOy8wbMiO0i9OIAxAPVnGFjQB4W3eJLVdkwjBGujdX%2Fk1MsbtG%0Al75lW5HAbn5EGvmyRoS4O3J7LF7MFiVxEWbqnbG532w8Z%2FIJYJ2Dc42q8nR2p2dQ%0AlxQ8%2FI4I166THh%2BTmUYA%2B6wi8UeTBtHx69fYK3Xt8x2ZJQh%2BfjWGGeVNRyLX6j1j%0AIjMzsER%2FLiih91BqkekWCC1eRmPJkC2AZVaWlWbutZgbZlM%3D%0A%3DV3XT%0A-----END%20PGP%20MESSAGE-----&account_email=flowcrypt.compatibility%40gmail.com&senderEmail=none@flowcrypt.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '1639b8ceb6c44a4c', + { + content: ['TEST, ПРОВЕРКА', 'C увaжeниeм, Пaвлoвcкий Poмaн Oлeгoвич.'], + encryption: 'encrypted', + signature: 'not signed', + quoted: true, + }, + authHdr + ); }) ); test( `decrypt - [enigmail] encrypted pgp/mime`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['This is an encrypted message.', 'Not much going on here.'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?account_email=flowcrypt.compatibility%40gmail.com&frame_id=frame_tGCJGTMBdi&message=-----BEGIN%20PGP%20MESSAGE-----%0AVersion%3A%20GnuPG%20v2%0A%0AhQIMA0taL%2FzmLZUBARAAmSfoaXFbA0tv0ulFxViTwrDVcbPHaPQxx3vaX2cHLABe%0AKS2P2wOekq%2B8qD%2F72MMWMU%2Bvx1fbVu%2B0MDkAEcygCP1o54mIR8vYGkpL70JaLyMF%0A0jqy8LKfheJO5o%2BdBYMv3rk55%2FQlMgrKSrXUmGr%2FEAM6kLh6UwWS%2FK00TFrwmPAx%0A2c4ngRQLqyHyg9DOLL8x2SkBoPYLHTycKY1oM1CgdwcNqjy5RXDwrN44Ws8HRX57%0APKLgrAM%2BvUv58bThYT2oS1L2l7rIq8S0n2eFI21HHUQFDA3rBJJyvmhV4JAy9BLi%0AUYqmBDjvMtdfn9iBkFhzapORqigAUds4aTiBnwWijgfuzilXq97OTmb%2FHNVvPd0A%0AsXY8u1c6snBqu9vuspu%2F2qXPLYh06H1aQlMP11q%2FhWVfVLnj8vFmYpwQREVe8cXd%0AKVWN8%2BhYiqKoSmu5nKbqwXMqeHjS9L%2BEGZMyiRlSwImUq%2BB9gGMcTBFR2EC%2BOD3U%0AweWhseK9jIOio0otF1EF4pV%2F%2BVUU2gPCZhUrytGItwfcDxyo2DPWUun2SA9EDH3%2F%0ApGf6ODUwCb67gNDDFoR%2BY%2BWxfGCKK1CSPAEHHnKXTUP1483IzUHWxP6R0%2BxhgypQ%0A%2FufEhXOVwEjdV%2BCTMlENeSNpQdNt1tyy2TMhlNd1A0dnRMivvgVpqk2hHH38iGeF%0AAgwDluAOlKXQo5sBD%2FwLeNZiKJznLa65VNzJot28Tc7BOZQyfmtbjF9H46RRB8a8%0AICqu78K8Paf9QBP%2F%2FWcPL0RFvWf42k4fZ3dy3DgPcwZourYKJpvFkdaiIuFQ1ua7%0AIgH6sJjTrv%2BbsBbCNloFTMgljBldmiSXSZPdOjf%2FAt8EU%2FG44Iu9NWzuowMDgXiZ%0AUfTUm3RXdWYYi84WlL1oMWdMTrHmvpd3s1yat4Y7yaBGrlxr0Vep6hmUAXtDqEep%0AcjPr%2BBl0tzXC9XJ9RJsAp03pDwEkfXiSfIQB9yorGF46XOT%2BdRnicwk7HgUQIkw1%0AbP3xsOFpP4R8xda3QZ0ySDmn3E4bAc9T6Lu0qKEBr6cECgZXp7NfJxpjoQbnHxd1%0AqS0FXmbTuHWagJbESHqXtrBBz6Ug%2BFoVh4fuxy5%2Fu3QFMaVFRoAyA3PbUTbOfiJa%0APMiW1nTJG7ofspKgmsg%2BxFqg9%2FdLepgBw2QU0azsbXPmmSXGJEwlzrrvkKz1EiK4%0A%2Fp3r5Agj7S4jXSUsDEhWFmrmqXmj5Sv3EcC2Jew%2FzykWG5NOMxuq4mPTWx1cK1Pu%0AP1eBnzXlHMZWNBvn6lDwPv1CyS%2BT5SrTjxuFmJYs6sPGioVIT%2FiVmAVgh7ctqV2a%0A3daPU5bLEVVH2m4mcMwULbQ9%2BVc1lIbuG5PlJvAYuRTy3QEsGs2VFd2t8lG%2BENLB%0ABgG6E8Ln3ziqECqQZV4WLTn5fRGttKuA3%2F%2BosQBC55%2BtcPsKk6j2J4pxaU8KwK4z%0AT40MKFRpBTNXZQOEWEvNngv3RsM3dp6FvVWgUoUhu6340H7OqASuKd9QoiqIZjXz%0A4O7%2BqVzjpJykiJyXoJDTXBCF9BO9SvxADG9IDTUsJ1iFYRDkWH3jjf29E3l47zru%0A4PFnKMQsDRT9UrtAjNR%2BHD1AZakZczhljcRql83rG7hDSOjBwUML%2FckpJ3HA4wx2%0AbeAN4y8ywJPHWbZxcT%2FwZlLZzIn%2F1us%2FQhYtIfU8%2FhPaU0N49oMVy6SU64KA4rgT%0AjUVhUoBIQ3ivi6hs0GAUAapcwdulEcuvQEJ1JbPXMst6aU5H73MbhjYTNduK3QZc%0AXpokQN8AZYL9pqbUcViMLWBqznuF%2BbOIMKNftEoj9MVPbHVKvHIZZQrKVZb7UMcl%0ATcSsI0Jm%2B5fWkdrHkI51YxcrVapNkT%2BpGo%2BMBzTVtw7oZ844eVYUnF44AjaDEr8x%0AR3lQ%2FHSh4Hy6ibRJ0ZGQZsbAg1SLAg%2Bhg8hzg1uuy9E0MDaI15mdz7FrsIwbbi8O%0AuRTWDQgLQtxCY45xvSmVJqangIg8pkQ%3D%0A%3Dv6vs%0A-----END%20PGP%20MESSAGE-----&message_id=15f7fcace2d72246&senderEmail=&is_outgoing=___cu_false', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '15f7fcace2d72246', + { + content: ['This is an encrypted message.', 'Not much going on here.'], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - [enigmail] encrypted inline`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['This is inline-encrypted message from Enigmail.', 'Yay.'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?account_email=flowcrypt.compatibility%40gmail.com&frame_id=frame_vCSPFGeIod&message=-----BEGIN%20PGP%20MESSAGE-----%0ACharset%3A%20utf-8%0AVersion%3A%20GnuPG%20v2%0A%0AhQIMA0taL%2FzmLZUBAQ%2F%2FRO4wLVr52Zf0v6%2Ffa19%2FnoJFsFLIEqsWkX3OPOZfiRew%0AtcI17dq5u854lbuXwSELEAUkhX0NJ2ZM%2BjNPRyW4dqhcuFBebBXN10%2FpzBaG%2BnKi%0ACK3B4mAhqYeFAzVeInFS9MPbp1%2BXzcyPm%2FkPs2oxISk4CUGaFClSTGFUdRjdwVyt%0A06BEVx4o0dvu0em5O4sbmAqAictL9Kc7c%2BBYRmvIBBat2xkJtoOix3HmJBcNR0w3%0AAQxoB1pKkbzqOtweOhcP9opSvO8GXx%2B9vXzSi88PJ4uMKOSFUbtKGavMyXYkKpIs%0AN%2FhYiK4L0B8%2FqcJS6LsM26o0kZsVMg9pz%2BBK3ZspAyq3QnMRGaVezzrA%2BeA2%2FGz8%0Aou5CU0tBXMLbuBPj8qWBBgaDJzWBJyQ9VRNwx1OE4yWN%2BR%2F5H38fy6Z%2FBj8NiueW%0AbSVVhXVdwPzYoG6Wg06CUS%2FuyjTUtUkGGy7noii610XLsOhfOcsBcYOEwFuQ9FYn%0An9x2qMfo71cuWwtDcxdUBfGsoZzJkn1auD6XfHrJY5fux0Ji%2Bav%2BnkWtgRsu2%2FJe%0ABEFikuBYFZxjWOiArGGybznVZXE8m8ogZWYMlyQYybShs%2Bctp%2B4Wx5oNWBP4E0Jb%0AT3qW6GXSreP%2FECfZNUggPgONUYm8YKTZoWgwL%2BsxyDlL6snZMidP4FrC35BnvQ%2BF%0AAgwDluAOlKXQo5sBD%2F9h6N4KWlL41e0jHJX%2F2KbPXg1%2FcU%2FW4urdFxmx%2FHu1y9Y%2F%0AJ9VKYxne3HwJb9BxNu6g1QJirGSL%2BN4dH%2FbaR9Bl01uPdR6KZg06lygWeVRIMPO%2B%0A2ytla9Gx9lv%2BG8bXM1adNVbCeRX%2FILvU13SM4rO2eHvZodBQ%2FYyaQfUOc59idNHx%0AaXSDT19%2FiBVB67Xxq%2Ft4J5n8xWt0b0gB6pEzADnJ92iK1so7iviSxWbn0ld4E9jf%0AczalFCZBb2Hlqlt7qUyOQvqPIw5YR5R24o4TFdtq8DzjLdNfaz8eIlHjuh%2Frvprq%0AxBhdqgWFMc2V8bOPIkQSmYfVQXPLWflnWV0MHuoo7RgW33xD2ASPKHpUX1br65C4%0Ahsq1e3R32tXcOO%2Fbh9SoJKj7vL%2BNP61QYkarmh30yh5YxNcJV33lkmZ%2F4AvF8fRa%0AeeTQdHKdvJtgmMgWuRSeR1zKSIadvylGZotqTI662pfm%2FzGjdVj8gJWvcN4XnAqI%0Aktg3mpI8mRS6yzDLcbWI%2BqFkcAkBfkK3HTw9Kqj596jQuWbd08ORm6NxH2L47BZE%0AfV4OiTm5mJFn2eRakrS9UmYhVkvL9jITXwhqMy1Mj72qxZVnx4PSnn8wgMt0Jd04%0A36QKwsmsl4oaxBAt95QQVu5a3UQa8P%2F2vTdinKaLV9voQdFW5lcOUPVO955ms9Jw%0AARLIm29ptBkVK6N3fquEQQtssR4Zt97HK4O7l%2FYilRa5m9iQFaPIqasHHJaVxhKM%0AZk3zfTTNR8t3%2FmoaSbo45bXQk4Vgmux1ATrNcKjyIRiNqPRz2tbJIc2H05naijsb%0AyTu3s7CnSECMWF283s2Dtg%3D%3D%0A%3Dl3WP%0A-----END%20PGP%20MESSAGE-----&message_id=15f7fcb7fabc7511&senderEmail=&is_outgoing=___cu_false___', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '15f7fcb7fabc7511', + { + content: ['This is inline-encrypted message from Enigmail.', 'Yay.'], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - [enigmail] encrypted+signed inline`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['This message is both encrypted + signed.'], - encryption: 'encrypted', - signature: 'could not verify signature: missing pubkey, missing sender info', - params: - '?account_email=flowcrypt.compatibility%40gmail.com&frame_id=frame_NYYEYtuCVf&message=-----BEGIN%20PGP%20MESSAGE-----%0ACharset%3A%20utf-8%0AVersion%3A%20GnuPG%20v2%0A%0AhQIMA0taL%2FzmLZUBAQ%2F9FX0uRThi4ZT1KmNEZYS3WC%2BNoqommn5szVhI72E03HUp%0A3JMub2XMmU80Oe6WybHancEZw3w%2FoWR5CvdQx9414jub4uXxaE91wBuqlS3Ow6%2Fo%0AXfXZAzT0aEz7jXkh9rAZDzKjwqJjD%2FUICHmZsgVsx1%2FZZBYNBpbh2esDFGcCE%2Bn0%0Ahgd5%2BekbNqXU1ByU0eZRMo30u3hw4RAp3dPcfIJO3mTNUTXbAunHztbvGFk1TI2s%0AaSxvJQ%2FQNt4IRMaVG7pl%2BGwc28ymWbNOv9vVQQB80TJt5x7xJ8S6MitoAzTZ0KTa%0Awj2BQ9JPO1fgxTw7Zehab5UhQLJXsofe0WnU7XIxzFYyZdZSGNq6u%2BcI%2BDfUH836%0AUDYyEOhlIOyYf8SCd7B3AT7Wd4%2F5c333EC%2FWnG7W7f8RsdWAQtf8E6iWEDgnGmvu%0A2trxHZdTIOhEqwgwPWkVX0UjBdJ7U8nBhP%2B%2Fcsn2h6bpxOARFpXOwgmlmjjA%2FQQL%0ARgaK0TCy7JcnQ%2Ft9SCGw62YYQsgF8RCUPvmz%2BKpZV%2B9ckwOlj8vN75sxFtitd%2FHq%0AhSVMUeIsgBGvo%2BOxFA%2BNFLQTxd8T9hUNpU2Y7RWv0GLqgQtj6GE7ykh4I4dcb%2Fgf%0AIApF4XKnzGlOIoHNUf9tOnY8JV%2BTLbQl3hnRX64QCNimglagQ0yxe3p5jzX1uImF%0AAgwDluAOlKXQo5sBEACU3rx6u9Xh%2B61DcpUHMxgQ43KqEXWwMpzk8YudWrmNKL23%0Aa65%2FOYpyCBsL%2FD0%2BbVKvLMhmyfaz09M3q5lh86oNrvHHFsbDOKzHlAeBF9x8%2BHOR%0ALANj0TCttNR08e4i3HPbUT6uK%2FfKlHbqA6%2BiKgbBafbdHJreXtKKS7g9erEYgBYe%0AEg14s7X8q%2BnHXZ5sS8%2FptWUh3CoVtRgBsYe6AgH%2B6uDvtQWu%2Bm3NRZZrTBUj94%2Fv%0ABlkAV6ptRbTsBWQJZjRaKGQuN115WBrKAoPzIXoIk%2F3LJSe1zZU9kpmdJ4wrawsE%0AwcMRJSjYWR2mjpIKZZa2UEMaHSNKD0tfMYnt2etvmDrrt1eLMfzd8Nz2Z4rj77c9%0ArfI8nQgTmX5EaHJQ0PcJ0H0Jn514gz3wOh1B8zCD34KlS%2FwRl4v2bc7ModN0pTUI%0AeohNA4j%2B9GamJNoMPbLGi7o0JqagLTPiF4JuuEmV0Mu%2FpjWKiik%2BSi6HIddXsP4s%0AWbPfIVweOhCKfkN161TwSw%2B1cdHOw%2BD%2BPAxMOCpSDU8GOV94uoTL0JtJEdAaZHsj%0AZZbMGC%2BzATIKxpoXIONr5Qwy50hHf%2BnZRQfvfn8il%2FF0Noyg08pMafZmAUjWQgSm%0Au9bE3NkTF7FXYrJ%2BX2687i%2F1KJ7UrjhJQFcz1%2B0wbRmmSmJlqqw7AJKxzO7wRNLp%0AAZlYT2fl7jLUvnq%2FKeEhpU%2FHIQ8kiHC31J8%2FSYBvt1s4%2F%2F0%2BcykA8bKEC43VKZ3R%0ApncO5P3LasxCMm6dPcrWuR%2FoN8UM8uTQjUsxhJlF6fNUv3gDqt0em24ZogKuKpzS%0AIPXX9EGotN5XxKgbCY6lAOiHOjHJ0tfMpPQvtqP1Y28mJjp%2Fx3kb8ul5h4H6Uigr%0AB7u8tHIbR82ghbqzE7vKrGld%2B31hP7sRKthtd17qJPEvDfvwW%2F6C7q8Do2PObVqY%0ARqwzVWns8mrkTuzJgzSUgWCHBU%2FrDVxf3ucVu7bDqCYkWVkm7bd8Gpy0%2Bako87UM%0A93Fa%2Ff%2FTegrWGbFqj2maoPgBVHCe%2FaEN2M2dyjeltqW9ATHyeelq4PgqO6i7CE00%0ARC5ZKpdPkMruroviP%2BWr59oIxEU9YzTVwv7B4jIr3I9ZxFrrdz5xIWwA3kfHoBs0%0Ay8H01tkzJVFlL0tRTd6SZOCMao9SXFa16SAd6boL2rzB4KhQPl2KYop4jFQGPvBa%0AZtlGgI8mjL5UH94YAO%2FpMQb5eB0fYxnZ5WCrjr3PMjg%2Fw9OB8y6DL7cpI1%2F9kxqP%0AfPlnDv%2B6U%2B8%2Bc%2B96s52C4QIpddeAqsyDbiUv3D7KfajhF0WDaf599YK1TAyOR3tX%0AtmCq4JtKQ9%2BHehztvwDM%2FvWf2Ku0hk%2FHjPwJ01ct%2FJLAGm1UeZ%2FjuhaqQldmOMBJ%0AbhSHT9U%2Ffy72GWNiDAeX6f4Fa6aJuOVKYjDUSAhdgGsfdfrPJ7kJPcOOyI%2B%2FcC1p%0Aasvfc9OvJWyZ716Md5j0hTVfKWfXtnhzKcGl8nrA4XYZGA8%2BlZYamefKzIVm46kw%0AowsB15NUI773ZDTddSCL8c6JQuOt5K0G60w9M0qxYouZEnWT4LE8eg1S61Vrbl6P%0A3yiG7MDy2p6%2FFlmCZgDHQRUqkiuCGUVpCwKiZwNzEMqe%2FMNx988dMknwadXEAt%2BI%0AR1xpkkyUDD8cdbb1%0A%3DWrMi%0A-----END%20PGP%20MESSAGE-----&message_id=15f7fd2fd072cff2&senderEmail=&is_outgoing=___cu_false___', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '15f7fd2fd072cff2', + { + content: ['This message is both encrypted + signed.'], + encryption: 'encrypted', + signature: 'could not verify signature: missing pubkey CBD1C3466E9C437F', + }, + authHdr + ); }) ); test( `decrypt - [enigmail] encrypted+signed pgp/mime`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['Message encrypted and signed using PGP/MIME.'], - encryption: 'encrypted', - signature: 'could not verify signature: missing pubkey, missing sender info', - params: - '?account_email=flowcrypt.compatibility%40gmail.com&frame_id=frame_POsACRbHGk&message=-----BEGIN%20PGP%20MESSAGE-----%0AVersion%3A%20GnuPG%20v2%0A%0AhQIMA0taL%2FzmLZUBAQ%2F%2Feb40AmsR8djZANi63cCx4sk2TIlNauZ9OdnqMEbII7sB%0AYoK%2F0KDRnH5I0cNfwpFcmXkUhrSLKtn0%2BfyCrxrxo%2FQZZO8fD78OqUu3ZwC3hFPm%0AOiLlx9oI48hj3Hrw%2F4CU8FQtboMA%2FqPPLqtjnIJLDHQiZayCF6XnokHNF4Cj3wqn%0A4%2BGn8AakUGsAr7iUyIkZ%2B%2FpR0VbPSgejFgddu8H9296o21MR%2FtB%2BFN7DK%2FL7fa69%0ADZyLLdGp5vPHUB3GikAuS%2FpoyggRc%2BlSUa4T6jtjUSAUGtOUWtRgBFLAeeuHoskX%0A6tw5A7OyDBTGyQSWIRb1J5N7P5dXrU%2Fvt97pQhrVgRXxfbeq0OLkLm9G98thE%2B%2FG%0Amww5CQ%2BZNfRMouPzBDPT050TGB23JMTxTx8o3bPLb%2FUCmB2Qhtb90XNcUiyU3gyJ%0APnkI91fKGftT6bG%2F9lk76RusZnEqWhNEsvXS8KF59pj3Ea1cVeowwQZq%2F57C6pWQ%0ANSKMQJI0W3VCCyrxMXbedqbXfVuI%2BmOYt4%2ByRKp0mPWced4d5nV6O8qICrfr3%2Fkk%0And7VtWqRL7nDTbcPWZNSPOP%2FDHj5yZ4w%2Bcq%2BrOj5AtjRsbWIt3NR%2Fpo%2Bhyyu3zHD%0AM4GktXqPxtDZl2HsTC6gc00CFP8zqTKqnDpQRZ%2BKl6xfvemPQLmz4pnrzEyEsbSF%0AAgwDluAOlKXQo5sBD%2F9EObMtDbWnqtRpIIYXp3es47FPBKgR5Ouc%2Fcrtf3K9n168%0AMp7K%2Ftt1JsrCnO4o3ojiIK6O40IilqnhBN3hFYcRPJ2lW2jefJvKO1ksji1q7k6H%0AdmTz%2BjE3mow%2BPAn7D%2By1CVgTpvy%2BNg2Do%2F6UR0dny4Mm7lZhH2l2sCTH6FFXskBV%0A3IzAwSONtwkxpvT7%2BMqcq7k9D5P5hZTPuip8ck%2BIFr%2FEKUaJm8fAnTcbf5tRqgep%0Ac%2BVy4QxKXu6GgTDHwYwHLzVbiPD8GG5cApbpn8c%2BnfKqgjGua0zyYl0FUd023kZy%0A9c4Webi83NVMZDm8%2F5SCHvVJtiKJa0bquxy1aBO5nLlxxnIM6H3oB1UrQpij5oC1%0AktaW08rwBSkDHnaFLfW8bxdyAkjsibahvIW3epIK5aLoOiDkhMIhkKaBvBOOSVet%0AO04XJauG2rAeYF9JFV8FxexOncXBSZfBFWHjeN3b%2BcriKuD41FwLx1nIkVIZYd6a%0AYXxvby7jKTO4%2B8Xy%2B6QuDFPKmUIRbSZZ07n8D6ZsJzwcU4MIBCthM320oIFnD9W4%0Aq6dk56Jma%2BrWsLbQoqh4I1rJ2kJ3yT1jQWBuAwLWz5Hzdomz1Q9if%2BSDlQy9sjl%2B%0AO%2BzKB34vcqfet3wbA44P3ROhmanBa1TOoBG%2Bwkhh8xusHyJd5aU6AbuEoi6XrtLq%0AAS31F9NVnEjnCykrBZIj2B5TlC1mT0yENRyCkqEvmBWVjM%2FxfiW2vBpmEj%2F7rI%2F3%0Ap0eQabbyVSHXngz0IlAch%2FcV8wp58tXkVUpWzn6GU0B1KCxuc7FyPcdAAThNzZP0%0AREhuIRgjJSR%2Bj4okHgJhKnxfvIxqlrnKYNyGWEvvL61D2nBiRlCPGl38CMSlT8eP%0A87hU2ks2I9ztv4l9Z9Ob639nYFBLQ5UlesUgQND6d%2BfHqk3mdC6Hzm2kHHBdujgl%0AFuj66eGrfgHwcNCtQiNkYXcgh6TmcIMvFgOiE1PyE3v6x04N7I71cFgUNkoeo4ke%0A4jjOgGJJHRDofWvTGvT4JtCnoqLPahQWqtR%2BBNMY5phFEVtsfuMND6fJTkzYEDpQ%0ABVM3NmukPaw6LIjlN1EmoeSX2BleqvvDIk9rAt3iekOlioYKqvk%2B7xjS2O9otWX6%0A15mHWRx62Et4RSArvRJdGiUP6UTLqGd89Il574poQXBMBDfkTvf%2BEQwgpeb8WEha%0A%2BtFI2aTMj3mlgskEUXSxtO0ZB7aORfCQiy2Jkf36puEfHwOy0l5YnQshXa%2FyJCQR%0ACIc4H8dnSuQlkgRnSODOnYGqpSqfU%2F7%2BMcM2na1jhsVLX6MPzSr6bOSB3QwTbGTk%0ALdO89dD3dnMeHmVjaKTg5wo6i7k1ERE1Um2gHMlrtW58AZN4KPABp07BXgV4H7P9%0ArkIBP42cfkPoUNJXd0BCGEiOg4%2FNcTjSg1%2FvWuAvmWEN28sABfO81d7ucGZtt1Js%0AuyHpVmumoSD%2Fi1woR58iwSPd5L3a4Ax%2BBCg7t0yTP%2FPJRtX7hvSh3FajNkE%2BexSq%0AJZPLq5CYAPNagBWY%2BYzRWTJCz9nC%2BpuOpxZ08x%2FdzX4AEcwvAG8pg0%2B%2BBo7JwDd6%0A8tm0I5LUXXm%2F%2FVf3AQf0GTfpM61bru%2BTyvjvRhmQJ8S5qwozazZtrJUpDQJDKhPY%0A%2BeMHgrlBDTHtXVLXfT0qKhft1UNXCY2v%2FUUq4C5%2FNjm1KHfMnydhHg%2BvzEg9mE4W%0A2mdbWVSz53XdfzBspAYE88EIT%2F8W2biebllWIuxb1%2FIbIpnkV0u5Gja0OB5cVVmy%0A64zNOOk5sgOIlsEgpgxAU8nHrnmg9585XiSjTSMAfb5h2zbQU0sEkOHvADnn8Asx%0AEWM0iquK7lpMaQKpE554UgBcDMjbZnhss1tZf5uz6SX4YEI2y64kIHXiTEL6sqj%2B%0Ao1XWkq9SDZOuvbq%2BUOgB6yaXwZr%2BB1fj6fGqozyy%2BHbTdg1Y2a%2FbTOG7%2BrM%2Fdl%2B9%0A7BUVZsCiF5Cs%2BVRLNmIpfpH80U4AGHoTyATsybiH9ZCZn8qsFmZ2hNpeWGrM%2FbQU%0A93We0G5lmun1qd347UhncEvfhtyt449iHytWebexzDqDMLfuo5BZtVfe%2FXJFhriP%0A2zFLe9gZu%2FOjM%2Bl6Th6UGJ01jrUmqKI1veai2y4jqzqRZbSg2EinBAp%2B1hI%3D%0A%3DFgMR%0A-----END%20PGP%20MESSAGE-----&message_id=15f7fd3ba3f37cf3&senderEmail=&is_outgoing=___cu_false___', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '15f7fd3ba3f37cf3', + { + content: ['Message encrypted and signed using PGP/MIME.'], + encryption: 'encrypted', + signature: 'could not verify signature: missing pubkey CBD1C3466E9C437F', + }, + authHdr + ); }) ); test( `decrypt - [enigmail] encrypted+signed+file pgp/mime + load from gmail`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['Message encrypted and signed as a whole using PGP/MIME.', 'cape-town-central.jpg', '185.69 kB'], - encryption: 'encrypted', - signature: 'could not verify signature: missing pubkey, missing sender info', - params: - '?account_email=flowcrypt.compatibility%40gmail.com&frame_id=frame_ZFnrtBtiit&message=&message_id=15f7fd7fe45fc026&senderEmail=&is_outgoing=___cu_false___', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '15f7fd7fe45fc026', + { + content: ['Message encrypted and signed as a whole using PGP/MIME.', 'cape-town-central.jpg', '185.69 kB'], + encryption: 'encrypted', + signature: 'could not verify signature: missing pubkey CBD1C3466E9C437F', + }, + authHdr + ); }) ); test( `decrypt - encrypted missing checksum`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['400 library systems in 177 countries worldwide'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?account_email=flowcrypt.compatibility%40gmail.com&frame_id=frame_DfGthWpEth&message=-----BEGIN%20PGP%20MESSAGE-----%0AVersion%3A%20FlowCrypt%205.0.4%20Gmail%20Encryption%20flowcrypt.com%0AComment%3A%20Seamlessly%20send%2C%20receive%20and%20search%20encrypted%20email%0A%0AwcFMA%2BADv%2F5v4RgKAQ%2F%2BK2rrAqhjMe9FLCfklI9Y30Woktg0Q%2Fxe71EVw6WO%0AtVD%2FVK%2Bxv4CHzi%2BHojtE0U2F%2BvqoPSO0q5TN9giKPMTiK25PnCzfd7Q%2BzXiF%0Aj%2B5RSHTVJxC62qLHhtKsAQtC4asub8cQIFXbZz3Ns4%2B7jKtSWPcRqhKTurWv%0AXVH0YAFJDsFYo26r2V9c%2BIe0uoQPx8graEGpKO9GtoQjXMKK32oApuBSSlmS%0AQ%2BnxyxMx1V%2BgxP4qgGBCxqkBFRYB%2FVe6ygNHL1KxxCVTEw9pgnxJscn89Iio%0AdO6qZ9EgIV0PVQN0Yw033MTgAhCHunlE%2FqXvDxib4tdihoNsLN0q5kdOeiMW%0A%2Bntm3kphjMpQ6TMCUGtdS7UmvnadZ%2Bdh5s785M8S9oY64mQd6QuYA2iy1IQv%0Aq3zpW4%2Fba2gqL36qCCw%2FOaruXpQ4NeBr3hMaJQjWgeSuMsQnNGYUn5Nn1%2B9X%0AwtlithO8eLi3M1dg19dpDky8CacWfGgHD7SNsZ2zqFqyd1qtdFcit5ynQUHS%0AIiJKeUknGv1dQAnPPJ1FdXyyqC%2FVDBZG6CNdnxjonmQDRh1YlqNwSnmrR%2FSy%0AX7n%2BnGra%2B%2F0EHJW6ohaSdep2jAwJDelq%2FDI1lqiN16ZXJ2%2FWH6pItA9tmkLU%0A61QUz6qwPAnd0t6iy%2FYkOi2%2Fs1%2BdwC0DwOcZoUPF8bTBwUwDS1ov%2FOYtlQEB%0AD%2F46rCPRZrX34ipseTkZxtw3YPhbNkNHo95Mzh9lpeaaZIqtUg2yiFUnhwLi%0AtYwyBCkXCb92l1GXXxGSmvSLDSKfQfIpZ0rV5j50MYKIpjSeJZyH%2F3qP%2BJXv%0AZ47GsTp0z5%2FoNau5XQwuhLhUtRoZd1WS9ahSJ1akiKeYJroLbTg10fjL25yp%0AiaoV16SqKA1H%2FJOuj6lT5z1nuez35JjeSpUc7ksdot60ZovMfWC%2BOGRnkYKb%0A7KxFd7uaxL6uOBOFyvRxYeohKd73aVkiKpcWd4orI18FhlftFNAwIdsmfzNc%0AmzTHZaUl89iYxEKR6ae6AKws1wzLq0noarsf2eKBVbTSfmK3S3xFqduKINnc%0Ae5Yb3F5adSj1dUjm1BZ4aqzsgKyBb%2BJ8keG9ESsnFOyxOIUXDM1nIo1IOgzC%0AM928Jb9GVa%2BuhdXRrb5cLjTihTusJN0I8oJrwKkwIpCJVgPMdDLkeubrMBQ4%0Afbpl4V76sOU2Nx%2B6nG2FnFBFBFohOL%2B0nTK5%2F6Ns9ateN7K9VP%2B%2BQcoeqfPk%0AIUO3%2BlCZW%2BtrTSvvFId3ziUVsPTeuAS%2B7nxSMfWZ%2FK9Ci6QV%2FXnx3F%2FqSmuS%0AAUm4zPQ1EjZf1N%2F5K%2BvhcCTN4MMx406VlqtedkXL2KPwZ6jDS%2Fww8RfcmPnD%0As94ct0WCZZtNlnQq%2B5h0ybwTJNLC2QFyrhhPqztVY95n9La2Mw5WITCWzg%2Fd%0AIBUceW%2FOwHYtePyaSQkCnegDw%2F2mN2%2FGC8d0OlwULcTYG6uVenGv2UOUbCr3%0APfy%2FEb%2FVqUEZK00PdvVQV7FWYAshuTFPTqidph04CgQvBpi3SDEEo8SkEIFS%0A%2FiEeRQaWjFEXKUI3FwKXPJQWvFpbrXBOAjnxXXbAFYOLxdydmq1GVl9Mm3GU%0AClc9g6t9vaYDBPx2gN562%2FCM%2FnT8Vq45VHe79XkrrcHDwLn7yeHJScNFsib%2B%0AVvwTPoUftlhC%2Fai21D403TsJpm7ZmPcDjagoIcXrS%2FlN03z79RBmSKFtYiXW%0A4obkKSGow61vMBh2%2FXLVYKJKpYKm%2FGnVlJxA0zQVl558x8I%2FnAMaxSzwx%2BZY%0AwaVU%2Fs5PLZ7Ghg3MOguiRTlflKUQyL0A7NR46OjFgUnHAZRxr4KO3GoxVPy4%0AXLeS4%2BWl68s7QlV6WF1IKCHWEUMEeRRea2%2FOvvlS%2FoLs2MNNWDemlJ4SiXHf%0AxINU38Txo84A00NALbKppsSyy9Gwj%2F%2FrO%2FFcerupkfeuOm9nHFwIQeeC5bWD%0AmmRlC90r2jY8gM%2Fv3Jjy9h8PbXWxh9MUpc7%2FkAcTwdGlMxiVjE29p065qTRr%0AOi6sJ7pWuYTfWldZqTVmaBjlv0zuXQ8Eo8o%2FUSvoTs%2BoihYIMcqReqdeqr%2FN%0Ae%2BsDtYKRg%2FLKp%2FJJ5nAQzVMP67DxkgwLNxx0ijBLysaQmvRlsiYWayxZB1Xd%0ABxA2bjZRvsmww%2BhgSKNlcsiubJGBqfqvgmlebZuJHHSC1L6mdMYgcihKmYAj%0Ap%2BHFLyqgyeRVMdjRHcrEdxNPG4fJmlk1bYiVQQ4XAd72w%2BAHS%2FseZ5HzbAK0%0AomuHYUD5PTEqZ1K9JObSsh3XMUkJK%2Bz3BnrOxnTOOyG2r%2B4FxizH6rfz%2FPgg%0AsPxqxE9ELUlgQe8plcPFge6aN9tUoSe%2BvMtDaEAqKw9JwofBF7jlxTqMMvQC%0AgWbn9x3W5o4VrnpjYGtPl8sh1QREu0A%2B0PUJAKL4A3GSMYRouGewLSMNJlOg%0A%2F0pPF6qB%2BFi4GJ7ju5C07tfr9z9UqRj09kDXJuoJd95NdSiCz6ndugn6gs8B%0AQf%2FXPxZVefeMLiB6p8pG0iZ%2FjcJjyYJLtTg6kA%2B1%2FffmJPfH%2F76ZA9dgEJLj%0A%2FW2u0Lp4NY8cwqcXuGKgl72TVJ34Iawl35Y0yr47k%2F7Y1vEQ5Q3bT7HP5A%3D%3D%0A-----END%20PGP%20MESSAGE-----&message_id=15f7ffbebc6ba296&senderEmail=&is_outgoing=___cu_true___', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '15f7ffbebc6ba296', + { + content: ['400 library systems in 177 countries worldwide'], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - pgp/mime with large attachment - mismatch`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['Your current key cannot open this message.'], - params: - '?account_email=flowcrypt.compatibility%40gmail.com&frame_id=frame_yVMKFLRDiY&message=&message_id=162275c819bcbf9b&senderEmail=&is_outgoing=___cu_false___', - error: 'decrypt error', - expectPercentageProgress: true, - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '162275c819bcbf9b', + { + content: ['Your current key cannot open this message.'], + error: 'decrypt error', + expectPercentageProgress: true, + }, + authHdr + ); }) ); test( `decrypt - pgp/mime with large attachment`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const msgId = '1622ea42f3654ddc'; + const expectedMessage = { content: ['This will will have a larger attachment below', 'image-large.jpg'], encryption: 'encrypted', signature: 'not signed', - params: - '?account_email=flowcrypt.compatibility%40gmail.com&frame_id=frame_yVMKFLRDiY&message=&message_id=1622ea42f3654ddc&senderEmail=&is_outgoing=___cu_false___', expectPercentageProgress: true, - }); + }; + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${msgId}`); + await BrowserRecipe.pgpBlockCheck(t, await inboxPage.getFrame(['pgp_block.htm']), expectedMessage); + await inboxPage.close(); + await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, msgId, expectedMessage, authHdr); }) ); test( `decrypt - pgp/mime with large attachment as message.asc`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['This will will have a larger attachment below', 'image-large.jpg'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?account_email=flowcrypt.compatibility%40gmail.com&frame_id=frame_yVMKFLRDiY&message=&message_id=1622eaa286f90737&senderEmail=&is_outgoing=___cu_false___', - expectPercentageProgress: true, - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '1622eaa286f90737', + { + content: ['This will will have a larger attachment below', 'image-large.jpg'], + encryption: 'encrypted', + signature: 'not signed', + expectPercentageProgress: true, + }, + authHdr + ); }) ); test( `decrypt - pgp/mime with small attachments as message.asc`, testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['Can you confirm this works.', 'Senior Consultant, Security'], - encryption: 'encrypted', - signature: 'not signed', - params: `?account_email=${acctEmail}&frame_id=frame_yVMKFLRDiY&message=&message_id=16224f57d26e038e&senderEmail=${acctEmail}&is_outgoing=___cu_false___`, - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '16224f57d26e038e', + { + content: ['Can you confirm this works.', 'Senior Consultant, Security'], + encryption: 'encrypted', + signature: 'could not verify signature: missing pubkey 6FC39F2CDD104B3C', + }, + authHdr + ); }) ); test( `decrypt - [flowcrypt] escape and keep tags in plain text`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['thispasswordhasainit'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?frame_id=frame_ZsfVUZsdjN&message=-----BEGIN%20PGP%20MESSAGE-----%0AVersion%3A%20FlowCrypt%206.0.2%20Gmail%20Encryption%0AComment%3A%20Seamlessly%20send%20and%20receive%20encrypted%20email%0A%0AwcFMA0taL%2FzmLZUBAQ%2F%2BMC4kEIaAIdbuApd3CIf72DSEy9%2BA9%2BKlcXbhbFiP%0Ah6bT0x7PSzKMAraAgIRaUmuX3WojyYmeA3sZOtFw5I1TXo2wX0WUYlWGtXA8%0AsgsQvf3voy46DEhFYKjpk38OqK77GWnU1t4QrNUqjQJ6pBjslo99yx9RvYpv%0At1X%2BN0OLcIevTh0R7tjidPsjQx8PRejhuIAgM6mI39n5YUB%2FVCMqDRrqQzrj%0AcD7%2F%2F4X0eJhTYjDGzrSdLtK%2Fn2zDca2XeHe3je4OtLGqYP19n4YgmjcEVvit%0AQsDorTdXwoDKp3gZ27VmjkL4ua%2BA4j%2BeN78HXAbKCf3Hk0xxOlOaDmAdKvZa%0AXVb1KZNLaAeE62GiEombvFhyihvKBfXxmBCvXBz5x6g83r5idLd7U6Ndafyx%0AnZMPvxs7uutxeJ3HG2oMvWPOhr00FyiJvMG8mfHJh6Coh4RkK%2Fe8oxeZioS9%0AL0ZYNpmukffcxTyD%2Bwm13d%2Bfeu%2F5DFA8SbBfnhEOW80dzpA7COqx42HkOlRt%0AbAPn9Ao%2Bv9hzhDmOrHTYiGBGBzRO53b5Wyp55pyYCY6r4LyR2%2Bs6%2BRrCVBo0%0AD7yjez9AqPw65sYi1qeT4UHtBzTbi%2F7ll3EjtphzLxTv1DyytMjqDUHcg7Qi%0AvrqLY2mfFm%2BudqbdR99WX2WzJijJRBwt5hExJMMA8%2BbBwUwDvb12YPaZjcQB%0AEACdW7%2BIK3RgtLjJmo3V964JR8CQkXq50XzgiA%2BcJOXTN9Jsc72W3Vs1xZE2%0Ap5D%2BI3b9qQOMgzWNpYF6N5NiyWFDtKhGyeXL2zoG8x4COyZb25al%2B%2BPMtTkT%0AKooVSbpYaRif6Q3vWVZ9C29aeDqxa%2FMwxoI89q%2BB0mO1oAweNgk7%2BZmjOeYG%0AfwxkYm%2BOGevabDWZrxKLr3LhhWIFeewPxfzyi3TqAZjEnEwkD0FYssR%2BLtSX%0AIsbXTdkV6j3%2FcuDHLdJ4x9nEr0mefpSNfzIwq4iDYdWR7huGjE%2FTkw%2FSF7t6%0ALt7OwsO%2BDVr40fYOi0vnF5h6GMxCgsHpMy7LC9iCpd0jL9wWvR6IukHOVEwj%0AWPmZ34M627IC%2FOgiuFllVmXdJ%2FbtBVEnLOyr6hvsMKtKqD0cS83FoaY2h%2Bn5%0A%2FG9WzSWjABIZgsQijoAIJc1C9%2BwwN3uUFocrgdF54Z9pbwZHUrnBvCYrL%2FTQ%0AAN7iBvQNkkoFAWeS1JMmGKymR3tqiB8pSQU9SP8rYJhOMcj0oezuZxEZG8ge%0A%2FyUijaF8X%2F7NgfqLoBym2mfoLxk2pEGFuhk2Bbtxi2LeRl5nzpCvO6oEYdYi%0AI1ERyOA39BezaN1kw%2BQrmpqETKm%2BInprCxGA1vUOVmOHO%2F0YHZBaYOIvk2Xj%0Ajkq6kVFmQxjFE9L1IfxbaGkQ79JVAUV9w66wcSz0yULr2%2FU6knQPBnENobl4%0A6fwiBkiSGAvKd9%2Buu6wJaZ5tYPWUP0HAuKccawytNmGREWAsffz%2BnrMsEDUG%0AJi09JiLTQU4ACCacM3hPVw%3D%3D%0A%3De%2B8z%0A-----END%20PGP%20MESSAGE-----&message_id=1663ac8b70e22517&senderEmail=&is_outgoing=___cu_true___&account_email=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '1663ac8b70e22517', + { + content: ['thispasswordhasainit'], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - [symantec] base64 german umlauts`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['verspätet die gewünschte', 'Grüße', 'ä, ü, ö or ß'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?frame_id=frame_TWloVRhvZE&message=&message_id=166117c082a73905&senderEmail=&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '166117c082a73905', + { + content: ['verspätet die gewünschte', 'Grüße', 'ä, ü, ö or ß'], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - [gnupg v2] thai text`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['still can read your message ยังคงอ่านได้อยู่', "This is time I can't read ครั้งนี้อ่านไม่ได้แล้ว"], - encryption: 'encrypted', - signature: 'not signed', - params: - '?frame_id=frame_oGBJClmooG&message=&message_id=166147ea9bb6669d&senderEmail=&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '166147ea9bb6669d', + { + content: ['still can read your message ยังคงอ่านได้อยู่', "This is time I can't read ครั้งนี้อ่านไม่ได้แล้ว"], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - [gnupg v2] thai text in html`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['เทสไทย', 'Vulnerability Assessment'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?frame_id=frame_NBokFyMmgB&message=&message_id=16613ff9c3735102&senderEmail=&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '16613ff9c3735102', + { + content: ['เทสไทย', 'Vulnerability Assessment'], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - [enigmail] basic html`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['The following text is bold: this is bold'], - encryption: 'encrypted', - signature: 'could not verify signature: missing pubkey, missing sender info', - params: - '?frame_id=frame_aLOUYUkbNJ&message=&message_id=1663a65bbd73ce1a&senderEmail=&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '1663a65bbd73ce1a', + { + content: ['The following text is bold: this is bold'], + encryption: 'encrypted', + signature: 'could not verify signature: missing pubkey D97859FF68EA0F04', + }, + authHdr + ); }) ); test( `decrypt - [thunderbird] unicode chinese`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['這封信是用 Thunderbird 做加密與簽章所寄出。', '第四屆董事會成員、認證委員會委員'], - encryption: 'encrypted', - signature: 'could not verify signature: missing pubkey, missing sender info', - quoted: true, - params: - '?frame_id=frame_TgvZakuQNa&message=&message_id=164563dc9e3a8549&senderEmail=&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '164563dc9e3a8549', + { + content: ['這封信是用 Thunderbird 做加密與簽章所寄出。', '第四屆董事會成員、認證委員會委員'], + encryption: 'encrypted', + signature: 'could not verify signature: missing pubkey 0B38948F4CD565B5', + quoted: true, + }, + authHdr + ); }) ); test( `decrypt - [security] mdc - missing - error`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - error: 'decrypt error', - content: ['Security threat!', 'MDC', 'Display the message at your own risk.'], - unexpectedContent: ['As stated in subject', 'Shall not decrypt automatically', 'Has to show a warning'], - params: `?frame_id=frame_obvAUTGAJU&message=${testConstants.encryptedMessageMissingMdcUriEncoded}&message_id=166b194b21a0997c&senderEmail=&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com`, - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '163df1bf12034b9d', + { + error: 'decrypt error', + content: ['Security threat!', 'MDC', 'Display the message at your own risk.'], + unexpectedContent: ['As stated in subject', 'Shall not decrypt automatically', 'Has to show a warning'], + }, + authHdr + ); }) ); test( `decrypt - [security] mdc - modification detected - error`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - error: 'decrypt error', - content: ['Security threat - opening this message is dangerous because it was modified in transit.'], - params: - '?frame_id=frame_obvAUTGAJU&message=-----BEGIN%20PGP%20MESSAGE-----%0AVersion%3A%20FlowCrypt%205.5.9%20Gmail%20Encryption%20flowcrypt.com%0AComment%3A%20Seamlessly%20send%2C%20receive%20and%20search%20encrypted%20email%0A%0AwcFMA0taL%2FzmLZUBAQ%2F%2BKvSED2vb9fJMQd6lRTh0idC7srhg4ESSf4ggCXFE%0AdeOq2IkV5dNhgWGGawFVVUTewMh3L3JklDoONlatBthc2OGNu%2BFyu5No7hhG%0A3Jq1GkNwCqex0%2BG%2BGVhlZfN2LOAx855H9m%2FAGxYo6KLU%2BROmPZV8PZo5YJPr%0Ar8TrhhfHF%2FPG4ZmQIcuvPI1e0ivgF74wP4cG0qaPEacvSxQ1ZuDwzdqC1kGv%0AseOTJEhpBG%2FD8YfbzUXVrX4GiOzIu2OhnlKfU6c0BJCTz%2BqmQRqYOZXLvKgd%0AnU0RzfLgMsd7Sy1lCpld1syY3bT4l0FIRWUtVx1NrJ7cluicEPDiqJsEZntS%0AYy1ViiRZlnk2Xvx1Qpsh7fifUS8e9gfwPevYFhZ%2Fb6SeqpRFRDFGa0uP9L5C%0A%2FCcWqiUaLUL8nF51CYzfIMeIEGBk0TiVUAn19mkQTFbtbIB9K3uQHjFzgnrL%0AnLaJ08Eme5NugtJMUIW7bgo4CAddRjj0isFsoesUv75%2FmEsHJ7JRPICnWx4b%0ALPKOyP0anN6TYDgTC6IqvMOoNi0ZPEIpmGmf7ZOWjR4eUT%2B9uBmBHEPwGbLQ%0A85Mcjy1C7X%2B0uUkIPsqXgF7Ya%2FpwTuZ8mDtF%2FFU3kR87y3jlDZ%2B3ltq%2BY%2B5A%0ABJyMGXGf24%2BSquE1Q%2BONIzBwBqwXuYvRJwqA9vOtZ1PBwUwDS1ov%2FOYtlQEB%0AD%2F0R6LMWFQHZQCIFkvXcB5r4X3J68tcLffAIVs%2BJnoyR6JECUuCZJdKLc4Aa%0AF%2BA15GKiOnf5Z8RIg3Fn3nXuyN5rlWOu0yOO%2FXrnCSMHiYErTLUO6%2B6V6%2Bby%0Ai%2BPOAtAWptnJ7rGSAy17ZgIYD9WNPdX8Bv1fWEOJII2rj%2B5CVyBsOZWrnlnP%0AHjHOQ6gHop7bnQlrpmpA95PLhyoW1LkEIoC0jgrGF%2B0QXRqEfdwpQBCklZyL%0A%2FWAsG2GJLrHUgQALgpTys6%2F5P7VP%2BVSOaEnOJJExIZPkRVRFzWlYq1avgJWw%0AEFGmKeg335%2FiThKBFQ8JsH9U22G5DD1BcfX%2Bqtm4n640zC5pHRpLJO6ggiCJ%0AZA1SCtq6TBSF1FTa158ZNgjkiGZfS%2BoZvrMW%2BS1691vMmJrwqiRlPg9PXCA%2B%0AouGrU%2F1FVyRKGx1%2FUki%2Fh9SaxDX%2F3uHOOwJzytNxGMJP%2F4Y1Y6hbDwDzcrCM%0AFlFHXiNbfB3uxiHD9wWHE44z91MkqOb7%2FajoLXA8J8U3KJGFa%2B8JkZleRVnq%0Ar%2FUT8ppv0%2FozWzV59mTulYzRdIPSy6r4V0bH16XGwZtHVrljOi4TrkExB9cS%0ATdcX96RMMYpJ7p7dGcxoHaRBY120BD%2BsJ51jGi%2FYupoZBdbg7KcOAEelD2%2FF%0ALM1LzR9f3HUaYyKvdPL%2BC0OwINKCAZBPShfECZOiqrNWgHLWddAdXqexZFLH%0A0y7td11E7UNcCZegIlwOYksW7yuuCZ2ZLLnfx%2Fu1G18nKBCealqNkaow%2FPj7%0A4q%2B0UYxfZnAl%2FrFuTK9ndd8tWMSm%2F6xzWEbqe%2F8NKJrCwk%2Fnu%2BpvF%2BMuRvf5%0A9DuzZFiNRQSjSxSYvkyLuw%3D%3D%0A%3DvxOj%0A-----END%20PGP%20MESSAGE-----&message_id=166b194b21a0997c&senderEmail=&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '163dee87a4bfed45', + { + error: 'decrypt error', + content: ['Security threat - opening this message is dangerous because it was modified in transit.'], + }, + authHdr + ); }) ); test( `decrypt - [security] signed message - maliciously modified - should not pass`, testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const { authHdr, acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const msgId = '15f7f7c5979b5a26'; - const signerEmail = 'sender@domain.com'; - const params = `?frameId=none&account_email=${acctEmail}&senderEmail=${signerEmail}&msgId=${msgId}`; await PageRecipe.addPubkey( t, browser, @@ -708,49 +951,61 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== 'sender@domain.com' ); // as the verification pubkey is not known, this scenario doesn't trigger message re-fetch - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params, - content: [], - encryption: 'not encrypted', - signature: 'error verifying signature: Signed digest did not match', - }); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + msgId, + { + content: [], + encryption: 'not encrypted', + signature: 'error verifying signature: Signed digest did not match', + }, + authHdr + ); }) ); test( `decrypt - [everdesk] message encrypted for sub but claims encryptedFor:primary,sub`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['this is a sample for FlowCrypt compatibility'], - encryption: 'encrypted', - signature: 'not signed', - params: - '?frame_id=frame_obvAUTGAJU&message=-----BEGIN%20PGP%20MESSAGE-----%0A%0AwcFMA62sJ5yVCTIHAQ%2F8CkcWeLmCy8lvANll0KbA9ymThNOmZjblBNRZvgT8DqaL%0AhaGXzHaMGHvi0d66P38RXfDc%2BH9l%2FjGtdS1zgiMJMpCUFtDc3OPgOuA93sReqBsq%0A7fv5a%2BLSdfFZUPgUkXM2ur0eA%2BniNE%2BG3mbDcr%2FcuILYI8xTs6xbHRIKVl2G09eS%0ABZMEyqH3duIAi0M42r4L%2FuvABTcEyVKvY%2FQHFmFTj1tSzqSD5PDv%2BnN0ihNR16R9%0AN56PMcZazvTdChhXuA3MNciKoJtbZ785c%2FdwRL8bz8rr7Wj6iF%2B3Qm6kgbkef%2Fo4%0A6D8u8G1eDfSWuwtXVqIOuokd%2FmYgNIVZwt1sJukuGv3eL76b7Mhk3lCEjE8uSOf9%0AN9mbLErel5VUTzNTVpA336aBnMKjEsJUIOg0sU0q8XAKeSjcrIuBrsaKpjq7WDXp%0AFA2eQkpHpwZnlWjVMOYRREdji3G%2Ft32ATTchNXl9zhQsioqQbfUtWkj2WvltE5oz%0AO85ddVUniqpQPdQaojZ5%2BdPZ8SBC%2F4eUp3z4J4%2Fb0fWSTPl%2FtLblFy1HJs0lKG5Z%0A8AaoCGF5TLPoygXjBk0ImikeIGlYIShVOqG36RJlMh4xOQCmY0g9nz9LdCEHJ%2BuC%0AkWh%2FoREBhSMnqlmn1ic%2FDG16h17E%2FtiOuOxsqTfIGlkLSShXDoiTjxgm527FA5HB%0AwUwDS1ov%2FOYtlQEBD%2F9f6jwJxYjdBo2pUy5c%2BgA47BtW%2Fzz12MKhRAHd%2B%2FbVbTv6%0A5JhlBw1Jow0ckjcbnDRqBP9EL%2BErAlc2UzGa%2B42Ahrc2HlDvyMJCcxLt0Fa2nhXG%0AYWGHsQbHxgbePWHozwun2RXaAvvBonhBaYtcn0QPNEtArB9uyO4YqXXoH1%2Fl0%2Fgh%0AIAzuR%2BLNymwdOBXpyiVFMJb6xyQF40aT31kI8Ge%2BUkBbkWDphcEPogd59krBEpwz%0AfBfPdlGoTrSwfbKbshM0kiEbPh%2BESMVvypg%2BPZo1Qp0eXYt7gjlYYqNzQHWobTTr%0AIQjY3T8vml7XlcPzxLFqvQliuIZyRLczvm%2BwDhTj%2BJ%2FdXAK0SHE%2F9XdqKY014j5t%0AWjUfy9iD6seZ85ntAWdxHmOkytANe3QfyVxbO3N31nFe4uqJmW0RaEDx0em3k9YM%0AYLe5OwK%2F49IpUj5gV1R3wnN0uNOZNOdhkyVJynLDJXV5DLoWO3yGMPM3iM%2BZGujk%0A4QrpXjVFscfTHy%2F5%2BbNFGHnapljzli9cbKqt3j610wLQa1pHj6K3xJOANwr0Vdjy%0ABFGwpREQDPceSNREFA%2B7FdPh7WQe7P5NbfYuBXGZZeIvRZ6R0EHi8Agxn1426qYJ%0AEJNr%2BqO2r49EhfCdwbizRLhBsqMJQIirkf5sI4w5RIgpI9ggkv%2FgQiqxvqFcDdK7%0AAVK%2BeZiB2bvY3SVaH49hWaCE1OZ28gDYPlce6ARxznq1eqQhvgUyOffjpDjPgSkF%0AQhQCj6%2Fle9lunPkNKEYUhFr2eBBabBejRAsdLTOslG3yltICpBjHGqOB2CaDlHgL%0Aa5eoeqHusBAx9fmYtd0Zi474cGay8RjGtq%2FE%2B8wDTsupnYGbsHF5pDXC7erW9gyZ%0AMzIE8wAZ%2BIxbhG7JXVtHaPWAbvl1ac7YBV7rpBYRKuvZvDQ9BL%2FtYy59HA%3D%3D%0A%3Dt1CY%0A-----END%20PGP%20MESSAGE-----&message_id=166b194b21a0997c&senderEmail=&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '16d558cb71e8d510', + { + content: ['this is a sample for FlowCrypt compatibility'], + encryption: 'encrypted', + signature: 'not signed', + }, + authHdr + ); }) ); test( `decrypt - [pep] pgp/mime message with text encoded as inline attachment`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['Subject: Re: Test from Tom iOS', 'test again', 'A message', 'Testing'], - encryption: 'encrypted', - signature: 'could not verify signature: missing pubkey, missing sender info', - quoted: true, - params: - '?frame_id=frame_obvAUTGAJU&message=-----BEGIN%20PGP%20MESSAGE-----%0A%0AhQEMA1HNSU%2BzzjQFAQf9GFHItnUD5A%2F2Abbh1qwdUdsl8i%2FhsgPwhONes2FIKxTg%0AsK9QbZSEBWh4GP3pPAaM84NvWEI%2FZFPR6Oy%2FYEOakzO681o2mk7mnf6doGnAy5P4%0AUqOoRCYuMxziyooMsWmwNqQLdazv3b5CkpT1uQjGjw9no%2B4038g2UZdyVw4w9m%2Fn%0AK65OHg544PcR3vuLZTiV%2BujQiwDsUddXYcbEOu2jZj3%2BwT6QZ3UoAni4VHQgSjBj%0AaVBgVHpGnBvTiMf%2FV3rEB0btPbBH2I4pE0ZEklXBCL2sMLz%2BGPQogo3FCTcT%2BBqL%0ALJ5AFFm%2FhXBNYg4ZXRl%2BgOhSi9NswPbQyWQ2OeJdDoUCDANLWi%2F85i2VAQEP%2FA5%2F%0AQqa26qcp1yeM%2FGBNMX7NeaZo0RrCqvBUho7Y7nwuwdMxpyN9mnDzcHPdgxe41OZ5%0AmKDD%2Bgjl7RHClEZBFpSxhc7pi4wIiodlIZ%2BGo3g9%2F7Z7XC7erewnc6BHSTrE5AJa%0AW%2FryxsRDrr9FzR1P3aHqssGXfD4J7%2B3BFASznQKPPaS8e%2BBj2ib6ZdKCyQLRFHZa%0A18RZPF6PprQ4oty%2BpqB8Jv8YTFCWQaYQYfVJLgO6pqwZzReOwcSwkipIraMoBSVn%0AsqAeup4ByOVYWmAhxvN5JP621cHPJbRcRgXqC5%2BRvSW8H0lxNVla7X755PhH0ret%0AKj4HR1o1PAJuPtdh0JMg0LSLiuOaHjfg1w5RtGE7ZyD1CbnF3EfLRmRTY3cLRdVV%0AJBvKj41lSd0EStnGxC2YaRTc50dzwE8ZF%2FvTzQbHc469AYvCOjECQW4kYNgusUia%0Aip7l0y2LYtm7S%2FWkNKCDoFF7gVGNOgtIM4nRlmPqp4D2tAGr3523RdzlRa8kQopo%0AqAHmLrS7%2B8HGESgzl452Pi2crm3J8wOTm3SyZOF2Eg7cyvbC75tNDWzK5ixs881X%0ASKNA2ti56JYd3Mg6Qi%2BsqdgJLLtXbsG0JB1%2B7GcBEVldmFBd1VAlM8cwJt6VNb%2Fr%0ADX4Sd5XpF9WyQbQuM9Np0Qi04UCrsnplG6ZaeJxQ0usBr8i9WKgr6EZg9CtNMD2i%0ARtx6wsjqbJ98oMFsDwGT4xauImVej8fiZiyiL4aJWb9RwLTwhNOjd%2Bgv9Ccw1zaF%0AAb%2F3ECc%2F4k%2FQgvPzWl0epomyZMNfYnw6KS%2FLfYARxJC3ckSFxrevPCfX19528WUC%0AdZ88bXAj1J2ktdDegMNlaltdevgz6uP%2B1dA%2FIYrr169AuOz0qsGhuXYSroa1kEhs%0AvvYB%2FpR55gme%2F5TouKH8baw1rK8tCHtn8N%2FUd0pjrc2P169LRt6SYoVqvvueYKdh%0A9rs%2B8KMdqlvzt99Qj9OcbjRIDe4TaoKcOaSFl2UhuMDWVHkgHDoEf4J5Pxb%2B12HW%0AKaxkKAIEZ7rOC5zS7FO3RfxRtQkXQ9TSZGQl1lRY78IJuDA9JByUKpmd7LuCMLJL%0AjE4b6mFx2lKCBFwoDVyPorr%2FkMvaA8idYV%2Fbj4gmiqaVMELjL58lOme%2FLRFFkV4F%0APXifXSeZG3od9bzCwN%2Fbj%2FVv1IlVL5tmh0%2F0FXinUM1LvIq4wk56KuDxCEM7LcTz%0ADyBzRt%2BW3qGiEeq4g6OKb%2BZL6izxBQTV9QW%2BBFe1oHByw9HIb4HStoi2g4ptUDwv%0AV0bvJqBGYfsTkar%2FUw%2Fm5x6CcW0hqd0pfzqTMIah87tNpCg87XTl0F%2BCt0Zbony9%0AzK9Emew4OB8QbVua4EhQlk1lFTw3kQzsmRKpuFrPac4vDI8jltzIfz6%2BCzNNE85m%0ADMiZUkYSgvuv6CRV2g1raAkVGx%2FNdkDdrc7wvM095A3nbfqnTbLYZ9162WRroCuK%0AW428mzpZ2ABLrRKYwGpE7iS%2FInXjyhrSoWRWXaHbUqpz9JS%2BuLhKOtWuony8T1tm%0AGezGvqZGnubcuGkRFgjELDxsgZG9GJ29r56UZ3ImsMXq148B9t63yW8VafVR%2BJvz%0Aywusa5FgAO69nLE38eAW8YpOgRy4swkowC5So2OWfAoZlTVxZpjpUSDTwXa4Uags%0ArnafwYtnU%2BR4fFt9FIoc6Ty3HvmwVGDV%2BfcMPrvzAfLuPgjNXPS7lB5BuZ2foPQP%0A158WD%2B%2BQoo2vDeTE8HOVpZBak595qJ%2FA27kMJrHPqKLcE9tVWplJ16%2FDVX4ceCs%2F%0AJ0viBtaPA19IHnBmkKyKvX3U5iXnLlwNlxwEdACONWbD3Y%2FwcpABwzeQaDJmFnoR%0ADQ77LtvRJodo34BWLYpx804fVqhQ0XyMaux3V9EeIhnTjFguWQze%2BA3gCYbKpVu5%0AQBxJsZagBOWtyVi8u%2FIu%2FxfaZzr%2B%2BzNPU9CCOuEQHK3H6OYjBSWLYOdYG6l2irUP%0A4ARDU0UKuWrRBQIup3y1EUJzdd6zYXBc5Y%2FUrk0VsikCzYOhXxC9H9W3Fn0pYCft%0AW5RlK3p8xKlRacHTlp4wtACvIuIhwhGDvXFe1iU53GfaKm8ZFaHcA7cbDpNTEvk5%0ArMO%2F0vlVxKmyOmgtnkFcgxdyi6vwp6hVMa59toPYqvZYitYRPcyOGx%2F%2FAITDCPHl%0AylTQGm9JCeG3kts8HC05N2QXKeUxhjHorOwhRc6anjmOdBba9z%2B6aK4Pv%2FJp5693%0A24vVNBIe4HlGmf4fAbPLh%2BG6GmN7QAD3z76RYubPmlFFkqqhIkDCc1awSySnsb06%0A9ZrS1kzcnzK8If2ejyL1n%2FuIx2koQp3LQTzZyCtoq8ho7ybdBhxVK5UfSxbAnJoj%0Agb7uTK1C6qh7iqeYvptt9tmcaQKPBOLIk1cpS9kScfTHTtdE9vqna733rx0kjEK1%0AjldIKwxxi5cc%2Fhd3DfsWQ4gHoprZdXdiUMLJqQTpDmVubx2vIiRAarkMNpd8hsy2%0AYFXUfa%2FGiNl2ax3UIX9zMDkaPESBLcjIcUbu%2F0C2YpDBBLKiwxm6QF1vbn5xOGdN%0AFtoraIzWsN93vJskaNAzi54dd2GL%2FAIVNg%2FhopG07B6Iwn5ZVYIBocAC40FmuQz2%0AyLpplIGqeQ6WSegRfRn8dpbii8IBpgYFrxiAD7uiCrZ9yP17hz%2FMhnXBgBBS9wIl%0AurfPaTitmEP7TaYQTpu9GKPtNjmREC0PN%2BoV7jvIofF1Z3s%2BJSnWaZvmLprcvCqD%0ALYplr%2BvCPeMyuSgLyAnGkmHCliKTGoqF%2BHQYXlPMuQcyoA41rIcQlVCv%2BlguzSDF%0AQNhBm8MKI2vaPTm0Y7hXgsDZ1stYftKC%2Bti0ge4vcelhJLisEYEeEMDNgoS%2Fw%2BLt%0AilRS8eJispykDW7GWdMog2La8wZRe0RH%2Fkcuj04IZTjYcLMxvmgk6zCFOlxxyF7I%0AcUJT%2FqKq0LsHyMABziErSsHJHij1bOw6sCaREXvTf6tDK86vNzuyBHTWVGqp1rZ9%0AyuhRuJ36EdbzuVEd0N6Z3RX4PQuG%2B4ueBfhbkfgLJrGJdTfNNhpVXuajv2ixJdU9%0AfVt4NQr2zIcdV9XNAdLRLuhLU5s5kl8E%2B2lB4%2FVWeb4ZA1oq3hCUIpJnZgRJgqSG%0A8%2FXD9%2FlZdzveihMaIJURQBWk2NbGnALQVrk2AjzspBonM2TbH9VugqzWNS66HUYf%0AE1tN0xe%2BahUhPDlD3GmpE5%2FgBnSUt%2BkQNZm1TOP7gocsOteLHfG31uAbXXACsM52%0A5BX%2BPrsnaTohmXnkFhkqJYtEjlsHI0rcUNQf0%2BueuctMyskb81MxCpP4aodpEuNC%0AtgEqwhgnwbiL68JRaao3Z6y7lbfREvJ0P7gevn0iwgtgdrP2nJdS8eUNQumRCYMs%0Am7qKQ28p8fuZ6f94oINHAoOJOe1wMD4j9vRftPtJU6sKT39ynHs2cylbYkFAqTOz%0Ai%2BRhdRbeuKybMoEx%2FSxfoEHh7RABWzN4DI9w2WhdH7L0hByuBT2GRocZDTYjYerh%0AaRrP6ZC4meeooFzGnurqgKIdEd5e76iYjqnVML1E%2Bw%2BCJSRDqhgG55z465ewZBdp%0AFEB%2FyQ%3D%3D%0A%3DVMeb%0A-----END%20PGP%20MESSAGE-----&message_id=166b194b21a0997c&senderEmail=&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com', - }); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '16ff09b1baca2051', + { + content: ['Subject: Re: Test from Tom iOS', 'test again', 'A message', 'Testing'], + encryption: 'encrypted', + signature: 'could not verify signature: missing pubkey A4556258EFD7EE07', + quoted: true, + }, + authHdr + ); }) ); test( 'decrypt - by entering pass phrase + remember in session', testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const pp = Config.key('flowcrypt.compatibility.1pp1').passphrase; const threadId = '15f7f5630573be2d'; const expectedContent = 'The International DUBLIN Literary Award is an international literary award'; @@ -778,8 +1033,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== 'decrypt - display email with cid image correctly', testWithBrowser(async (t, browser) => { const threadId = '186eed032659ad4f'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); @@ -788,41 +1042,71 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== const replyFrame = await inboxPage.getFrame(['compose.htm']); await replyFrame.waitAndClick('@action-forward'); await replyFrame.waitForContent('@input-body', 'googlelogo_color_272x92dp.png'); // check if forwarded content contains cid image name + await inboxPage.close(); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${threadId}`, undefined, authHdr); + await gmailPage.waitAll('iframe'); + const pgpBlockFromGmailPage = await gmailPage.getFrame(['pgp_block.htm']); + await pgpBlockFromGmailPage.waitForSelTestState('ready'); + await pgpBlockFromGmailPage.checkIfImageIsDisplayedCorrectly('#pgp_block img'); }) ); test( "decrypt - thunderbird - signedHtml verifyDetached doesn't duplicate PGP key section", testWithBrowser(async (t, browser) => { - const threadId = '17daefa0eb077da6'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); + const msgId = '17daefa0eb077da6'; + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${msgId}`); await inboxPage.waitAll('iframe'); - const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); - await pgpBlock.waitForSelTestState('ready'); - const urls = await inboxPage.getFramesUrls(['pgp_pubkey.htm'], { sleep: 3 }); - expect(urls.length).to.be.lessThan(2); + await (await inboxPage.getFrame(['pgp_block.htm'])).waitForSelTestState('ready'); + expect(await inboxPage.getFramesUrls(['pgp_pubkey.htm'], { sleep: 3 })).length.to.be.lessThan(2); + await inboxPage.close(); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + await (await gmailPage.getFrame(['pgp_block.htm'])).waitForSelTestState('ready'); + expect(await gmailPage.getFramesUrls(['pgp_pubkey.htm'], { sleep: 3 })).length.to.be.lessThan(2); }) ); test( 'decrypt - print feature in pgp block', testWithBrowser(async (t, browser) => { - const threadId = '182917712be838e1'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); - await inboxPage.waitAll('iframe'); - const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); - await pgpBlock.waitForSelTestState('ready'); - const printPage = await browser.newPageTriggeredBy(t, () => pgpBlock.click('@action-print')); - await printPage.waitForContent('@print-user-email', 'First Last '); - await printPage.waitForContent('@print-subject', 'Test print dialog'); - await printPage.waitForContent('@print-from', 'From: sender@domain.com'); - await printPage.waitForContent('@print-to', 'To: flowcrypt.compatibility@gmail.com'); - await printPage.waitForContent('@print-cc', 'ci.tests.gmail@flowcrypt.dev'); - await printPage.waitForContent('@print-content', 'Test print message'); + const msgId = '182917712be838e1'; + const testPrintBlockInPage = async (page: ControllablePage) => { + await page.waitAll('iframe'); + const pgpBlock = await page.getFrame(['pgp_block.htm']); + await pgpBlock.waitForSelTestState('ready'); + const printPage = await browser.newPageTriggeredBy(t, () => pgpBlock.click('@action-print')); + await printPage.waitForContent('@print-user-email', 'First Last '); + await printPage.waitForContent('@print-subject', 'Test print dialog'); + await printPage.waitForContent('@print-from', 'From: sender@domain.com'); + await printPage.waitForContent('@print-to', 'To: flowcrypt.compatibility@gmail.com'); + await printPage.waitForContent('@print-cc', 'ci.tests.gmail@flowcrypt.dev'); + await printPage.waitForContent('@print-content', 'Test print message'); + await printPage.close(); + await page.close(); + }; + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await testPrintBlockInPage(await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${msgId}`)); + await testPrintBlockInPage(await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr)); + }) + ); + + test( + 'decrypt - verifyDetached displays error on corrupted signature attachment', + testWithBrowser(async (t, browser) => { + const msgId = '18024d53a24b19fe'; + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + msgId, + { + content: ['テストです\nテスト'], + signature: 'error verifying signature: Ascii armor integrity check failed', + encryption: 'not encrypted', + }, + authHdr + ); }) ); @@ -830,14 +1114,27 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== "decrypt - thunderbird - signedMsg verifyDetached doesn't duplicate PGP key section", testWithBrowser(async (t, browser) => { const threadId = '17dad75e63e47f97'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const { authHdr, acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); await pgpBlock.waitForSelTestState('ready'); + const expectedMessage = { + signature: 'could not verify signature: missing pubkey 203FAE7076005381', + encryption: 'not encrypted', + content: ['1234'], + }; + await BrowserRecipe.pgpBlockCheck(t, pgpBlock, expectedMessage); const urls = await inboxPage.getFramesUrls(['pgp_pubkey.htm'], { sleep: 3 }); expect(urls.length).to.be.equal(1); + await inboxPage.close(); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${threadId}`, undefined, authHdr); + await gmailPage.waitAll('iframe'); + const pgpBlockFromGmailPage = await gmailPage.getFrame(['pgp_block.htm']); + await pgpBlockFromGmailPage.waitForSelTestState('ready'); + await BrowserRecipe.pgpBlockCheck(t, pgpBlockFromGmailPage, expectedMessage); + const frameUrlsFromGmailPage = await gmailPage.getFramesUrls(['pgp_pubkey.htm'], { sleep: 3 }); + expect(frameUrlsFromGmailPage.length).to.be.equal(1); }) ); @@ -845,8 +1142,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== 'decrypt - thunderbird - signing key is rendered in signed and encrypted message', testWithBrowser(async (t, browser) => { const threadId = '175adb163ac0d69b'; - const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); @@ -859,58 +1155,108 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== test( 'decrypt - thunderbird - signed text is recognized', testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - t.mockApi!.configProvider = new ConfigurationProvider({ - attester: { - pubkeyLookup: { - [acctEmail]: { - pubkey: somePubkey, - }, - 'some.sender@test.com': { - pubkey: await get203FAE7076005381(), - }, - }, - }, - }); - await BrowserRecipe.setUpCommonAcct(t, browser, 'compatibility'); - const threadId = '17dad75e63e47f97'; - const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup!['some.sender@test.com'] = { pubkey: await get203FAE7076005381() }; + const msgId = '17dad75e63e47f97'; + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${msgId}`); await inboxPage.waitAll('iframe', { timeout: 2 }); const urls = await inboxPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 10, appearIn: 20 }); expect(urls.length).to.equal(1); - const url = urls[0].split('/chrome/elements/pgp_block.htm')[1]; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params: url, + const expectedMessage = { + content: ['1234'], + encryption: 'not encrypted', + signature: 'signed', + }; + await BrowserRecipe.pgpBlockCheck(t, await inboxPage.getFrame(['pgp_block.htm']), expectedMessage); + await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, msgId, expectedMessage, authHdr); + }) + ); + + test( + 'decrypt - timeout when looking up pubkey - inbox', + testWithBrowser(async (t, browser) => { + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup!['some.sender@test.com'] = { + returnError: new HttpClientErr('RequestTimeout', Status.BAD_REQUEST), + }; + const msgId = '17dad75e63e47f97'; + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${msgId}`); + const pgpFrame = await inboxPage.getFrame(['pgp_block.htm']); + await pgpFrame.waitForContent('@pgp-signature', 'error verifying signature: offline, click to retry'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup!['some.sender@test.com'] = { pubkey: await get203FAE7076005381() }; + await pgpFrame.waitAndClick('@pgp-signature'); + await BrowserRecipe.pgpBlockCheck(t, await inboxPage.getFrame(['pgp_block.htm']), { content: ['1234'], encryption: 'not encrypted', signature: 'signed', }); + await inboxPage.close(); }) ); test( - 'verification - message text is rendered prior to pubkey fetching', + 'decrypt - timeout when looking up pubkey - gmail', testWithBrowser(async (t, browser) => { + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup!['some.sender@test.com'] = { + returnError: new HttpClientErr('RequestTimeout', Status.BAD_REQUEST), + }; const msgId = '17dad75e63e47f97'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - const senderEmail = 'this.pubkey.takes.long.time.to.load@sender.test'; - t.mockApi!.configProvider = new ConfigurationProvider({ - attester: { - pubkeyLookup: { - [acctEmail]: { - pubkey: somePubkey, - }, - [senderEmail]: { - pubkey: await get203FAE7076005381(), - delayInSeconds: 5, - }, - }, + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + const pgpFrame = await gmailPage.getFrame(['pgp_block.htm']); + await pgpFrame.waitForContent('@pgp-signature', 'error verifying signature: offline, click to retry'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup!['some.sender@test.com'] = { pubkey: await get203FAE7076005381() }; + await pgpFrame.waitAndClick('@pgp-signature'); + await BrowserRecipe.pgpBlockCheck(t, await gmailPage.getFrame(['pgp_block.htm']), { + content: ['1234'], + encryption: 'not encrypted', + signature: 'signed', + }); + await gmailPage.close(); + }) + ); + + test( + 'decrypt - failure retrieving chunk download - next request will try anew', + testWithBrowser(async (t, browser) => { + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + t.mockApi!.configProvider!.config.google = { + getAttachment: { + 'ANGjdJ_0g7PGqJSjI8-Wjd5o8HcVnAHxIk-H210TAxxwfhKWlCUqnXbZtBdwjPQqN9omCqn-0-r4JBy6amb0ogGz9jZL9q11Z_iUJzxr_X0MlJj0cw-3EYCFKPDrpfVVQZ-28Ajhd35CkI3Z93s3FU4BUKHROZR1qdEPOoQM63k1IOPTfL9c7ES-W8EaOKxB-k0n0frlXqpTJgv-AHAi9NEAaq-ghluobPc4JiSjgkK7_0MkykEm4oZfBSHSuzG94c3HWeYNJw4bcWFHiKRln7bB8nq5JTJe546Zg2MoVkMuc7K6a0cUwGd9mdAUAPqPyq1ENIQ9bGFK7ozlDezHHZYP8rOTEL3QBx6rEE-aaGT2MEQyWPtsp8Zgt42prnUjysPDe-uVs-pl31UpIDhf': + { error: new HttpClientErr('RequestTimeout', Status.BAD_REQUEST) }, }, + }; + const msgId = '1885ded59a2b5a8d'; + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + expect((await gmailPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(0); + await gmailPage.waitForContent('.attachment_loader', 'Categorize: unknown err'); // 'RequestTimeout' responseText gets lost in chunk downloader + t.mockApi!.configProvider!.config.google = {}; + await gmailPage.target.$$eval('.evaluated', elems => { + for (const el of elems) { + el.classList.remove('evaluated'); + } + }); // trigger processing + await BrowserRecipe.pgpBlockCheck(t, await gmailPage.getFrame(['pgp_block.htm']), { + content: ['Standard message'], + encryption: 'not encrypted', + signature: 'could not verify signature: missing pubkey 06CA553EC2455D70', }); - await BrowserRecipe.setUpCommonAcct(t, browser, 'compatibility'); - const params = `?frameId=none&acctEmail=${acctEmail}&msgId=${msgId}&signature=___cu_true___&senderEmail=${senderEmail}`; - const pgpHostPage = await browser.newPage(t, `chrome/dev/ci_pgp_host_page.htm${params}`); - const pgpBlockPage = await pgpHostPage.getFrame(['pgp_block.htm']); + await gmailPage.close(); + }) + ); + + test( + 'verification - message text is rendered prior to pubkey fetching', + testWithBrowser(async (t, browser) => { + const msgId = '17dad75e63e47f97'; + const senderEmail = 'some.sender@test.com'; + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup![senderEmail] = { + pubkey: await get203FAE7076005381(), + delayInSeconds: 5, + }; + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + const pgpBlockPage = await gmailPage.getFrame(['pgp_block.htm']); await pgpBlockPage.waitForContent('@pgp-block-content', '1234', 4, 10); await pgpBlockPage.waitForContent('@pgp-signature', 'verifying signature...', 3, 10); await pgpBlockPage.waitForContent('@pgp-signature', 'signed', 10, 10); @@ -920,48 +1266,34 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== test( 'verification - public key fetched from WKD', testWithBrowser(async (t, browser) => { - t.mockApi!.configProvider = new ConfigurationProvider({ - wkd: { - directLookup: { - 'only.on.wkd': { - pubkeys: [onlyOnWkdPubKey], - }, - }, - }, - }); - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - const senderEmail = 'only.on.wkd@signing.test'; - const message = encodeURIComponent( - '\r\n-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: SHA512\r\n\r\ntest signed msg\r\n-----BEGIN PGP SIGNATURE-----\r\nVersion: FlowCrypt Email Encryption 8.3.2\r\nComment: Seamlessly send and receive encrypted email\r\n\r\nwnUEARYKAAYFAmMEtG8AIQkQ+1x3UHaDHFEWIQQvI5Sm4OisrFQgXUP7XHdQ\r\ndoMcUf2WAP0RJ7mXIPJUWSKIi3OCfddHlDX/y3rv+Kwabyjm5/dZMQD/TcUa\r\nrqxUmshPoZbQBgFPwpS0V/8nHTNj0b2ugcvnIQ4=\r\n=eCak\r\n-----END PGP SIGNATURE-----\r\n' - ); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - content: ['test signed msg'], + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + t.mockApi!.configProvider!.config.wkd = { + directLookup: { + 'some.sender': { + pubkeys: [await get203FAE7076005381()], + }, + }, + }; + const threadId = '17dad75e63e47f97'; + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); + await inboxPage.waitAll('iframe', { timeout: 2 }); + const urls = await inboxPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 10, appearIn: 20 }); + expect(urls.length).to.equal(1); + await BrowserRecipe.pgpBlockCheck(t, await inboxPage.getFrame([urls[0]]), { + content: ['1234'], encryption: 'not encrypted', signature: 'signed', - params: `?frameId=none&acctEmail=flowcrypt.compatibility@gmail.com&message=${message}&msgId=&signature=___cu_true___&senderEmail=${senderEmail}`, }); + expect(await inboxPage.read('@message-line')).to.not.include('1234'); }) ); - test( 'decrypt - fetched pubkey is automatically saved to contacts', testWithBrowser(async (t, browser) => { const msgId = '17dad75e63e47f97'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; const senderEmail = 'some.sender@test.com'; - t.mockApi!.configProvider = new ConfigurationProvider({ - attester: { - pubkeyLookup: { - [acctEmail]: { - pubkey: somePubkey, - }, - [senderEmail]: { - pubkey: await get203FAE7076005381(), - }, - }, - }, - }); - await BrowserRecipe.setUpCommonAcct(t, browser, 'compatibility'); + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup![senderEmail] = { pubkey: await get203FAE7076005381() }; const acctAttr = acctEmail.replace(/[\.@]/g, ''); const senderAttr = senderEmail.replace(/[\.@]/g, ''); { @@ -973,13 +1305,17 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== expect(await contactsFrame.isElementPresent(`@action-show-email-${acctAttr}`)).to.be.true; expect(await contactsFrame.isElementPresent(`@action-show-email-${senderAttr}`)).to.be.false; } - const params = `?frameId=none&acctEmail=${acctEmail}&msgId=${msgId}&signature=___cu_true___&senderEmail=${senderEmail}`; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params, - content: ['1234'], - encryption: 'not encrypted', - signature: 'signed', - }); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + msgId, + { + content: ['1234'], + encryption: 'not encrypted', + signature: 'signed', + }, + authHdr + ); { const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); await SettingsPageRecipe.toggleScreen(settingsPage, 'additional'); @@ -999,51 +1335,47 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== 'decrypt - unsigned encrypted message', testWithBrowser(async (t, browser) => { const threadId = '17918a9d7ca2fbac'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const expectedMessage = { + content: ['This is unsigned, encrypted message'], + encryption: 'encrypted', + signature: 'not signed', + }; + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe'); const urls = await inboxPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 3 }); expect(urls.length).to.equal(1); - const url = urls[0].split('/chrome/elements/pgp_block.htm')[1]; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params: url, - content: ['This is unsigned, encrypted message'], - encryption: 'encrypted', - signature: 'not signed', - }); + await BrowserRecipe.pgpBlockCheck(t, await inboxPage.getFrame([urls[0]]), expectedMessage); + await inboxPage.close(); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${threadId}`, undefined, authHdr); + await gmailPage.waitAll('iframe', { timeout: 2 }); + const frameUrlsFromGmailPage = await gmailPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 10, appearIn: 20 }); + expect(frameUrlsFromGmailPage.length).to.equal(1); + await BrowserRecipe.pgpBlockCheck(t, await gmailPage.getFrame([frameUrlsFromGmailPage[0]]), expectedMessage); }) ); test( 'signature - sender is different from pubkey uid', testWithBrowser(async (t, browser) => { - const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - t.mockApi!.configProvider = new ConfigurationProvider({ - attester: { - pubkeyLookup: { - [acctEmail]: { - pubkey: somePubkey, - }, - 'sender@example.com': { - pubkey: testConstants.pubkey2864E326A5BE488A, - }, - }, - }, - }); - await BrowserRecipe.setUpCommonAcct(t, browser, 'ci.tests.gmail'); + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup!['sender@example.com'] = { + pubkey: testConstants.pubkey2864E326A5BE488A, + }; const threadId = '1766644f13510f58'; const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe', { timeout: 2 }); const urls = await inboxPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 10, appearIn: 20 }); expect(urls.length).to.equal(1); - const url = urls[0].split('/chrome/elements/pgp_block.htm')[1]; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params: url, + const expectedMessage = { content: ['How is my message signed?'], encryption: 'not encrypted', signature: 'signed', - }); + }; + await BrowserRecipe.pgpBlockCheck(t, await inboxPage.getFrame(['pgp_block.htm']), expectedMessage); + await inboxPage.close(); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${threadId}`, undefined, authHdr); + await BrowserRecipe.pgpBlockCheck(t, await gmailPage.getFrame(['pgp_block.htm']), expectedMessage); }) ); @@ -1051,20 +1383,10 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== 'signature - verification succeeds when signed with a second-best key', testWithBrowser(async (t, browser) => { const threadId = '1766644f13510f58'; - const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - t.mockApi!.configProvider = new ConfigurationProvider({ - attester: { - pubkeyLookup: { - [acctEmail]: { - pubkey: somePubkey, - }, - 'sender@example.com': { - pubkey: testConstants.pubkey2864E326A5BE488A, - }, - }, - }, - }); - await BrowserRecipe.setUpCommonAcct(t, browser, 'ci.tests.gmail'); + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup!['sender@example.com'] = { + pubkey: testConstants.pubkey2864E326A5BE488A, + }; await PageRecipe.addPubkey( t, browser, @@ -1072,25 +1394,31 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== '-----BEGIN PGP PUBLIC KEY BLOCK-----\r\nVersion: FlowCrypt Email Encryption [BUILD_REPLACEABLE_VERSION]\r\nComment: Seamlessly send and receive encrypted email\r\n\r\nxjMEYZeW2RYJKwYBBAHaRw8BAQdAT5QfLVP3y1yukk3MM/oiuXLNe1f9az5M\r\nBnOlKdF0nKnNJVNvbWVib2R5IDxTYW1zNTBzYW1zNTBzZXB0QEdtYWlsLkNv\r\nbT7CjwQQFgoAIAUCYZeW2QYLCQcIAwIEFQgKAgQWAgEAAhkBAhsDAh4BACEJ\r\nEMrSTYqLk6SUFiEEBP90ux3d6kDwDdzvytJNiouTpJS27QEA7pFlkLfD0KFQ\r\nsH/dwb/NPzn5zCi2L9gjPAC3d8gv1fwA/0FjAy/vKct4D7QH8KwtEGQns5+D\r\nP1WxDr4YI2hp5TkAzjgEYZeW2RIKKwYBBAGXVQEFAQEHQKNLY/bXrhJMWA2+\r\nWTjk3I7KhawyZfLomJ4hovqr7UtOAwEIB8J4BBgWCAAJBQJhl5bZAhsMACEJ\r\nEMrSTYqLk6SUFiEEBP90ux3d6kDwDdzvytJNiouTpJQnpgD/c1CzfS3YzJUx\r\nnFMrhjiE0WVgqOV/3CkfI4m4RA30QUIA/ju8r4AD2h6lu3Mx/6I6PzIRZQty\r\nLvTkcu4UKodZa4kK\r\n=7C4A\r\n-----END PGP PUBLIC KEY BLOCK-----\r\n', 'sender@example.com' ); + // todo: make sure pubkey2864E326A5BE488A isn't present in ContactStore yet + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${threadId}`, undefined, authHdr); + await gmailPage.waitAll('iframe', { timeout: 2 }); + const frameUrlsFromGmailPage = await gmailPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 10, appearIn: 20 }); + expect(frameUrlsFromGmailPage.length).to.equal(1); + const expectedMessage = { + content: ['How is my message signed?'], + encryption: 'not encrypted', + signature: 'signed', + }; + await BrowserRecipe.pgpBlockCheck(t, await gmailPage.getFrame([frameUrlsFromGmailPage[0]]), expectedMessage); + await gmailPage.close(); + // todo: remove pubkey2864E326A5BE488A from ContactStore const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); await inboxPage.waitAll('iframe', { timeout: 2 }); const urls = await inboxPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 10, appearIn: 20 }); expect(urls.length).to.equal(1); - const url = urls[0].split('/chrome/elements/pgp_block.htm')[1]; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params: url, - content: ['How is my message signed?'], - encryption: 'not encrypted', - signature: 'signed', - }); + await BrowserRecipe.pgpBlockCheck(t, await inboxPage.getFrame([urls[0]]), expectedMessage); }) ); test( 'decrypt - protonmail - PGP/inline signed and encrypted message with pubkey - pubkey signature is ignored', testWithBrowser(async (t, browser) => { - const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); const dbPage = await browser.newExtensionPage(t, 'chrome/dev/ci_unit_test.htm'); // todo: url? // add the pubkey of the sender await dbPage.page.evaluate(async (pubkey: string) => { @@ -1099,10 +1427,8 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== // eslint-disable-next-line @typescript-eslint/no-explicit-any await (window as any).ContactStore.update(undefined, 'schlemazle@proton.me', { pubkey: key }); }, testConstants.protonPubkey); - const accessToken = await BrowserRecipe.getGoogleAccessToken(dbPage, acctEmail); await dbPage.close(); - const extraAuthHeaders = { Authorization: `Bearer ${accessToken}` }; // eslint-disable-line @typescript-eslint/naming-convention - const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/1869220e0c8f16dd`, undefined, extraAuthHeaders); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/1869220e0c8f16dd`, undefined, authHdr); await gmailPage.waitAll('iframe'); const pgpBlock = await gmailPage.getFrame(['pgp_block.htm']); await BrowserRecipe.pgpBlockCheck(t, pgpBlock, { @@ -1117,13 +1443,12 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== test( 'decrypt - protonmail - PGP/inline signed and encrypted message with pubkey - pubkey signature is ignored - inbox', testWithBrowser(async (t, browser) => { - const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); const threadId = '1869220e0c8f16dd'; let inboxPage = await browser.newExtensionInboxPage(t, acctEmail, threadId); await inboxPage.waitAll('iframe'); expect((await inboxPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(1); - expect((await inboxPage.getFramesUrls(['pgp_pubkey.htm'])).length).to.equal(1); + expect(await (await inboxPage.getFrame(['pgp_pubkey.htm'])).isElementVisible('@action-add-contact')).to.be.true; expect((await inboxPage.getFramesUrls(['attachment.htm'])).length).to.equal(0); // invisible await BrowserRecipe.pgpBlockCheck(t, await inboxPage.getFrame(['pgp_block.htm']), { content: ['Sent with Proton Mail secure email.'], @@ -1143,7 +1468,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== inboxPage = await browser.newExtensionInboxPage(t, acctEmail, threadId); await inboxPage.waitAll('iframe'); expect((await inboxPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(1); - expect((await inboxPage.getFramesUrls(['pgp_pubkey.htm'])).length).to.equal(1); + expect(await (await inboxPage.getFrame(['pgp_pubkey.htm'])).isElementVisible('@action-add-contact')).to.be.true; expect((await inboxPage.getFramesUrls(['attachment.htm'])).length).to.equal(0); // invisible await BrowserRecipe.pgpBlockCheck(t, await inboxPage.getFrame(['pgp_block.htm']), { content: ['Sent with Proton Mail secure email.'], @@ -1154,79 +1479,135 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); + test( + 'decrypt - public key is rendered minimized for outgoing messages', + testWithBrowser(async (t, browser) => { + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + const threadId = '1869220e0c8f16de'; + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail, threadId); + await inboxPage.waitAll('iframe'); + expect((await inboxPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(1); + expect((await inboxPage.getFramesUrls(['attachment.htm'])).length).to.equal(0); // invisible + const pubkeyFrame1 = await inboxPage.getFrame(['pgp_pubkey.htm']); + expect(await pubkeyFrame1.isElementVisible('@action-add-contact')).to.be.false; // should be hidden because the sender matches acctEmail + await inboxPage.close(); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${threadId}`, undefined, authHdr); + await gmailPage.waitAll('iframe'); + expect((await gmailPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(1); + expect((await gmailPage.getFramesUrls(['attachment.htm'])).length).to.equal(0); // invisible + const pubkeyFrame2 = await gmailPage.getFrame(['pgp_pubkey.htm']); + expect(await pubkeyFrame2.isElementVisible('@action-add-contact')).to.be.false; // should be hidden because the sender matches acctEmail + }) + ); + + test( + 'decrypt - not an armored public key in a file that looked like a public key', + testWithBrowser(async (t, browser) => { + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + const msgId = '1869220e0c8f16de'; + // 1. plain text + t.mockApi!.configProvider!.config.google = { + getAttachment: { + '1869220e0c8f16de-part1': { data: 'MTIz'.repeat(500) }, // string containing 123123... + }, + }; + const gmailPage1 = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + await gmailPage1.waitAll('iframe'); + await gmailPage1.waitForContent('.attachment_loader', 'Unknown OpenPGP format'); + expect((await gmailPage1.getFramesUrls(['pgp_block.htm'], { sleep: 0, appearIn: 0 })).length).to.equal(1); + expect((await gmailPage1.getFramesUrls(['attachment.htm'], { sleep: 0, appearIn: 0 })).length).to.equal(0); + expect((await gmailPage1.getFramesUrls(['pgp_pubkey.htm'], { sleep: 0, appearIn: 0 })).length).to.equal(0); + await gmailPage1.close(); + // 2. encryptedFile + t.mockApi!.configProvider!.config.google = { + getAttachment: { + '1869220e0c8f16de-part1': { + data: `LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQpWZXJzaW9uOiBGbG93Q3J5cHQgRW1haWwgRW5jcnlwdGlvbiA3LjkuOA0KQ29tbWVudDogU2VhbWxlc3NseSBzZW5kIGFuZCByZWNlaXZlIGVuY3J5cHRlZCBlbWFpbA0KDQp3VjREZVdmZ0N0VnRkbm9TQVFkQWRkRitWYmhVTjd0V2NGMnNKSW5aRzFKK08xYlBOLzNHd0NGbXlSd2wNCmFGTXcwMGhHVUd4UXBscUJNZnBVaktnWHdJSlpnbFNPbkd0b242VkpuVlpXSmwzN0tQcmZ6aFZ6bnhJbg0KckxCT3ZIUHp3Y0ZNQXpCZmdhbXUwU0ExQVJBQW9EeGhiRUIvQmNnVDB6Y29CYnJRMDhPZXpKZ2VWVDhXDQozY2p5RFI1YjY2U21MUCt5ZzdLTm5oUXNnR1I4blNRaUozNk1Id3JmU3MzTVcrNSt5YXdZOWcveXZWQzgNCkMxS3MzQTREbFlvcWFTY3dTUjhDeG9qcTAwNmErdGI0blp5cTdyY3ZsaDg5UjVObURZMjkxcC8vQ05JSA0KNC9rRWZXSVVIaW9sZEc0VlFnTnhVd0ZSbEVmMXYwL1RMTGg0bXN0ckJhU1BBM3BiV1VOZnZOYmc2WGl2DQpIcU1FVGdxUVVOb0MvU0dCYlNFOHgvNTlZa0tQQVlVcUNpT2E2UW5NWW14UUliUE1xNTFUV0VTS1ZVYmQNCmZ4S3BBeDNUaWQzRFBqWDNjT1Zvb2VsRWxDeXZLSDlkWlBweWEyTGpoankrUkVKWmZkNkpmNXpDUkdKVA0KSCs5cG9CdVpDR3BSMmVXamQ3SG5hbzFObjdKZkFSM3R2SDdVZUVMc1JjcFNJQ1JPZWxUQmJEVWlQK2JNDQpzOVduUWVsQ3FVNGNrNDE3dUpaNjluSXp1Y0NURnlnYmlIZzVXZnNzQzNxcVQzRTVjSE0yNXJEbmQ5MSsNCkVZN1RCbFJ5Z0tqM1RmRlYyRHZUNmdybk0yQWhvUnkyTWNGSGtMaEhCanJ4M3BCSHhGRWkvZVZLcncvaw0Ka044alJ4MFBMWWlZYWtGZjJWTCt4d0JxUkljWmd5SER4K2o5akViR1d2M25kU1ByT01qNFZxaVRMb0tUDQpBVkk4TUwyVHVCZGJGQS9TUWYyODZtTjhBeklRR2ZqL3J1enI0NFFCZS90RnlHdSsyR0NBQ3FxWGl2b3cNClo2d2QwVWRuc056Y3FKY0FWa28zOFN3QldtdjZzc3NwQURNZXNtYnU5WjA1V3k1L1BodlN3QUlCckovZA0KdjFJWnQ3VFpackNmSG4xak1xamRWRUhTRXB0VEJxYzBiSGxUT0c4Q0NST2VPNWFkSE13UW8zekJSRThYDQpqNG1JTkp5R1pyM3g5TCtxUTJuUnZrSlRBVTZNWm02UzdsWWdVdURqbi9DS3YzNUtYa1hqcnNPN1lsTTANClhydG1uMUZCTVZMQTNta3MwK1R4TSsyalBGNitKbmpaK29tVEpIbjRuWGNmWSsxM1VBaGZBNlNkeFFkQg0KVGQ3cjlkOWM0WUxTaEtEdXhwMlh4eDNXVVR2N3oxSm9sdFI1ZURXVFgxc3hMZURQQ0s0RnQ1VVNSYVhCDQpVc3hENnE0R2x3bHAzZz09DQo9MmVUTQ0KLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQ0K`, + }, + }, + }; + const gmailPage2 = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + await gmailPage2.waitAll('iframe'); + expect((await gmailPage2.getFramesUrls(['pgp_block.htm'])).length).to.equal(1); + expect((await gmailPage2.getFramesUrls(['pgp_pubkey.htm'], { sleep: 0, appearIn: 0 })).length).to.equal(0); + const attachmentFrame = await gmailPage2.getFrame(['attachment.htm']); + const downloadedFiles = await attachmentFrame.awaitDownloadTriggeredByClicking('@download-attachment'); + const entries = Object.entries(downloadedFiles); + expect(entries.length).to.equal(1); + const decryptedContent = entries[0][1].toString(); + expect(decryptedContent).to.equal('1234'); + await gmailPage2.close(); + // 3. broken file + t.mockApi!.configProvider!.config.google = { + getAttachment: { + '1869220e0c8f16de-part1': { + data: 'LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgp4c0ZOQkdQOGIxSUJFQUN2WTk1bkVZRUZDOUpFZVA0NzVCWTRGSERaSzhITE5TTWJ4c2tRZGNSYXV3eXUKNEpyVm5Yb3UvOFFmdEtaejNheVVGbEswbVJ5NWFHZytEMW1jTjJFRHVmd0E3ZnVPb3dHWk1yOVdxeE9sCm1SK21YL0I3eWM4RmZNTHNIWjhrOVQzRncrcy9QbTR0dEdBaHVBSUpkMEx5bzZZTGdaVGFoL0hNK1MyOApQUUhFcGZPQWdtYk52YjdXYUxRd2gwb1RNR01Mb3NYSENoOE5PdlNXOVRTNHpCK2JNaEVuZkY1MytYTTUKUlVac0RRU3M4cDU5aXRjbjdrVTNMNDVDSzhWamc2UzQ5bWlHcFo2eFBESitmS04vWmhMelRrVDVhSFZ2Ck9qVUpMQ0NYcFluRzh1cVUvMXhYTGRBTk0xRk5LSFRrNEV1dUdpSEZBNlhZZWlQVnd4L2ROdytJdmVQUgpjYmd0a0dvTWZkZXQ0eXdmVWZyRnlkRlV1WEhmNTlYSm9hUzB0azNuVS9nUkMwZlJnZVN3ZFFhbVoxaXMKeEFzeXBydDlwUFNIbVZWQ3lGRU95Qk5ELzhsaWxCOFpMNS8xYmxPQmdyWkdqMXpNUm5VSkhEanM2VGtQCmhBcXc5ZEw2ais0cE4ybzNnalVGY2JQQng5TGZiZldicnFhWk1Xd2tEYi95c0E0cFNDZUxCbkdZSXc3OApoRExjaWpDZStSSkxsdTJzbkhmUnFjQ0kyd2FiK01NVUhDMTF4VHA1bHpBNHUwZW9xdWZwK0xPdWREWHoKemF3c2RqeitvalJ4ZjBZaUVkNGpZVmtJOS9xUDRXVmtPM1FtSlBOV3JEdzNYRGpTU3Z3cHo1ZWxyRTBsCjI0cE9IMXBHTE4vNkNEWnAwaDF3TnRMaEVBWDBhSWYva2N5cGp3QVJBUUFCelN0elkyaHNaVzFoZW14bApRSEJ5YjNSdmJpNXRaU0E4YzJOb2JHVnRZ', + }, + }, + }; + const gmailPage3 = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + await gmailPage3.waitAll('iframe'); + expect((await gmailPage3.getFramesUrls(['pgp_block.htm'])).length).to.equal(1); + expect((await gmailPage3.getFramesUrls(['attachment.htm'], { sleep: 0, appearIn: 0 })).length).to.equal(0); + const pubkeyFrame = await gmailPage3.getFrame(['pgp_pubkey.htm']); + await pubkeyFrame.waitForContent('@container-pgp-pubkey', 'This OpenPGP key is not usable.'); + await gmailPage3.close(); + // 4. binary pubkey + t.mockApi!.configProvider!.config.google = { + getAttachment: { + '1869220e0c8f16de-part1': { + data: 'xsFNBGP8b1IBEACvY95nEYEFC9JEeP475BY4FHDZK8HLNSMbxskQdcRauwyu4JrVnXou/8QftKZz3ayUFlK0mRy5aGg+D1mcN2EDufwA7fuOowGZMr9WqxOlmR+mX/B7yc8FfMLsHZ8k9T3Fw+s/Pm4ttGAhuAIJd0Lyo6YLgZTah/HM+S28PQHEpfOAgmbNvb7WaLQwh0oTMGMLosXHCh8NOvSW9TS4zB+bMhEnfF53+XM5RUZsDQSs8p59itcn7kU3L45CK8Vjg6S49miGpZ6xPDJ+fKN/ZhLzTkT5aHVvOjUJLCCXpYnG8uqU/1xXLdANM1FNKHTk4EuuGiHFA6XYeiPVwx/dNw+IvePRcbgtkGoMfdet4ywfUfrFydFUuXHf59XJoaS0tk3nU/gRC0fRgeSwdQamZ1isxAsyprt9pPSHmVVCyFEOyBND/8lilB8ZL5/1blOBgrZGj1zMRnUJHDjs6TkPhAqw9dL6j+4pN2o3gjUFcbPBx9LfbfWbrqaZMWwkDb/ysA4pSCeLBnGYIw78hDLcijCe+RJLlu2snHfRqcCI2wab+MMUHC11xTp5lzA4u0eoqufp+LOudDXzzawsdjz+ojRxf0YiEd4jYVkI9/qP4WVkO3QmJPNWrDw3XDjSSvwpz5elrE0l24pOH1pGLN/6CDZp0h1wNtLhEAX0aIf/kcypjwARAQABzStzY2hsZW1hemxlQHByb3Rvbi5tZSA8c2NobGVtYXpsZUBwcm90b24ubWU+wsGKBBABCAA+BQJj/G9SBAsJBwgJEGFtWWvCBl1IAxUICgQWAAIBAhkBAhsDAh4BFiEEpRQABVdStE+56giVYW1Za8IGXUgAAJsVEACCwO90h/jfWK0KJ203z9fRnDT+iX1ahTEnIvzsGUXwo5opTK8k8fz/wZDNl9itrd9c65fWOkeiVYM0jDINxeEvhTwJwTqYyic+yfnnH9EMIBlUCd36dh+xIK2GwdmtdqYBDwyKzOqWGRQb3zE9I6aHajI7yzaJyxEBLv2mrNId2Vtrz12JbJJv4RO4Dv3sZPJoJfbkuV5xg6uEUtIk9aAMiDdNUhkw3JvPq/cKnh6AAHPBSxxV8dRXOTgIgf5ncoXNodyGtbpPzis7Hxz+5KwoyfkDzQYtAKVpXRlyh+F06C5jUCUvmoFxZoH40OfSBpHKcu4EKqIBh28boI0ofxQCIWvMiYkcfYeKjnwg25MdpYvatxS4NQVegzq0DhiVEisO0cKtKawnVGPXTUsevGswICsJBS9DRv3FMkGJIDqR1S/E2GWZa3+U6A4TwPrcmzfXvzqQ+vxPdq03fMExIHeYlcnexypFUN9K/LtLgXEG34/LXXI9gNBjyfYUwjLZAuehYqsMqM05waJ3ZlgbZEsePK0LMfRO9g6lq7LsFtB0q28u5IwK6M7Fnox5bzQrhIDXAFpU4rw7GWWKF71Ujw9r6P8rY0RcRaW2RGlY8+tQvxnSHcK/Ki6ozlWQCv5blHur/EmTO9neO84dHspC8d5Ggwv8qDFR5deohm/TLlkh3c7BTQRj/G9SARAAv8AZdsZwWtxE7+NMX+CAurhFwvIxeDOjrXe5LeBhzIEUVXkTNIpf/udqBfH34LcemmoB6pPnpaxS0Grg/a8FLk7TRU2WkucrnbT8nuv9GihJCyucC9Co5ZoVmNwIFrxaSkC5oQvsQoytUyk5TJ95egTs7qcsICouCpcIJfM+seNtpc26XDWVrf+L3FWGK47LBExHhUrIbgEiUjLfHwCGZEQsctfTIs4W2PJhfF/egiPEDDLhfWgDQAplZrr6vZlCwPmGy5JYjYMq4u363+9eU/p3jBaK0kJg3O1KvDxnom/p4ouA64UbkB65gBW58XCECWGJi+AsKU4nmBTXu6DuFZUSedLl7LEmmFvcAHd5Pp9WFvn7UKae7qZRdLT8QDlRutn1IiVQLnlocI3dHS1Aw0uzbc8+kdE8SNbDBZYkLb7eb+aLsQtSegCu21+yIfMOBcBSoQa9uB3L9ZC1xvooGzWKWcCPjEykQc3akqACHGAsXXSOWvlfzx4dr9oDQASoqdQdZb3j3vDNqYYK00AJyQ9Rczic4tqDngUX8inTSAswkeQ/N/ZITI2Y3lwD0KF/vYTOSl7SK0wVLHZy54NXViZcuRJwYzqPoBpfj2ILGTa5o/WnTzWAQl+HHlD0xXhsLC0EeyiKMkBi0X/0MoHrdEvwvjSVIH7mGo+1hC2PipEAEQEAAcLBdgQYAQgAKgUCY/xvUgkQYW1Za8IGXUgCGwwWIQSlFAAFV1K0T7nqCJVhbVlrwgZdSAAAlfAP/1MszOKhkoqQK6JQHKyfBxXk+MKhp1TTAwtz+1X1OAOkrm/0Qi9S8kJU1LLQUXQWCNAsYM7H84lLfu9XTuHm39/QhupULjt1SAzc9Hfri00iSfWBB7diJX6UMjRMOAuNpiJ+/nKO8m7QJp61tvWdxYJUAXoJ0niZsnXk2KkJJHtceqVFGIuVjyFZVzZ3Z2I1QVOA8rxMZ9bSpnlzJFbHiyFmmAxLjn0Usr/wDKOPOubaVgt3+VVon6i4MWPnCgJ+KyuXI8Om99vRI3/d/fH0ZrBeK1Vyc8v2TTXtZHtOwpqczDn0JD4t+V/tv512cMeXGHjX1f0bNDkeRJ7czyX92FbyLhePuCg3oxEvB7yknSOzO0B/gmGarCBs3MltkE3fS9p8haasjBX1QLdkQAC4vT31BIrhyFFbQxnBeFGw/PK0Roga3gUH4WRkY24xdJ5ZOktj7F6y5mhxv69xbaJet4WB/6MGm36Zc9M0T0tcJlrGXTXFEw/PwRB1QJluM/KxliL2WcHSpr1rgRDGBmGCOGYYrPkjiHuBo3JqsVm0WNA5sNQKxg7PO+78WdK9nDCl8ZVimWLowZR776EhQ8nCqn8ckik9Y+AlJLQYmZj/np4NhifobIjw4MGcf8h2YOq6fWhhyZQKk1IOxVv0wZnqyjcHp3/HqlEqdUDdlDNGYaMN', + }, + }, + }; + const gmailPage4 = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr); + await gmailPage4.waitAll('iframe'); + // todo: we can add support for binary public keys + await gmailPage4.waitForContent('.attachment_loader', 'Unknown OpenPGP format'); + expect((await gmailPage4.getFramesUrls(['pgp_block.htm'], { sleep: 0, appearIn: 0 })).length).to.equal(1); + expect((await gmailPage4.getFramesUrls(['attachment.htm'], { sleep: 0, appearIn: 0 })).length).to.equal(0); + expect((await gmailPage4.getFramesUrls(['pgp_pubkey.htm'], { sleep: 0, appearIn: 0 })).length).to.equal(0); + await gmailPage4.close(); + }) + ); + test( 'signature - cleartext signed messages from HTML are re-fetched when needed', testWithBrowser(async (t, browser) => { - const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); const settingsPage = await browser.newExtensionSettingsPage(t, acctEmail); - const accessToken = await BrowserRecipe.getGoogleAccessToken(settingsPage, acctEmail); // todo: include in t? await settingsPage.close(); - const extraAuthHeaders = { Authorization: `Bearer ${accessToken}` }; // eslint-disable-line @typescript-eslint/naming-convention - const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/1866867cfdb8b61e`, undefined, extraAuthHeaders); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/1866867cfdb8b61e`, undefined, authHdr); await gmailPage.waitAll('iframe'); - const pgpBlock = await gmailPage.getFrame(['pgp_block.htm']); - // should re-fetch the correct text/plain text with signature - await BrowserRecipe.pgpBlockCheck(t, pgpBlock, { - content: ['this is message 1 for flowcrypt issue 4342'], - unexpectedContent: ['this is message 1 CORRUPTED for flowcrypt issue 4342'], + const pgpBlocks = await Promise.all((await gmailPage.getFramesUrls(['pgp_block.htm'])).map(url => gmailPage.getFrame([url]))); + expect(pgpBlocks.length).to.equal(3); + await BrowserRecipe.pgpBlockCheck(t, pgpBlocks[0], { + content: ['this is message 3 for flowcrypt issue 4342'], encryption: 'not encrypted', signature: 'signed', }); - await gmailPage.close(); - }) - ); - - test( - `decrypt - corrupted text in "incorrect message digest" scenario`, - testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); - const params = `?frameId=none&message=-----BEGIN%20PGP%20SIGNED%20MESSAGE-----%0AHash%3A%20SHA512%0A%0A%0Athis%20is%20message%201%20CORRUPTED%20for%20flowcrypt%20issue%204342%0A-----BEGIN%20PGP%20SIGNATURE-----%0A%0A%0AwnUEARYKACcFAmPwp3kJEAdIHIrPnUn%2BFiEEm6Oc4HXwg5swNA%2FIB0gcis%2Bd%0ASf4AAGFcAP4%2FB%2FjbpeERlTNqorb5x6sXUFhfPHP6PZAXvVnpuaFdJQD%2FZ510%0AeYDnbx25XRLsdWoerPpG23tgqK45zOHjaIoveAo%3D%0A%3DHAkD%0A-----END%20PGP%20SIGNATURE-----&msgId=1866867cfdb8b61e&senderEmail=ci.tests.gmail@flowcrypt.test&isOutgoing=___cu_true___&acctEmail=ci.tests.gmail@flowcrypt.test&parentTabId=0`; // should re-fetch the correct text/plain text with signature - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params, + await BrowserRecipe.pgpBlockCheck(t, pgpBlocks[1], { content: ['this is message 1 for flowcrypt issue 4342'], unexpectedContent: ['this is message 1 CORRUPTED for flowcrypt issue 4342'], encryption: 'not encrypted', signature: 'signed', }); - }) - ); - - test( - `decrypt - missing pubkey in "incorrect message digest" scenario`, - testWithBrowser(async (t, browser) => { - const msgId = '1766644f13510f58'; - const acctEmail = 'ci.tests.gmail@flowcrypt.test'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'ci.tests.gmail'); - const signerEmail = 'sender.for.refetch@domain.com'; - const data = await GoogleData.withInitializedData(acctEmail); - /* eslint-disable @typescript-eslint/no-non-null-assertion */ - const msg = data.getMessage(msgId)!; - const signature = Buf.fromBase64Str(msg!.raw!) - .toUtfStr() - .match(/\-\-\-\-\-BEGIN PGP SIGNATURE\-\-\-\-\-.*\-\-\-\-\-END PGP SIGNATURE\-\-\-\-\-/s)![0]; - /* eslint-enable @typescript-eslint/no-non-null-assertion */ - const params = `?frameId=none&account_email=${acctEmail}&senderEmail=${signerEmail}&msgId=${msgId}&message=Some%20corrupted%20message&signature=${encodeURIComponent( - signature - )}`; - // as the verification pubkey is not known, this scenario doesn't trigger message re-fetch - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params, - content: ['Some corrupted message'], + await BrowserRecipe.pgpBlockCheck(t, pgpBlocks[2], { + content: ['this is message 2 for flowcrypt issue 4342'], encryption: 'not encrypted', - signature: 'could not verify signature: missing pubkey 2864E326A5BE488A', + signature: 'signed', }); + await gmailPage.close(); }) ); test( - 'decrypt - re-fetch signed-only message from API on non-fatal verification error', + 'decrypt - signed-only PGP/MIME message is processed from API, rendered html is ignored', testWithBrowser(async (t, browser) => { const msgId = '17daefa0eb077da6'; const acctEmail = 'flowcrypt.compatibility@gmail.com'; const signerEmail = 'some.sender@test.com'; - const data = await GoogleData.withInitializedData(acctEmail); t.mockApi!.configProvider = new ConfigurationProvider({ attester: { pubkeyLookup: { @@ -1238,125 +1619,118 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }, }, }, + google: { htmlRenderer: () => 'Some corrupted message' }, }); - await BrowserRecipe.setUpCommonAcct(t, browser, 'compatibility'); - /* eslint-disable @typescript-eslint/no-non-null-assertion */ - const msg = data.getMessage(msgId)!; - const signature = Buf.fromBase64Str(msg!.raw!) - .toUtfStr() - .match(/\-\-\-\-\-BEGIN PGP SIGNATURE\-\-\-\-\-.*\-\-\-\-\-END PGP SIGNATURE\-\-\-\-\-/s)![0]; - /* eslint-enable @typescript-eslint/no-non-null-assertion */ - const params = `?frameId=none&account_email=${acctEmail}&senderEmail=${signerEmail}&msgId=${msgId}&message=Some%20corrupted%20message&signature=${encodeURIComponent( - signature - )}`; - // as the verification pubkey is retrieved from the attester, the incorrect message digest will trigger re-fetching from API - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params, - content: [], // todo: #4164 I would expect '1234' here + const { authHdr } = await BrowserRecipe.setUpCommonAcct(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + msgId, + { + content: ['1234'], + encryption: 'not encrypted', + signature: 'signed', + }, + authHdr + ); + }) + ); + + test( + 'decrypt - signed-only PGP/MIME message - text is rendered only once in inbox', + testWithBrowser(async (t, browser) => { + const msgId = '17daefa0eb077da6'; + const signerEmail = 'some.sender@test.com'; + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup![signerEmail] = { pubkey: await get203FAE7076005381() }; + const inboxPage = await browser.newExtensionInboxPage(t, acctEmail, msgId); + await inboxPage.waitAll('iframe'); + await BrowserRecipe.pgpBlockCheck(t, await inboxPage.getFrame(['pgp_block.htm']), { + content: ['1234'], encryption: 'not encrypted', signature: 'signed', }); + expect(await inboxPage.read('@message-line')).to.not.include('1234'); }) ); test( 'decrypt - protonmail - load pubkey into contact + verify detached msg', testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - t.mockApi!.configProvider = new ConfigurationProvider({ - attester: { - pubkeyLookup: { - [acctEmail]: { - pubkey: somePubkey, - }, - 'flowcrypt.compatibility@protonmail.com': { - pubkey: protonMailCompatKey, - }, - }, + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup!['flowcrypt.compatibility@protonmail.com'] = { pubkey: protonMailCompatKey }; + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '16a9c109bc51687d', + { + content: ['1234'], + encryption: 'not encrypted', + signature: 'could not verify signature: missing pubkey 7ED43D79E9617655', }, - }); - await BrowserRecipe.setUpCommonAcct(t, browser, 'compatibility'); - const textParams = - `?frameId=none&message=&msgId=16a9c109bc51687d&` + - `senderEmail=some.alias%40protonmail.com&isOutgoing=___cu_false___&signature=___cu_true___&acctEmail=flowcrypt.compatibility%40gmail.com`; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params: textParams, - content: ['1234'], - encryption: 'not encrypted', - signature: 'could not verify signature: missing pubkey 7ED43D79E9617655', - }); - await PageRecipe.addPubkey(t, browser, 'flowcrypt.compatibility%40gmail.com', testConstants.protonCompatPub, 'some.alias@protonmail.com'); - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params: textParams, - content: ['1234'], - encryption: 'not encrypted', - signature: 'signed', - }); - const htmlParams = - `?frameId=none&message=&msgId=16a9c0fe4e034bc2&` + - `senderEmail=some.alias%40protonmail.com&isOutgoing=___cu_false___&signature=___cu_true___&acctEmail=flowcrypt.compatibility%40gmail.com`; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params: htmlParams, - content: ['1234'], - encryption: 'not encrypted', - signature: 'signed', - }); + authHdr + ); + await PageRecipe.addPubkey(t, browser, 'flowcrypt.compatibility@gmail.com', testConstants.protonCompatPub, 'some.alias@protonmail.com'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '16a9c109bc51687d', + { + content: ['1234'], + encryption: 'not encrypted', + signature: 'signed', + }, + authHdr + ); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '16a9c0fe4e034bc2', + { + content: ['1234'], + encryption: 'not encrypted', + signature: 'signed', + }, + authHdr + ); }) ); test( 'decrypt - protonmail - auto TOFU load matching pubkey first time', testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - t.mockApi!.configProvider = new ConfigurationProvider({ - attester: { - pubkeyLookup: { - [acctEmail]: { - pubkey: somePubkey, - }, - 'flowcrypt.compatibility@protonmail.com': { - pubkey: protonMailCompatKey, - }, - }, + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup!['some.alias@protonmail.com'] = { pubkey: protonMailCompatKey }; + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '16a9c109bc51687d', + { + content: ['1234'], + encryption: 'not encrypted', + signature: 'signed', }, - }); - await BrowserRecipe.setUpCommonAcct(t, browser, 'compatibility'); - const params = - `?frameId=none&message=&msgId=16a9c109bc51687d&` + - `senderEmail=flowcrypt.compatibility%40protonmail.com&isOutgoing=___cu_false___&signature=___cu_true___&acctEmail=flowcrypt.compatibility%40gmail.com`; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params, - content: ['1234'], - encryption: 'not encrypted', - signature: 'signed', - }); + authHdr + ); }) ); test( 'decrypt - verify encrypted+signed message', testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - t.mockApi!.configProvider = new ConfigurationProvider({ - attester: { - pubkeyLookup: { - [acctEmail]: { - pubkey: somePubkey, - }, - 'martin@politick.ca': { - pubkey: mpVerificationKey, - }, - }, + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup!['martin@politick.ca'] = { pubkey: mpVerificationKey }; + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '1617429dc55600db', + { + content: ['4) signed + encrypted email if supported'], + encryption: 'encrypted', + signature: 'signed', }, - }); - await BrowserRecipe.setUpCommonAcct(t, browser, 'compatibility'); - const params = `?frameId=none&message=&msgId=1617429dc55600db&senderEmail=martin%40politick.ca&isOutgoing=___cu_false___&acctEmail=flowcrypt.compatibility%40gmail.com`; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params, - content: ['4) signed + encrypted email if supported'], - encryption: 'encrypted', - signature: 'signed', - }); + authHdr + ); }) ); @@ -1394,17 +1768,19 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== test( 'decrypt - wrong message - checksum throws error', testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const threadId = '15f7ffb9320bd79e'; const expectedContent = 'Ascii armor integrity check failed'; - const params = `?frame_id=&threadId=${threadId}&msgId=${threadId}&senderEmail=&account_email=flowcrypt.compatibility%40gmail.com`; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params, - content: [expectedContent], - encryption: '', - signature: '', - error: 'decrypt error', - }); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + threadId, + { + content: [expectedContent], + error: 'decrypt error', + }, + authHdr + ); }) ); @@ -1467,31 +1843,31 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== test.todo('decrypt - by entering secondary pass phrase'); - test( - `decrypt - don't allow api path traversal`, - testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - const params = - '?frame_id=frame_TWloVRhvZE&message=&message_id=../test&senderEmail=&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com'; - const pgpHostPage = await browser.newPage(t, `chrome/dev/ci_pgp_host_page.htm${params}`); - const pgpBlockPage = await pgpHostPage.getFrame(['pgp_block.htm']); - await pgpBlockPage.waitForSelTestState('ready', 5); - await pgpBlockPage.waitForContent('@container-err-text', 'API path traversal forbidden'); - }) - ); - test( `decrypt - signed only - parse error in a badge`, testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - const params = '?frame_id=&msgId=corrupted-1&signature=___cu_true___&senderEmail=&account_email=flowcrypt.compatibility%40gmail.com'; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params, - content: [], - encryption: '', - signature: '', - error: 'parse error', + const acctEmail = 'flowcrypt.compatibility@gmail.com'; + const msgId = '175ccd8755eab85f'; + // eslint-disable @typescript-eslint/no-non-null-assertion + t.mockApi!.configProvider = new ConfigurationProvider({ + attester: singlePubKeyAttesterConfig(acctEmail, somePubkey), + google: { + getMsg: { + [msgId]: { raw: { msg: { id: msgId, threadId: msgId, historyId: msgId, raw: 'RSo' } } }, // corrupted raw part + }, + }, }); + const { authHdr } = await BrowserRecipe.setUpCommonAcct(t, browser, 'compatibility'); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '175ccd8755eab85f', + { + content: [], + error: 'parse error', + }, + authHdr + ); }) ); @@ -1499,8 +1875,7 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== 'decrypt - prevent rendering of attachments from domain sources other than flowcrypt.s3.amazonaws.com', testWithBrowser(async (t, browser) => { const threadId1 = '184cc6aa8e884397'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId1}`); await inboxPage.waitAll('iframe'); const pgpBlock = await inboxPage.getFrame(['pgp_block.htm']); @@ -1510,71 +1885,41 @@ XZ8r4OC6sguP/yozWlkG+7dDxsgKQVBENeG6Lw== }) ); - test( - `decrypt - try path traversal forward slash workaround`, - testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - const params = - '?frame_id=frame_TWloVRhvZE&message=&message_id=..\\test&senderEmail=&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com'; - const pgpHostPage = await browser.newPage(t, `chrome/dev/ci_pgp_host_page.htm${params}`); - const pgpBlockPage = await pgpHostPage.getFrame(['pgp_block.htm']); - await pgpBlockPage.waitForSelTestState('ready', 5); - await pgpBlockPage.waitForContent('@container-err-text', 'API path traversal forbidden'); - }) - ); - test( `verify - sha1 shows error`, testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.compatibility@gmail.com'; - t.mockApi!.configProvider = new ConfigurationProvider({ - attester: { - pubkeyLookup: { - [acctEmail]: { - pubkey: somePubkey, - }, - 'sha1@sign.com': { - pubkey: sha1signpubkey, - }, - }, + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + t.mockApi!.configProvider!.config.attester!.pubkeyLookup!['sha1@sign.com'] = { pubkey: sha1signpubkey }; + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '1882fa9e2b996242', + { + content: ['test'], + encryption: 'not encrypted', + signature: 'error verifying signature: Insecure message hash algorithm: SHA1. Sender is using old, insecure OpenPGP software.', }, - }); - await BrowserRecipe.setUpCommonAcct(t, browser, 'compatibility'); - const msg = `-----BEGIN PGP MESSAGE----- - -yMCxATvCy8zAxHhitbJOfXrcEcbTKkkMIOCRmpOTr6NQkpFZrABEiQolqcUlCrmpxcWJ6alchw5U -sjAwMjEoiymyhJfeapohyXRUYeazxTBjWJkSeOtDWJnBRnFxCsDEv33mYDjmdsuGPyx68g7tMwe3 -tqlevvUo5EIap+wmZm6mRXcOGBplvJy1mfuq1plrt08qs97Y2ztB+/XbuyG3Ir48u7I3pmD+TWae -WSd5d26QYXcuusauc0Xy/fS1/FXbPJaYHlCeMCfnhrF9d2jyH33V+er6r3lS5i/mchOKffpglktT -d6Z36//MsmczN00Wd60t9T+qyLz0T4/UG2Y9lgf367f3d+kYPE0LS7mXuFmjlPXfw0nKyVsSeFiu -3duz+VfzU3HVZ65L4xc5PBYwWLlshdcG94VTt2oK3cuLC5zuy/3ks0sw1+MGzmKtjMeJrqXph+8p -5W5JmHL28qarbQvv+71V3ni6odk8Z2NDban2y1kA -=Ruyn ------END PGP MESSAGE-----`; - const params = `?frame_id=frame_TWloVRhvZE&message=${encodeURIComponent( - msg - )}&message_id=none&senderEmail=sha1%40sign.com&is_outgoing=___cu_false___&account_email=flowcrypt.compatibility%40gmail.com`; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params, - content: ['test'], - encryption: 'not encrypted', - signature: 'error verifying signature: Insecure message hash algorithm: SHA1. Sender is using old, insecure OpenPGP software.', - }); + authHdr + ); }) ); test( 'verify - Kraken - urldecode signature', testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - const params = `?frameId=frame_ZRxshLEFdc&message=&msgId=171d138c8750863b&senderEmail=Kraken%20%3Ccensored%40email.com%3E&isOutgoing=___cu_false___&signature=___cu_true___&acctEmail=flowcrypt.compatibility%40gmail.com&parentTabId=12%3A0`; + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const expectedContent = 'Kraken clients can now begin converting popular currencies'; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params, - content: [expectedContent], - encryption: 'not encrypted', - signature: 'could not verify signature: missing pubkey A38042F607D623DA', - }); + await BrowserRecipe.pgpBlockVerifyDecryptedContent( + t, + browser, + '171d138c8750863b', + { + content: [expectedContent], + encryption: 'not encrypted', + signature: 'could not verify signature: missing pubkey A38042F607D623DA', + }, + authHdr + ); }) ); @@ -1584,18 +1929,8 @@ d6Z36//MsmczN00Wd60t9T+qyLz0T4/UG2Y9lgf367f3d+kYPE0LS7mXuFmjlPXfw0nKyVsSeFiu const threadId = '187365d19ec9a10c'; const threadId2 = '18736a0687a8426b'; const threadId3 = '187cfc92db548a0c'; - const acctEmail = 'flowcrypt.compatibility@gmail.com'; const expectedErrMsg = 'This executable file was not checked for viruses, and may be dangerous to download or run. Proceed anyway?'; - t.mockApi!.configProvider = new ConfigurationProvider({ - attester: { - pubkeyLookup: { - [acctEmail]: { - pubkey: somePubkey, - }, - }, - }, - }); - await BrowserRecipe.setUpCommonAcct(t, browser, 'compatibility'); + const { acctEmail, authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); const pgpBlockPage = await inboxPage.getFrame(['pgp_block.htm']); await pgpBlockPage.waitAndClick('@download-attachment-0'); @@ -1629,10 +1964,8 @@ d6Z36//MsmczN00Wd60t9T+qyLz0T4/UG2Y9lgf367f3d+kYPE0LS7mXuFmjlPXfw0nKyVsSeFiu }) ); expect(Object.entries(downloadedFile3).length).to.equal(1); - const accessToken = await BrowserRecipe.getGoogleAccessToken(inboxPage2, acctEmail); await inboxPage2.close(); - const extraAuthHeaders = { Authorization: `Bearer ${accessToken}` }; // eslint-disable-line @typescript-eslint/naming-convention - const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${threadId}`, undefined, extraAuthHeaders); + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${threadId}`, undefined, authHdr); await gmailPage.waitAll('iframe'); const pgpBlockPage3 = await gmailPage.getFrame(['pgp_block.htm']); await pgpBlockPage3.waitAndClick('@download-attachment-0'); @@ -1656,7 +1989,7 @@ d6Z36//MsmczN00Wd60t9T+qyLz0T4/UG2Y9lgf367f3d+kYPE0LS7mXuFmjlPXfw0nKyVsSeFiu ); expect(Object.entries([downloadedFile4, downloadedFile5]).length).to.equal(2); await gmailPage.close(); - const gmailPage2 = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${threadId2}`, undefined, extraAuthHeaders); + const gmailPage2 = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${threadId2}`, undefined, authHdr); const pgpBlockPage4 = await gmailPage2.getFrame(['pgp_block.htm']); await pgpBlockPage4.waitAndClick('@download-attachment-0'); // check warning modal for inline signed attachment test on Gmail page diff --git a/test/source/tests/flaky.ts b/test/source/tests/flaky.ts index ac71d7af88f..78c01ec25d7 100644 --- a/test/source/tests/flaky.ts +++ b/test/source/tests/flaky.ts @@ -30,7 +30,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test test( 'compose - own key expired - update and retry', testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.test.key.new.manual@gmail.com'; + const acctEmail = 'flowcrypt.test.key.new.manual.0@gmail.com'; t.mockApi!.configProvider = new ConfigurationProvider({ attester: { pubkeyLookup: { @@ -94,7 +94,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test test( 'setup - create key - with backup to inbox', testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.test.key.new.manual@gmail.com'; + const acctEmail = 'flowcrypt.test.key.new.manual.1@gmail.com'; t.mockApi!.configProvider = new ConfigurationProvider({ attester: singlePubKeyAttesterConfig(acctEmail, somePubkey), }); @@ -112,7 +112,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test test( 'setup - create key - choose no backup', testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.test.key.new.manual@gmail.com'; + const acctEmail = 'flowcrypt.test.key.new.manual.2@gmail.com'; t.mockApi!.configProvider = new ConfigurationProvider({ attester: singlePubKeyAttesterConfig(acctEmail, somePubkey), }); @@ -130,7 +130,7 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test test( 'setup - create key - backup as file - submit pubkey', testWithBrowser(async (t, browser) => { - const acctEmail = 'flowcrypt.test.key.new.manual@gmail.com'; + const acctEmail = 'flowcrypt.test.key.new.manual.3@gmail.com'; t.mockApi!.configProvider = new ConfigurationProvider({ attester: singlePubKeyAttesterConfig(acctEmail, somePubkey), }); diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index bd0cf62ebee..a1f72d649ea 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -140,27 +140,17 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test ); test( - 'mail.google.com - decrypt message in offline mode', + 'mail.google.com - back button works in offline mode', testWithBrowser(async (t, browser) => { await BrowserRecipe.setUpCommonAcct(t, browser, 'ci.tests.gmail'); const gmailPage = await openGmailPage(t, browser); - /* - await gmailPage.type('[aria-label^="Search"]', 'encrypted email for offline decrypt'); - await gmailPage.press('Enter'); // submit search - await Util.sleep(2); // wait for search results - */ await gotoGmailPage(gmailPage, '/FMfcgzGkbDWztBnnCgRHzjrvmFqLtcJD'); - const pgpBlockUrls = await gmailPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { - sleep: 10, - appearIn: 25, - }); - expect(pgpBlockUrls.length).to.equal(1); - await gmailPage.page.setOfflineMode(true); // go offline mode - await gmailPage.press('Enter'); // open the message - const pgpBlockFrame = await gmailPage.getFrame(['pgp_block.htm']); + const expectedMessage = { content: ['this should decrypt even offline'], signature: 'signed', encryption: 'encrypted' }; + await BrowserRecipe.pgpBlockCheck(t, await gmailPage.getFrame(['/chrome/elements/pgp_block.htm'], { sleep: 10, timeout: 25 }), expectedMessage); + await gotoGmailPage(gmailPage, '/FMfcgzGkbDRNgcQxLmkhBCKVSFwkfdvV'); // plain convo await gmailPage.page.setOfflineMode(true); // go offline mode - await pgpBlockFrame.frame.goto(pgpBlockFrame.frame.url()); // reload the frame - await pgpBlockFrame.waitForContent('@pgp-block-content', 'this should decrypt even offline'); + await gmailPage.page.goBack({ waitUntil: 'load' }); + await BrowserRecipe.pgpBlockCheck(t, await gmailPage.getFrame(['/chrome/elements/pgp_block.htm']), expectedMessage); }) ); @@ -184,9 +174,8 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await gotoGmailPage(gmailPage, '/QgrcJHrtqfgLGKqwChjKsHKzZQpwRHMBqpG'); const urls = await gmailPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { sleep: 10, appearIn: 25 }); expect(urls.length).to.equal(1); - const params = urls[0].split('/chrome/elements/pgp_block.htm')[1]; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params, + const pgpBlockFrame = await gmailPage.getFrame(['pgp_block.htm']); + await BrowserRecipe.pgpBlockCheck(t, pgpBlockFrame, { content: ['test that content from msg.asc renders'], encryption: 'encrypted', signature: 'not signed', @@ -207,15 +196,14 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test appearIn: 25, }); expect(pgpBlockUrls.length).to.equal(1); - const url = pgpBlockUrls[0].split('/chrome/elements/pgp_block.htm')[1]; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params: url, + const pgpBlockFrame = await gmailPage.getFrame([pgpBlockUrls[0]]); + await BrowserRecipe.pgpBlockCheck(t, pgpBlockFrame, { content: ['1234'], encryption: 'not encrypted', signature: 'signed', }); await pageHasSecureReplyContainer(t, browser, gmailPage); - await testMinimumElementHeight(gmailPage, '.pgp_block.signedMsg', 80); + await testMinimumElementHeight(gmailPage, '.pgp_block.signedDetached', 80); await testMinimumElementHeight(gmailPage, '.pgp_block.publicKey', 120); const pubkeyPage = await gmailPage.getFrame(['/chrome/elements/pgp_pubkey.htm']); await pubkeyPage.waitForContent('@container-pgp-pubkey', 'Fingerprint: 50B7 A032 B5E1 FBAB 24BA B205 B362 45FD AC2F BF3D'); @@ -234,11 +222,10 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test appearIn: 25, }); expect(pgpBlockUrls.length).to.equal(1); - await testMinimumElementHeight(gmailPage, '.pgp_block.signedMsg', 80); + await testMinimumElementHeight(gmailPage, '.pgp_block.signedDetached', 80); await testMinimumElementHeight(gmailPage, '.pgp_block.publicKey', 120); - const url = pgpBlockUrls[0].split('/chrome/elements/pgp_block.htm')[1]; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params: url, + const pgpBlockFrame = await gmailPage.getFrame([pgpBlockUrls[0]]); + await BrowserRecipe.pgpBlockCheck(t, pgpBlockFrame, { content: ['1234'], encryption: 'not encrypted', signature: 'signed', @@ -255,13 +242,8 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await BrowserRecipe.setUpCommonAcct(t, browser, 'ci.tests.gmail'); const gmailPage = await openGmailPage(t, browser); await gotoGmailPage(gmailPage, '/FMfcgzGkbDZKPLBqWFzbgWqCrplTQdNz'); - const pgpBlockUrls = await gmailPage.getFramesUrls(['/chrome/elements/pgp_block.htm'], { - sleep: 10, - appearIn: 25, - }); - const url = pgpBlockUrls[0].split('/chrome/elements/pgp_block.htm')[1]; - await BrowserRecipe.pgpBlockVerifyDecryptedContent(t, browser, { - params: url, + const pgpBlockFrame = await gmailPage.getFrame(['pgp_block.htm'], { sleep: 10, timeout: 25 }); + await BrowserRecipe.pgpBlockCheck(t, pgpBlockFrame, { content: ['Encrypted Subject: [ci.test] Thunderbird html signed + encrypted', '1234'], encryption: 'encrypted', signature: 'signed', diff --git a/test/source/tests/settings.ts b/test/source/tests/settings.ts index d4723eea717..4fd8e2ab108 100644 --- a/test/source/tests/settings.ts +++ b/test/source/tests/settings.ts @@ -20,7 +20,7 @@ import { Buf } from '../core/buf'; import { GoogleData } from '../mock/google/google-data'; import Parse from './../util/parse'; import { OpenPGPKey } from '../core/crypto/pgp/openpgp-key'; -import { BrowserHandle } from '../browser'; +import { BrowserHandle, ControllablePage } from '../browser'; import { AvaContext } from './tooling'; import { ConfigurationProvider, HttpClientErr, Status } from '../mock/lib/api'; import { somePubkey, testMatchPubKey } from '../mock/attester/attester-key-constants'; @@ -764,30 +764,57 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await attachmentPreviewImage.waitAll('#attachment-preview-container img.attachment-preview-img'); }) ); + test( + 'settings - inbox - show original', + testWithBrowser(async (t, browser) => { + const threadId = '15f7f5e966792203'; // signed inline + const { acctEmail } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const inboxPage = await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=${acctEmail}&threadId=${threadId}`); + await inboxPage.waitForSelTestState('ready'); + await inboxPage.waitAll('iframe'); + expect((await inboxPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(1); + expect(await inboxPage.read('@message-line')).to.not.contain('BEGIN'); + expect(await inboxPage.read('@see-original')).to.equal('SEE ORIGINAL'); + + // switch to original + await inboxPage.waitForNavigationIfAny(() => inboxPage.waitAndClick('@see-original')); + await inboxPage.waitForSelTestState('ready'); + await inboxPage.waitAll('iframe'); + // expect no pgp blocks + expect((await inboxPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(0); + expect(await inboxPage.read('@message-line')).to.contain('BEGIN'); + expect(await inboxPage.read('@see-original')).to.equal('SEE DECRYPTED'); + + // switch back to decrypted + await inboxPage.waitForNavigationIfAny(() => inboxPage.waitAndClick('@see-original')); + await inboxPage.waitForSelTestState('ready'); + await inboxPage.waitAll('iframe'); + expect((await inboxPage.getFramesUrls(['pgp_block.htm'])).length).to.equal(1); + expect(await inboxPage.read('@message-line')).to.not.contain('BEGIN'); + expect(await inboxPage.read('@see-original')).to.equal('SEE ORIGINAL'); + }) + ); test( 'settings - pgp/mime preview and download attachment', testWithBrowser(async (t, browser) => { - await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); - const downloadedAttachmentFilename = `${__dirname}/7 years.jpeg`; - Util.deleteFileIfExists(downloadedAttachmentFilename); - const inboxPage = await browser.newExtensionPage( - t, - `chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=16e8b01f136c3d28` - ); - const pgpBlockFrame = await inboxPage.getFrame(['pgp_block.htm']); - // check if download is awailable - await pgpBlockFrame.waitAll('.download-attachment'); - // and preview - await pgpBlockFrame.waitAndClick('.preview-attachment'); - const attachmentPreviewImage = await inboxPage.getFrame(['attachment_preview.htm']); - await attachmentPreviewImage.waitAll('#attachment-preview-container img.attachment-preview-img'); - await (inboxPage.target as any) // eslint-disable-line no-underscore-dangle - ._client() - .send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath: __dirname }); - await attachmentPreviewImage.waitAndClick('@attachment-preview-download'); - await Util.sleep(1); - expect(fs.existsSync(downloadedAttachmentFilename)).to.be.true; - Util.deleteFileIfExists(downloadedAttachmentFilename); + const { authHdr } = await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); + const checkPage = async (page: ControllablePage) => { + const pgpBlockFrame = await page.getFrame(['pgp_block.htm']); + // check if download is awailable + await pgpBlockFrame.waitAll('.download-attachment'); + // and preview + await pgpBlockFrame.waitAndClick('.preview-attachment'); + const attachmentPreviewImage = await page.getFrame(['attachment_preview.htm']); + await attachmentPreviewImage.waitAll('#attachment-preview-container img.attachment-preview-img'); + const downloadedFiles = await attachmentPreviewImage.awaitDownloadTriggeredByClicking(() => + attachmentPreviewImage.waitAndClick('@attachment-preview-download') + ); + expect(Object.keys(downloadedFiles)).contains('7 years.jpeg'); + await page.close(); + }; + const msgId = '16e8b01f136c3d28'; + await checkPage(await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, authHdr)); + await checkPage(await browser.newExtensionPage(t, `chrome/settings/inbox/inbox.htm?acctEmail=flowcrypt.compatibility@gmail.com&threadId=${msgId}`)); }) ); const checkIfFileDownloadsCorrectly = async (t: AvaContext, browser: BrowserHandle, threadId: string, fileName: string) => { @@ -805,8 +832,8 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T await BrowserRecipe.setupCommonAcctWithAttester(t, browser, 'compatibility'); // `what's up?.txt` becomes `what's_up_.txt` and this is native way and we can't change this logic // https://github.com/FlowCrypt/flowcrypt-browser/issues/3505#issuecomment-812269422 - await checkIfFileDownloadsCorrectly(t, browser, '1821bf879a6f71e0', "what's_up_.txt"); - await checkIfFileDownloadsCorrectly(t, browser, '182263bf9f105adf', "what's_up%253F.txt.pgp"); + await checkIfFileDownloadsCorrectly(t, browser, '188721aebb71c16c', "what's_up_.txt"); + await checkIfFileDownloadsCorrectly(t, browser, '188722a157fd54a8', `what's_up%253F.txt`); // should not strip .gpg or .pgp extension when downloading original file after unsuccesssful decryption // // Check if bad pgp attachment file got downloaded with original file name await checkIfFileDownloadsCorrectly(t, browser, '18610f7f4ae8da0a', 'test.bat.pgp'); diff --git a/test/source/tests/tooling/browser-recipe.ts b/test/source/tests/tooling/browser-recipe.ts index f81ee6ab548..f95655b6a4a 100644 --- a/test/source/tests/tooling/browser-recipe.ts +++ b/test/source/tests/tooling/browser-recipe.ts @@ -1,18 +1,19 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ -import { Config, Util, TestMessage, TestMessageWithParams } from '../../util'; +import { Config, Util, TestMessage } from '../../util'; import { AvaContext } from '.'; import { BrowserHandle, Controllable, ControllableFrame, ControllablePage } from '../../browser'; import { OauthPageRecipe } from './../page-recipe/oauth-page-recipe'; import { SetupPageRecipe } from './../page-recipe/setup-page-recipe'; import { TestUrls } from '../../browser/test-urls'; -import { google } from 'googleapis'; +import { gmail_v1, google } from 'googleapis'; import { testVariant } from '../../test'; import { testConstants } from './consts'; import { PageRecipe } from '../page-recipe/abstract-page-recipe'; import { InMemoryStoreKeys } from '../../core/const'; import { GmailPageRecipe } from '../page-recipe/gmail-page-recipe'; +import { expect } from 'chai'; import { KeyUtil } from '../../core/crypto/key'; import { ConfigurationProvider } from '../../mock/lib/api'; @@ -99,7 +100,8 @@ export class BrowserRecipe { } const accessToken = await BrowserRecipe.getGoogleAccessToken(settingsPage, acctEmail); await settingsPage.close(); - return { acctEmail, accessToken }; + const authHdr = { Authorization: `Bearer ${accessToken}` }; // eslint-disable-line @typescript-eslint/naming-convention + return { acctEmail, authHdr }; }; public static setupCommonAcctWithAttester = async (t: AvaContext, browser: BrowserHandle, acct: 'compatibility' | 'compose' | 'ci.tests.gmail') => { @@ -164,15 +166,20 @@ export class BrowserRecipe { // eslint-disable-next-line @typescript-eslint/naming-convention const list = await gmail.users.drafts.list({ userId: 'me', access_token: accessToken }); if (list.data.drafts) { - await Promise.all( - list.data.drafts - .filter(draft => draft.id) - // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-non-null-assertion - .map(draft => gmail.users.drafts.delete({ id: draft.id!, userId: 'me', access_token: accessToken })) - ); + await BrowserRecipe.deleteDrafts(list.data.drafts, accessToken); } }; + public static deleteDrafts = async (drafts: gmail_v1.Schema$Draft[], accessToken: string) => { + const gmail = google.gmail({ version: 'v1' }); + await Promise.all( + drafts + .filter(draft => draft.id) + // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-non-null-assertion + .map(draft => gmail.users.drafts.delete({ id: draft.id!, userId: 'me', access_token: accessToken })) + ); + }; + // todo - ideally we could just add a 3rd common account: 'compatibility' | 'compose' | 'pp-change' in setUpCommonAcct public static setUpFcPpChangeAcct = async (t: AvaContext, browser: BrowserHandle) => { const acctEmail = 'flowcrypt.test.key.imported@gmail.com'; @@ -205,14 +212,17 @@ export class BrowserRecipe { return { acctEmail, passphrase: key.passphrase, settingsPage }; }; - public static pgpBlockVerifyDecryptedContent = async (t: AvaContext, browser: BrowserHandle, m: TestMessageWithParams) => { - const pgpHostPage = await browser.newPage(t, `chrome/dev/ci_pgp_host_page.htm${m.params}`); - try { - const pgpBlockPage = await pgpHostPage.getFrame(['pgp_block.htm']); - return await BrowserRecipe.pgpBlockCheck(t, pgpBlockPage, m); - } finally { - await pgpHostPage.close(); - } + public static pgpBlockVerifyDecryptedContent = async ( + t: AvaContext, + browser: BrowserHandle, + msgId: string, + m: TestMessage, + extraHeaders: Record + ) => { + const gmailPage = await browser.newPage(t, `${t.urls?.mockGmailUrl()}/${msgId}`, undefined, extraHeaders); + await gmailPage.waitAll('iframe'); + await BrowserRecipe.pgpBlockCheck(t, await gmailPage.getFrame(['pgp_block.htm']), m); + await gmailPage.close(); }; public static pgpBlockCheck = async (t: AvaContext, pgpBlockPage: ControllableFrame, m: TestMessage) => { @@ -243,21 +253,30 @@ export class BrowserRecipe { } } } + const sigBadgeContent = await pgpBlockPage.read('@pgp-signature'); + const encBadgeContent = await pgpBlockPage.read('@pgp-encryption'); if (m.signature) { - const sigBadgeContent = await pgpBlockPage.read('@pgp-signature'); + // todo: check color, 'signed' should have 'green_label' class without 'red_label', others should have 'red_label' class if (sigBadgeContent !== m.signature) { t.log(`found sig content:${sigBadgeContent}`); throw new Error(`pgp_block_verify_decrypted_content:missing expected signature content:${m.signature}\nactual sig content:${sigBadgeContent}`); } + } else if (!m.error) { + // some badge still has to be present + expect(sigBadgeContent).to.be.ok; } if (m.encryption) { - const encBadgeContent = await pgpBlockPage.read('@pgp-encryption'); if (encBadgeContent !== m.encryption) { t.log(`found enc content:${encBadgeContent}`); throw new Error(`pgp_block_verify_decrypted_content:missing expected encryption content:${m.encryption}`); } + } else if (!m.error) { + // some badge still has to be present + expect(encBadgeContent).to.be.ok; } if (m.error) { + expect(sigBadgeContent).to.be.empty; + expect(encBadgeContent).to.be.empty; await pgpBlockPage.notPresent('@action-print'); const errBadgeContent = await pgpBlockPage.read('@pgp-error'); if (errBadgeContent !== m.error) { diff --git a/test/source/tests/unit-node.ts b/test/source/tests/unit-node.ts index 576269cfa4d..31746a000ce 100644 --- a/test/source/tests/unit-node.ts +++ b/test/source/tests/unit-node.ts @@ -2743,6 +2743,23 @@ AAAAAAAAAAAAAAAAzzzzzzzzzzzzzzzzzzzzzzzzzzzz.....`) t.pass(); }); + test(`[unit][ExpirationCache.await] removes rejected promises from cache`, async t => { + const cache = new ExpirationCache>(24 * 60 * 60 * 1000); // 24 hours + const rejectionPromise = Promise.reject(Error('test-error')); + cache.set('test-key', rejectionPromise); + await t.throwsAsync(() => cache.await('test-key', rejectionPromise) as Promise>, { + instanceOf: Error, + message: 'test-error', + }); + expect(cache.get('test-key')).to.be.an('undefined'); // next call simply returns undefined + const fulfilledPromise = Promise.resolve('new-test-value'); + cache.set('test-key', fulfilledPromise); + // good value is returned indefinitely + expect(await cache.await('test-key', fulfilledPromise)).to.equal('new-test-value'); + expect(await cache.await('test-key', fulfilledPromise)).to.equal('new-test-value'); + expect(cache.get('test-key')).to.equal(fulfilledPromise); + }); + test(`[unit][Str] splitAlphanumericExtended returns all parts extendec till the end of the original string`, async t => { expect(Str.splitAlphanumericExtended('part1.part2@part3.part4')).to.eql(['part1.part2@part3.part4', 'part2@part3.part4', 'part3.part4', 'part4']); t.pass(); diff --git a/test/source/util/index.ts b/test/source/util/index.ts index 339b40a327b..c5b91aeed0a 100644 --- a/test/source/util/index.ts +++ b/test/source/util/index.ts @@ -46,10 +46,6 @@ export type TestMessage = { error?: string; }; -export type TestMessageWithParams = TestMessage & { - params: string; -}; - export type TestKeyInfo = { title: string; passphrase: string; diff --git a/tooling/build-types-and-manifests.ts b/tooling/build-types-and-manifests.ts index 5068fcaefb4..49e9ae392ba 100644 --- a/tooling/build-types-and-manifests.ts +++ b/tooling/build-types-and-manifests.ts @@ -114,6 +114,8 @@ const updateEnterpriseBuild = () => { const makeMockBuild = (sourceBuildType: string) => { const mockBuildType = `${sourceBuildType}-mock`; + const mockGmailPageHost = 'gmail.localhost:8001'; + const mockGmailPage = `https://${mockGmailPageHost}`; exec(`cp -r ${buildDir(sourceBuildType)} ${buildDir(mockBuildType)}`); const editor = (code: string) => { return code @@ -131,7 +133,7 @@ const makeMockBuild = (sourceBuildType: string) => { edit(`${buildDir(mockBuildType)}/js/common/platform/catch.js`, editor); edit(`${buildDir(mockBuildType)}/js/content_scripts/webmail_bundle.js`, editor); edit(`${buildDir(mockBuildType)}/manifest.json`, code => - code.replace(/https:\/\/mail\.google\.com/g, 'https://gmail.localhost:8001').replace(/https:\/\/www\.google\.com/g, 'https://google.localhost:8001') + code.replace(/https:\/\/mail\.google\.com/g, mockGmailPage).replace(/https:\/\/www\.google\.com/g, 'https://google.localhost:8001') ); };