jhillyerd / enmime Goto Github PK
View Code? Open in Web Editor NEWMIME mail encoding and decoding package for Go
License: MIT License
MIME mail encoding and decoding package for Go
License: MIT License
Branching off from #11
"There isn't anything in there about the Root, or the message headers, besides the GetHeader function, which when you look at it, accesses the private header field. It's not quite clear the Root headers and the same as the Envelope field."
Now that the MIMEPart interface has been eliminated, the getters and setters on Part don't have much purpose, and having them is not idiomatic for Go.
The accessors will be replaced with public struct fields. This is an API change, so it's better to do it now before an official release.
I need a little help getting information from the Header below, as you can see there are newline separation between header fields, the purpose is to get the status and the Diagnostic-Code field.
--1489
Content-Description: Delivery report
Content-Type: message/delivery-status
Reporting-MTA: dns; host1337
X-Postfix-Queue-ID: 1489
X-Postfix-Sender: rfc822; [email protected]
Arrival-Date: Wed, 4 May 2017 15:21:18 +0200 (EST)
Final-Recipient: rfc822; [email protected]
Original-Recipient: rfc822;[email protected]
Action: failed
Status: 4.2.1
Diagnostic-Code: something went
wrong
--1489
The problem right now is that it stopes looking for header fields when it encounters a empty newline, so the fields that i need is not in the *Part variable, if i remove the empty line's manually it work's.
(The mail comes directly from a postfix that received it from google.)
And the code i am using to get the information.
r := strings.NewReader(Mailcontent_String)
env, err := enmime.ReadEnvelope(r)
if err != nil {
fmt.Print(err)
}
part2 := env.Root.FirstChild.NextSibling
fmt.Println(part2.Header)
Per RFC 1341 (https://tools.ietf.org/html/rfc1341):
In general, choosing the best type
means displaying only the LAST part that can be displayed.
With the current implementation, it is hard to determine mime part ordering. Additionally, enmime drains the content from HTML and text parts, making it hard to interact with each mime part as a whole entity.
Ideally, the api would allow for something like:
# get a slice of mime parts
mimeParts := ReadMime(reader)
for _, part := range mimeParts {
mapOfHeaders := part.Headers() // map[string][]string
easyAccessToCommonHeader := part.ContentType() // have other helpers maybe, like "to", "from", or get header slice by string, get charset, etc
rawBytes := part.RawContent()
decoded := part.DecodedContent() // uses the detected charset and content type
}
This allows a client to know the order and present the best display and allows for easily parsing the mime entities. Ideally, someone should be able to stitch this information back together and create the (nearly) identical email from the parts.
Unfortunately, you cannot always trust the charset that is defined in a Content-Type header. We've seen cases where enmime essentially corrupts part.Content by decoding a declared gbk charset where the data in fact was utf-8.
Instead of taking for granted whatever is declared in the header, one could ask a charset detection library like https://github.com/saintfish/chardet. I'll see if I can prepare a PR. Let me know what you think.
With the later changes, the headers field of the Envelope has been made private. I have need of all headers in the email and there does not seem to be a way of doing this without knowing ahead of time what they are, and using the GetHeader method.
Do you have a recommended way of doing this, ie perhaps a new HeaderKeys method, make headers public, or a new GetRawHeader method, or perhaps there is something I'm missing?
https://github.com/jhillyerd/go.enmime/issues/13 - reported by @kgilonne
I encounter difficulties to parse a MIME file, due to 2 boundaries:.
Content-Type: multipart/related; boundary="----=_NextPart_eedf1356402a50765728c12998413837"
Content-Type: multipart/alternative; boundary="----=_NextPart_eedf1356402a50765728c12998413837_alt"
A test for this scenario should be created to see if the new boundaryReader handles it correctly.
Changes in #35 should have had unit tests, but I don't want to hold up PR queue
If the header contains fields like "Dkim-Signature" or "Domainkey-Signature" which contain a 'Content-Type:' inside the value then Content-Type header field is parsed wrongly as 'List-Unsubscribe; b=oCvFiVQEh8Fqkfnk9yJ2llkWAnsRxQr8Xf10SjcXK2wrzCXtizroaBbi0FZ7XbHd9fFz03 9UcQ7Vc1EUZ8pAHMG98BRjVaUNuEl2Eqle+NoKi+zRA023xULkCmWzWalclNB/FI5YTEQCpl JBE4+6LWrtWlorhybEDjvi4chJzc0=' instead of 'multipart/alternative; boundary=mimepart_583f950f96b48_6afcdf1038924a'.
Example headers in the email:-
"headers": {
"Authentication-Results": "mx.google.com; dkim=pass [email protected]; spf=pass (google.com: domain of bounce+beef2e.191099-deepak=[email protected] designates 166.78.70.59 as permitted sender) smtp.mailfrom=bounce+beef2e.191099-deepak=[email protected]",
"Content-Type": "multipart/alternative; boundary=mimepart_583f950f96b48_6afcdf1038924a",
"Delivered-To": "[email protected]",
"Dkim-Signature": "a=rsa-sha256; v=1; c=relaxed/relaxed; d=papertrailapp.com; q=dns/txt; s=krs; t=1480561936; h=List-Unsubscribe: Content-Type: Mime-Version: Subject: Message-Id: To: From: Date: Sender; bh=Ypk2VpJetOH0wE/ecQUh9usmggXKCYSph2kozqlVh78=; b=oBgHqQb5gL9P21CVXgOUN06ByZHE4Znxnyp3JsIePEzsMDF+Z4nuzKl9CeQA1gv6B3v329Tr W6yRYEXPBPANr2EWcbK9gPUjT33SLckZlvFbaIeEv4/bdCrcr0V7CTBQzMLhXmDuv8xth427 FFlyn2Zy0dWTMFd3UUvp64QrTYc=",
"Domainkey-Signature": "a=rsa-sha1; c=nofws; d=papertrailapp.com; s=krs; q=dns; h=Sender: Date: From: To: Message-Id: Subject: Mime-Version: Content-Type: List-Unsubscribe; b=oCvFiVQEh8Fqkfnk9yJ2llkWAnsRxQr8Xf10SjcXK2wrzCXtizroaBbi0FZ7XbHd9fFz03 9UcQ7Vc1EUZ8pAHMG98BRjVaUNuEl2Eqle+NoKi+zRA023xULkCmWzWalclNB/FI5YTEQCpl JBE4+6LWrtWlorhybEDjvi4chJzc0=",
"List-Unsubscribe": "https://papertrailapp.com/account",
"Message-Id": "[email protected]",
"Mime-Version": "1.0",
"Received": "by 10.31.150.214 with SMTP id y205csp655646vkd; Wed, 30 Nov 2016 19:12:17 -0800 (PST)\nfrom smtp-out.papertrailapp.com (smtp-out.papertrailapp.com. [166.78.70.59]) by mx.google.com with ESMTPS id d12si49552199iof.62.2016.11.30.19.12.16 for [email protected] (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Nov 2016 19:12:16 -0800 (PST)\nfrom papertrailapp.com (pt02rw04.papertrailapp.com [67.214.214.182]) by mxa.mailgun.org with ESMTP id 583f9510.7f4fa0643298-smtp-out-n03; Thu, 01 Dec 2016 03:12:16 -0000 (UTC)",
"Received-Spf": "pass (google.com: domain of bounce+beef2e.191099-deepak=[email protected] designates 166.78.70.59 as permitted sender) client-ip=166.78.70.59;",
"Return-Path": "[email protected]",
"Sender": "[email protected]",
"X-GM-MSGID": "158b85e4ae57c1ba",
"X-GM-THRID": "158b85e4ae57c1ba",
"X-Mailgun-Sending-Ip": "166.78.70.59",
"X-Mailgun-Sid": "WyI3YjEyNCIsICJkZWVwYWtAcmVkc2lmdC5pbyIsICIxOTEwOTkiXQ==",
"X-Received": "by 10.36.101.5 with SMTP id u5mr31628139itb.45.1480561936981; Wed, 30 Nov 2016 19:12:16 -0800 (PST)",
"X-Report-Abuse-To": "[email protected]"
}
Having the Base64Cleaner might be a good idea in many cases, but it can also be problematic, because "dirty" base64 can be used to obfuscate malware (see [1], where Step 4 does not produce a parsing error with enmime). Therefore, would it make sense to introduce a flag that allows to disable usage of the cleaner?
What I did:
Parsed eml from Step 4 on [1].
What I expected:
Parsing error (as the core base64 decoder would return)
What I got:
No parsing error
Release or branch I am using:
develop
[1] https://noxxi.de/research/mime-5-easy-steps-to-bypass-av.html
There is an RFC for email feedback reports with content type multipart/report - http://www.ietf.org/rfc/rfc5965.txt
Adding it here in case anyone else gets to it before me, there are a few examples in the RFC link above.
Normally the Epilogue is an area that should be left blank, and applications should ignore it, which enmime does.
These areas should generally be left blank, and implementations should ignore anything that appears before the first boundary or after the last one.
- rfc1341
Nevertheless, in real life things are not always according to standard. Epilogues are now used by spammers or attackers to insert malicious content into emails, this content comes in the form of other mime parts, these come right after the closing boundary of an email.
--B_3583309036_620884921--
This parts are displayed by email clients and when they come with a content disposition of inline for example, clients try execute or render the content.
Anyway. It would be nice to extend enmime in a way that it could perform beyond boundary mime parsing , after finding the "last" closing boundary. Perform a last check and search for other parseable content. Because when the parts are extracted to perform further analysis like malware analysis, the attachments on the epilogue are ignored and forwarded to the end user. And there is no way we can be aware of their existence before hand.
#37 should have had unit tests, but I don't want to hold up the PR queue
While writing Inbucket tests, I noticed that "
is leaking into address names.
Got: "Test of ศษฒสขศฏศกษชษดส" [email protected]
Want: Test of ศษฒสขศฏศกษชษดส [email protected]
Version: enmime v0.2.1
An enmime.Envelope is currently constructed from a net.mail.Message. The Go Message struct provides little benefit, and causes the head to be parsed by the built in ReadMIMEHeader() function before enmime has even seen the Message. This prevents enmime from working around malformed headers, like those in #2
enmime.Envelope should be built on-top of enmime.Part, and any missing functionality added to Part.
envelope.go:func parseBinaryOnlyBody doesn't copy headers like From, Subject, To, etc into its Root part.
What I did:
e, err := enmime.ReadEnvelope(email)
if err != nil {
return err
}
for _, a := range e.Attachments {
if a.ContentType == "message/rfc822" ||
(strings.HasSuffix(strings.ToLower(a.FileName), ".eml") && a.ContentType == "application/octet-stream") {
err := saveAttachment(a.Content)
if err != nil {
return err
}
return nil
}
}
What I expected:
a.Content
to be the full slice of bytes of the attachment
What I got:
just the body of the attached message without the headers, boundary...
Release or branch I am using:
origin/master
enmime needs to both encode and decode Content-ID headers
Package documentation in doc.go
does not mention MailBuilder and references functions that no longer exist.
Consider renaming to enmime.go
when updating.
I've integrated the repo with coveralls.io, so now we can see that test coverage is currently 66% (Dec 2016).
Fortunately, most of the enmime core code is well tested. The command line utilities, and I/O error related code paths are not. This should be easy to improve.
Recently I made a little test using following content with enmime
Content-Type: multipart/mixed; boundary="Enmime-Test-100"
--Enmime-Test-100
Content-Transfer-Encoding: base64
Content-Type: text/html; charset=utf-8
PGgxPlRlc3QhPC9oMT4K
--Enmime-Test-100
Content-Transfer-Encoding: base64
Content-Type: application/octet-stream; name="test.txt.gz"; charset="us-ascii"
Content-Disposition: attachment; filename=test.txt.gz
H4sICG2/PFoAA3Rlc3QudHh0ACtJLS7hAgDGNbk7BQAAAA==
--Enmime-Test-100--
As you can see, when I append a '=' to the html part's content PGgxPlRlc3QhPC9oMT4K
, it's a malformed base64 encoded string and will abort the work of enmime.Ok, I saved this modified content and opened it with macOS's Mail app, I also can get the correct attachment though the html part is displayed incorrecly.
Another example is, when I insert a speciall byte into fourth from the bottom of attachment's content like follows.
41 3D 3D A== -------> 11 41 3D 3D .A==
Obviously, it is also a malformed base64 encoded string, but it can be extracted with enmime .The key problem is the extracted file can't be uncompressed while extracted with another tools like Mail.app,Thunderbird and python's built-in package can be uncompressed correctly.
Inbucket needs to read message headers during delivery, but doesn't need to parse the entire message until somebody tried to view it.
Go's built in header parsing doesn't handle encoded headers. It would be nice if enmime could just parse the headers and return them.
Idea:
I thought about creating a Part field that would uniquely identify/order each Part inside the Envelope's MIME Tree.
This feature would give additional flexibility on how to handle Parts inside the Envelope. It could really be useful in future enhancements, especially in features related to Envelope editing.
Here is an example of a MIME Part Tree using the EnvelopeToMarkdown function from utils.go:
multipart/alternative
|-- text/plain
|-- multipart/related
| |-- text/html
| |-- image/png, disposition: inline, filename: "img3.png"
| |-- multipart/related
| | `-- text/html
| `-- image/png, disposition: inline, filename: "img3.png"
`-- image/png, disposition: inline, filename: "img3.png"
Let me illustrate on how this feature could prove itself to be useful:
A unique ID could differentiate the last attachment with file name "img3.png" from other attachments with similar file names.
We could directly read content from each Part using its unique PartID field. For text and HTML Parts, this would require an additional modification (cf. "Restore the Part's buffer after reading it's content" issue). We could also think about a function that edits the text/html parts.
We could think about creating a function which modifies the MIME Part Tree and creates a modified Envelope out of it.
For example, we would like to strip from the MIME Part Tree the first "multipart/related" content-type Part. This function would result in a new Envelope having such MIME Part Tree:
multipart/alternative
|-- text/plain
`-- image/png, disposition: inline, filename: "img3.png"
See this pull request for how this could be achieved: #35
In my proposition, the Parts' PartIDs will look as such:
multipart/alternative PartID = 0 (root)
|-- text/plain PartID = 1
|-- multipart/related PartID = 2.0 ("multipart/")
| |-- text/html PartID = 2.1
| |-- image/png, disposition: inline, filename: "img3.png" PartID = 2.2
| |-- multipart/related PartID = 2.3.0 ("multipart/")
| | `-- text/html PartID = 2.3.1
| `-- image/png, disposition: inline, filename: "img3.png" PartID = 2.4
`-- image/png, disposition: inline, filename: "img3.png" PartID = 3
Migrated from https://github.com/jhillyerd/go.enmime/issues/33 - by @astropanic
I'm not sure if this is an issue with this library itself or the message is malformed, but I get for certain emails this error message:
malformed MIME header line: name="7DDA4_foo_9E5D72.zip"
The culprit lies in:
Content-Type: application/x-zip-compressed; x-unix-mode=0600;
name="7DDA4_foo_9E5D72.zip"`
Which normally should be indented like:
Content-Type: application/x-zip-compressed; x-unix-mode=0600;
name="7DDA4_foo_9E5D72.zip"`
To reproduce, try this gist or:
check.go
package main
import (
"net/mail"
"os"
"github.com/jhillyerd/go.enmime"
)
func main() {
file, _ := os.Open("email.raw")
msg, err := mail.ReadMessage(file)
if err != nil {
panic(err)
}
_, err = enmime.ParseMIMEBody(msg)
if err != nil {
panic(err)
}
}
email.raw
From: Valarie Hunt <[email protected]>
Content-Type: multipart/mixed; boundary="Apple-Mail=_26553715-0747-B876-099A-AAD1243E4D6F"
X-Smtp-Server: 02840D23-670F-1769-17F2-5D55D55E2EA0
Subject: Requested receipt ID:9E5D72
Message-Id: <[email protected]>
X-Universally-Unique-Identifier: 21A69A4E-635C-1D67-F18B-29B96F28FE89
Date: Tue, 29 Mar 2016 05:54:31 -0500
To: foo <[email protected]>
Mime-Version: 1.0 (Mac OS X Mail 9.3 (3124))
--Apple-Mail=_26553715-0747-B876-099A-AAD1243E4D6F
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=utf-8
Dear foo,
Please find attached your receipt, sent as requested.
We are making improvements to our billing systems to help serve you =
better and because of that the attached invoice will look different from =
your previous ones.
Kind regards,
Valarie Hunt
VP Analytic Services
--Apple-Mail=_26553715-0747-B876-099A-AAD1243E4D6F
Content-Disposition: inline; filename="7DDA4_foo_9E5D72.zip"
Content-Type: application/x-zip-compressed; x-unix-mode=0600;
name="7DDA4_foo_9E5D72.zip"
Content-Transfer-Encoding: base64
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
--Apple-Mail=_26553715-0747-B876-099A-AAD1243E4D6F--
Do you plan take such "malformed" messages in account, and let them be readable by your library ?
Regards,
Wojciech
It would be be nice if you could list what RFCs this library supports :)
Part.AddChild
obsoletes the constructor.
What I did: Tried to parse email with video and manifest attachments from an exchange server
What I expected: I expected the attachments to parse
What I got: Failed to ReadParts: illegal base64 data at input byte 0
Release or branch I am using: master at bed8d3f
The payload is huge because the attachment is about 5MB; however, if it would help, I have no issue sending it to you. I have tried to figure out what is going on, but I haven't had much luck. If I send it from a non-exchange email source, it works fine. Any ideas on what might be going on? This is my first foray into email parsing, and not shockingly, Microsoft is making it horrible. Thanks for any help that you can provide.
func TestPartSetter in part_test.go is useless now that we don't use an interface, delete it.
Part should know how to write out itself, and call Encode() on it's child parts.
5.2. Content-Type Defaults
Default RFC 822 messages without a MIME Content-Type header are taken
by this protocol to be plain text in the US-ASCII character set,
which can be explicitly specified as:Content-type: text/plain; charset=us-ascii
This default is assumed if no Content-Type header field is specified.
It is also recommend that this default be assumed when a
syntactically invalid Content-Type header field is encountered. In
the presence of a MIME-Version header field and the absence of any
Content-Type header field, a receiving User Agent can also assume
that plain US-ASCII text was the sender's intent. Plain US-ASCII
text may still be assumed in the absence of a MIME-Version or the
presence of an syntactically invalid Content-Type header field, but
the sender's intent might have been otherwise.
Migrated from: https://github.com/jhillyerd/go.enmime/issues/35 - by @Lazyshot
A lot of the time we receive malformed e-mails from many sources, which leave us with a lot of errors coming out of parsing, but most of these are unreasonable in breaking the entire parsing process.
That is sometimes we care about particular errors but not others.
For example when parsing e-mails, we will sometimes get malformed e-mails where headers are empty on a part of a multipart message. Typically these are just empty boundaries, but can be a hindrance in parsing the entire e-mail. "Empty header at boundary" or "Missing Content-Type at boundary".
I was hoping we could create a solution that would allow for parsing to ignore certain errors or for the parsing to accumulate all the errors for us to discern which is important and which isn't without stopping all processing.
Golang's mime.FormatMediaType does not handle non-ASCII characters. PR #54 escapes non-ASCII characters with \u1234
notation.
RFC 2616 sec 2.2 does not define any special meaning for backslash quoted characters. In other applications I've seen non-ASCII characters converted to underscores for filenames, but I feel we can do better.
My suggestion is to remove all accent marks from alphabetic characters (ie ร -> A, รณ -> o), then convert any remaining non-ASCII characters to underscores.
It is parsed correctly by the email viewer, but the library does not parse correctly.
Return-Path: <[email protected]>
Received: from cleannexus.test.com ([192.168.179.132])
by mail.test.com (8.13.8/8.13.8) with ESMTP id w0M0ln2m020846;
Mon, 22 Jan 2018 09:47:49 +0900
Received: from naver.com (m12.directsend.co.kr [223.130.81.81])
by cleannexus.test.com (8.14.2/8.14.2) with ESMTP id w0M0eeui004746
for <[email protected]>; Mon, 22 Jan 2018 09:40:40 +0900
Date: Mon, 22 Jan 2018 09:40:40 +0900
Content-Type: multipart/alternative; boundary="--82be5ca2-6dee-48ed-b547-ff9b31858929"
MIME-Version: 1.0
Message-Id: <[email protected]>
From: =?UTF-8?B?67CV7J2A7Zic?= <[email protected]>
To: <[email protected]>
Subject: =?UTF-8?B?7IS46riI7J2AIO2YhOq4iCDsnbzsi5zrtojsnbjqsbAg64ukIOyVhOyLnOyjoD8g7KCI7IS466eMIOyEseqzte2VtOuPhCDtmITquIjsnYQg7KeA7YKsIOyImCDsnojsirXri4jri6Qu?=
----82be5ca2-6dee-48ed-b547-ff9b31858929
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
PGh0bWwgbGFuZz0ia28iPgo8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CgoJPGRpdiBpZD0iZHNfYm94IiBzdHlsZT0iZm9udC1mYW1pbHk6ICfrp5HsnYAg6rOg65SVJywn64KY64iUIOqzoOuUlScsZG90dW0sSGVsdmV0aWNhLHNhbnMtc2VyaWY7bGluZS1oZWlnaHQ6MS41O2ZvbnQtc2l6ZToxMnB4O2NvbG9yOiM2NjY7KndvcmQtYnJlYWs6YnJlYWstYWxsOy1tcy13b3JkLWJyZWFrOmJyZWFrLWFsbDtwYWRkaW5nOjBweCAxMHB4OyI+CgkKCQk8ZGl2IGNsYXNzPSJkc19hcnRpY2xlIiBzdHlsZT0iY2xlYXI6Ym90aDttYXJnaW46M2VtIDAiPgkKCQkJPHAgYWxpZ249Imp1c3RpZnkiIHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyBsaW5lLWhlaWdodDogMC41OyI+Jm5ic3A7PC9wPjxmb250IHNpemU9IjMiPjxwIHN0eWxlPSJsaW5lLWhlaWdodDogMC41OyI+PGJyPjwvcD48c3BhbiBzdHlsZT0iZm9udC1zaXplOiAxMnB0OyI+PHAgc3R5bGU9ImxpbmUtaGVpZ2h0OiAwLjU7Ij48YnI+PHRhYmxlIGNsYXNzPSJfX3NlX3RibCIgc3R5bGU9ImJvcmRlci13aWR0aDogMXB4IDFweCAwcHggMHB4OyBib3JkZXItc3R5bGU6IHNvbGlkIHNvbGlkIG5vbmUgbm9uZTsgYm9yZGVyLWNvbG9yOiByZ2IoMjA0LCAyMDQsIDIwNCkgcmdiKDIwNCwgMjA0LCAyMDQpIGN1cnJlbnRDb2xvciBjdXJyZW50Q29sb3I7IGJvcmRlci1pbWFnZTogbm9uZTsiIGJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nP!
SIwIj48dGJvZHk+PHRyPjx0ZCBzdHlsZT0iYm9yZGVyLXdpZHRoOiAwcHggMHB4IDFweCAxcHg7IGJvcmRlci1zdHlsZTogbm9uZSBub25lIHNvbGlkIHNvbGlkOyBib3JkZXItY29sb3I6IGN1cnJlbnRDb2xvciBjdXJyZW50Q29sb3IgcmdiKDIwNCwgMjA0LCAyMDQpIHJnYigyMDQsIDIwNCwgMjA0KTsgYm9yZGVyLWltYWdlOiBub25lOyB3aWR0aDogODY0cHg7IGhlaWdodDogMTg3MHB4OyBiYWNrZ3JvdW5kLWNvbG9yOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48cD48c3Ryb25nPjwvc3Ryb25nPjwvcD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48c3Ryb25nPjxicj48L3N0cm9uZz4mbmJzcDs8c3BhbiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsiPuyghOyekOqysOygnOyImOuLqOydmCDrsJzri6zroZwg7ZmI7Ie87ZWRLCZuYnNwO+yduO2EsOuEt+yHvO2VkSwg7Iud64u5IOyWtOuKkOqzs+ydtOuToCZuYnNwO+qzoOyVoeydmCDrjIDquIjrj4Qg66ek64usIO2VoOu2gOuhnCDqs4TsgrDsnbQg6rCA64ql7ZWcIOyLnOuMgOyeheuLiOuLpC4g6riw7JeF65Ok7J2AJm5ic3A76rOg6rCd7Li17J2YIOuLpOyWke2VnCDqtazrp6QmbmJzcDvsmIjsgrDsl5Ag64yA7J2R7ZWY6rOg7J6QIOqysOygnCDsobDqsbTqs7wg6rKw7KCcIOyImOuLqOydhCDri6Trs4DtmZTtlZjsl6wg66ek7Lac7J2EIOq3ueuMgO2ZlCDtlZjquLAg7JyE7ZW0IOunjuydgCDruYTsmqnsnYQg7KeA6!
7aI7ZWY66mwIOuFuOugpe2VmOqzoCDsnojsirXri4jri6QuJm5ic3A77ZWA7YWM7YGsIOq4sOyIoOydmCDrsJzri6zroZwg6rCB7KKFIO2OmOydtOuTpOqzvCDsmpTsppgmbmJzcDvsgqztmozsoIEg66y47KCc66GcIOq4iSDrtoDsg4HtlZjqs6Ag7J6I64qUIOqwgOyDge2ZlO2PkOyZgCDqsJnsnYAmbmJzcDvsp4Drtogg7IiY64uo7J20Jm5ic3A77IOd6rmA7Jy866GcJm5ic3A76riw7JeF7J2AIO2VreyDgSDshozruYTsnpDrk6TsnZgg64uI7KaI66W8IOyVnuyEnOqwgOqzoCDsnojsirXri4jri6QuPC9zcGFuPjwvcD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48YnI+PC9wPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0idGV4dC1hbGlnbjogbGVmdDsiPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDApOyI+Jm5ic3A76re465+s64KYIOyghCDqta3rr7zsnYQg64yA7IOB7Jy866GcIO2VmOuKlCZuYnNwO+yEuOq4iCDrgqnrtoDripQmbmJzcDvsnbTrn7Ag7ZiE7Iuk7JeQ7IScIOyYiOyZuOqwgCDslYTri5Ag7IiYIOyXhuyKteuLiOuLpC4g7KCV67aA64qUIOqzvOyEuCDsnqzsm5Ag7ZmV7Lap7JeQ66eMIOyXtOydhCDsmKzrpqzqs6Ag7IS46riIIOuCqeu2gCDrsKnsi53snYAg7IiY7Iut64WE7J20IOyngOuCmOuPhCDri6zrnbzsp4Dsp4Ag7JWK7JWY7Iq164uI64ukLiDstZzqt7zrk6TslrQg7Iug7Jqp7Lm065Oc66GcIOuCqeu2gOqwgCDqsIDriqXtlbTsoYzri6Tqs6DripQg7ZWY7KeA66eMIDEl64KYIOuQmOuKlCZuYnNwO+y5tOuTnCDsiJjsiJjro4wg65iQ!
7ZWcJm5ic3A764Kp7IS47J6Q7J2YIOu2gOuLtOyduCDsoJDsnYQg6rOg66Ck7ZWY66m0IOydtOuKlCA8c3Ryb25nPuqwgOyCsOyEuOyZgCDri6TrpoQg7JeG64qUIOu2iOydtOydtTwvc3Ryb25nPuydtOudvCDrs7wg7IiYIOyeiOyKteuLiOuLpC4g7J2067+Q66eMIOyVhOuLiOudvCZuYnNwO+qwgeyihSDshLjslaEg6rCQ66m0IOuTsSDsobDshLgg7Zic7YOd7J2AIDxzdHJvbmc+67O17J6h7ZWcIOyalOqxtDwvc3Ryb25nPuydhCDqtazruYTtlbTslbzrp4wg7KCB7Jqp67Cb7J2EIOyImCDsnojslrQg7KCV67aA64qUIOuCqeyEuOyekOuTpOyXkOuKlCDqsrDsvZQg7Lmc7KCI7ZWY7KeAIOyViuydgCDtmITsi6TsnoXri4jri6QuPC9zcGFuPjwvcD48cD48YnI+PC9wPjxwIGFsaWduPSJqdXN0aWZ5IiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPjwvcD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48Zm9udCBzaXplPSIzIj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsgZm9udC1zaXplOiAxMnB0OyI+Jm5ic3A7PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7Ij4yMDE464WEIOyYrO2VtOuPhCDshozrk53shLjrspXsnbQg7JWE656Y7JmAIOqwmeydtCDqsJzsoJXrkJjslrQg6riw7JeFIOuwjyBDRU/qu5jshJzripQg67mg66W4IOuMgOu5hOulvCDtlZjshZTslbwg7IaM7KSR7ZWcIOyerOyCsOydhCDsp4Dtgqwg7IiYIOyeiOyKteuLiOuLpC48!
L3NwYW4+PC9zcGFuPjwvZm9udD48L3A+PHAgYWxpZ249Imp1c3RpZnkiIHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyBsaW5lLWhlaWdodDogMC41OyI+PGZvbnQgc2l6ZT0iMyI+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7IGZvbnQtc2l6ZTogMTJwdDsiPuKAizwvc3Bhbj48L2ZvbnQ+PGJyPjwvcD48Zm9udCBzaXplPSIzIj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsgZm9udC1zaXplOiAxMnB0OyI+PHAgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxzdHJvbmc+Jmx0OzIwMTjrhYQg6rCc7KCVIOyEuOycqOqzvCDsho3sgrDtkZwmZ3Q7Jm5ic3A7PC9zdHJvbmc+PC9wPjwvc3Bhbj48L2ZvbnQ+PGZvbnQgc2l6ZT0iMyI+PHAgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxpbWcgd2lkdGg9IjkwMSIgaGVpZ2h0PSI0NzciIGNsYXNzPSJ0eGMtaW1hZ2UiIHN0eWxlPSJ3aWR0aDogNTE2cHg7IGhlaWdodDogMjc4cHg7IGNsZWFyOiBub25lOyBmbG9hdDogbm9uZTsiIHNyYz0iaHR0cHM6Ly9kaXJlY3RzZW5kLmNvLmtyL3VwbG9hZF9pbWFnZXMvMTUxNjE1MDEwNGJmYWM4M2QyNDNmNTc3NGQyNDEyZDllNjlkZDNhM2Y4LmpwZyI+PC9wPjxkaXYgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjwvZGl2PjxwPjwvcD48L2ZvbnQ+PGZvbnQgc2l6ZT0iMyI+PHAgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxzcGFuIHN0eWxlPSJjb2xvcjo!
gcmdiKDAsIDAsIDApOyBmb250LXNpemU6IDlwdDsiPmV4KSDsho3sgrDtkZwg6rOE7IKwIOuwqeuylTxicj48L3NwYW4+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7IGZvbnQtc2l6ZTogOXB0OyI+LSDshozrk53snbQgNeyynOunjOybkOyduCDqsr3smrAgOiA17LKc66eM7JuQIFggMjQlIC0gNTIy66eM7JuQID0gNjc466eM7JuQPC9zcGFuPjxzcGFuPjxicj48L3NwYW4+PHNwYW4+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7IGZvbnQtc2l6ZTogOXB0OyI+LSDshozrk53snbQgMeyWtSA47LKc66eM7JuQ7J24IOqyveyasCA6IDHslrU47LKc66eM7JuQIFggMzglIC0gMSw5NDDrp4zsm5AgPSA0LDkwMOunjOybkDwvc3Bhbj48YnI+PC9zcGFuPjxzcGFuPjxicj48L3NwYW4+PC9wPjwvZm9udD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48Zm9udCBzaXplPSIzIj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsgZm9udC1zaXplOiAxMnB0OyI+Jm5ic3A7PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7Ij7qsJzsoJUg7IaM65Od7IS467KV7J2AIOyLoOyEpOuQmOuKlCDstZzqs6Ag7IS47Jyo6rO8IOuIhOynhCDqtazqsITsnZgg7LaU6rCA66GcJm5ic3A76rOg7IaM65Od7J6Q7JeQ6rKM64qUIOyEuOu2gOuLtOydtCDrjZTsmrEg6rCA7KSR65CY7JeI7Iq164uI64ukLiDtirntnogg7KSR7IaM6riw7JeF7J2YIENFT+q7mOy!
EnOuKlCDtj4nqt6Drs7Tri6Qg64aS7J2AIOyImOykgOydmCDshozrk53snYQmbmJzcDvsp4DquInrsJvqs6Ag6rOE7Iuc6riw7JeQIOyEuOuylSDqsJzsoJUg7IKs7ZWt7J2YIOyYge2WpeydhCDrp47snbQg67Cb7J2EIOyImCDrsJbsl5Ag7JeG7Iq164uI64ukLiZuYnNwOyZuYnNwO+q3vOuhnOyGjOuTneydtCDrp47snYzsl5Drj4QmbmJzcDvshLjrspXsg4Eg6rO17KCc7JWh7J2AIO2EsOustOuLiCDsl4bsnbQg7KCB7Ja0IOyGjOuTneyEuOyZgCDso7zrr7zshLjrpbwg7Y+s7ZWo7ZWY66m0IOyGjOuTneydmCDqsbDsnZggPHN0cm9uZz7soIjrsJjsl5Ag6rCA6rmM7Jq0IOq4iOyVoeydhCDshLjquIg8L3N0cm9uZz7snLzroZwg64Kp67aA7ZW07JW8IO2VmOuKlCDsi5zrjIDqsIAg64+E656Y7ZWY7JiA7Iq164uI64ukLiA8L3NwYW4+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7IGZvbnQtc2l6ZTogMTBwdDsiPijqt7zroZzshozrk50gMeyWteybkCDstIjqs7zsi5wg6rO17KCc7JyoIDIlKTwvc3Bhbj48L3NwYW4+PC9mb250PjwvcD48Zm9udCBzaXplPSIzIj48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48YnI+PC9wPjwvZm9udD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48Zm9udCBzaXplPSIzIj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsiPiZuYnNwO+yggO2drCDtlLzsoJzsnbTsu6jshKTtjIXsl5DshJzripQg6rOg7IaM65OdIENFT+u2hOuTpOydmCDsoIjshLgg64+E7Jqw66+466GcIOuCmOyEnC!
A8c3Ryb25nPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDI1NSwgMCwgMCk7Ij7qt7zroZzshozrk53qs7wg67mE6rWQ7ZWY66m0IDgwJSDsoIjqsJA8L3NwYW4+PC9zdHJvbmc+65CcIOygiOyEuCDshJzruYTsiqTrpbwg7KCc6rO17ZW0IOuTnOumrOqzoOyekCDtlanri4jri6QuIO2YhOq4iCDsnbzsi5zrtogg64Kp67aA66W8IOybkOy5meycvOuhnCDtlZjripQg7IS46riI64Kp67aA64qUIOygiOyEuOunjCDshLHqs7XtlZjsl6zrj4Qg7JeE7LKt64KcIO2YhOq4iO2dkOumhCDqsJzshKDtmqjqs7zrpbwg6rCA7KC47Jio64uk6rOgIO2VoCDsiJgg7J6I7Iq164uI64ukLiDsi6TsoJzroZwg7IiY66eO7J2AIENFT+q7mOyEnOuPhCDtlLzsoJzsnbTsu6jshKTtjIXsnZgg7KCI7IS4IOyEnOu5hOyKpOuhnCZuYnNwO+2BsCDrp4zsobHsnYQg7Ja76rOgIOqzhOyLreuLiOuLpC48L3NwYW4+PC9mb250PjwvcD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48YnI+PC9wPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0idGV4dC1hbGlnbjogbGVmdDsiPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDApOyI+Jm5ic3A7PHN0cm9uZz7tlLzsoJzsnbTsu6jshKTtjIU8L3N0cm9uZz7snZggPC9zcGFuPjxzdHJvbmc+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7Ij7tirntl4jsnpDrs7jtmZQ8L3NwYW4+PC9zdHJvbmc+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMC!
k7Ij7rnbwg67aI66as64qUIOyCsOyXheyerOyCsOq2jOydhCDtmZzsmqntlZwmbmJzcDvsu6jshKTtjIXsnYAmbmJzcDvqt7zroZzshozrk53shLjsnZggMjAl67CW7JeQIOyViOuQmOuKlCDshLjquIjsnLzroZwgQ0VP7J2YJm5ic3A77ZmV7Iuk7ZWcIOygiOyEuCDrj4TsmrDrr7jroZwg7J6Q66as66ek6rmA7ZWY7JiA7Iq164uI64ukLiDslYTrnpjsnZgg7ZGc64qUIOyGjOuTnSDrtoTrpZjsl5Ag65Sw66W4IOyEuOq4iCDrgqnrtoDslaEg67mE6rWQ7J6F64uI64ukLiZuYnNwOzwvc3Bhbj48L3A+PHNwYW4+PHAgYWxpZ249Imp1c3RpZnkiIHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+PGJyPjwvcD48cCBhbGlnbj0iY2VudGVyIiBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyI+PGltZyB3aWR0aD0iNzk5IiBoZWlnaHQ9IjMzOCIgY2xhc3M9InR4Yy1pbWFnZSIgc3R5bGU9IndpZHRoOiA2MTlweDsgaGVpZ2h0OiAyNDlweDsgY2xlYXI6IG5vbmU7IGZsb2F0OiBub25lOyIgc3JjPSJodHRwczovL2RpcmVjdHNlbmQuY28ua3IvdXBsb2FkX2ltYWdlcy8xNTE2MTgzOTkyNmI1NmUzNDg2YTNmOTIyYWIzOTAyYjg0MzZlMzQyYjAuanBnIj48ZGl2IGFsaWduPSJjZW50ZXIiIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij48L2Rpdj48cD48L3A+PHAgYWxpZ249Imp1c3RpZnkiIHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+PGJyPjwvcD48cD48L3A+PC9zcGFuPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0idGV4dC1hbGlnbjogbGVmdDsiPiZuYnNwOzxzcGFuIHN0eWxlPSJjb2xvcjogc!
mdiKDAsIDAsIDApOyI+7ZGc7JeQIOydmO2VmOuptCZuYnNwO+qwmeydgCAxMOyWteybkOydmCDshozrk53snbQg67Cc7IOd7ZWY7JiA7Ja064+EIOyGjOuTneydmCDsooXrpZjsl5Ag65Sw6528IOyLpOyImOugueyVoeydgCA8c3Ryb25nPjPslrXsm5A8L3N0cm9uZz4g7J207IOBJm5ic3A77LCo7J206rCAIOuCqeuLiOuLpC4g66ek64WEIOqzoOycqOydmCDshLjquIjrtoDri7TsnYQg7IiY67CY7ZWY64qUIOq3vOuhnOyGjOuTneqzvCDrsLDri7nquIgg7J247LacIOuMgOyLoOyXkCDtlLzsoJzsnbTsu6jshKTtjIXsnZggPC9zcGFuPjxzdHJvbmc+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7Ij7tirntl4jsnpDrs7jtmZQ8L3NwYW4+PC9zdHJvbmc+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7Ij7rpbwg6rK97ZeY7ZWY7Iuc7Ja0Jm5ic3A77IiY7LKc66eM7JuQIOuCtOyngCA8c3Ryb25nPuyImOyWteybkOydmCDsoIjshLjtmqjqs7w8L3N0cm9uZz7smYAg64+Z7Iuc7JeQIOq4sOyXheydmCDquLDsiKDroKXrj4Qg7ZmV67O07ZWY7Iuc64qUIDIwMTjrhYTrj4Qg7ZWc7ZW06rCAIOuQmOyLnOq4uCDrsJTrno3ri4jri6QuIDwvc3Bhbj48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48YnI+PC9wPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0idGV4dC1hbGlnbjogbGVmdDsiPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDApOyI+642UIOyekOyEu!
O2VnCDsgqztla3snYAg7JWE656Y7J2YIOyXsOudveyymOuhnCDrrLjsnZgg7KO87Iuc66m0IOu5oOuluCDsi5zsnbzrgrTsl5Ag67Cp66y4IOyDgeuLtCDrk5zrpqzqsqDsirXri4jri6QuJm5ic3A7PC9zcGFuPjxwPjwvcD48cCBzdHlsZT0idGV4dC1hbGlnbjogbGVmdDsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPiZuYnNwOzwvZm9udD48c3BhbiBsYW5nPSJFTi1VUyIgc3R5bGU9ImNvbG9yOiBibGFjazsgZm9udC1zaXplOiAxMnB0OyBtc28tYmlkaS1mb250LWZhbWlseTogQXJpYWw7IG1zby1hc2NpaS1mb250LWZhbWlseTog66eR7J2AIOqzoOuUlTsgbXNvLWFzY2lpLXRoZW1lLWZvbnQ6IG1pbm9yLWZhcmVhc3Q7IG1zby1oYW5zaS1mb250LWZhbWlseTog66eR7J2AIOqzoOuUlTsgbXNvLWhhbnNpLXRoZW1lLWZvbnQ6IG1pbm9yLWZhcmVhc3Q7IG1zby1mb250LWtlcm5pbmc6IDBwdDsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPiZuYnNwOzwvZm9udD48L3NwYW4+PHNwYW4gbGFuZz0iRU4tVVMiIHN0eWxlPSJjb2xvcjogYmxhY2s7IG1zby1iaWRpLWZvbnQtZmFtaWx5OiBBcmlhbDsgbXNvLWFzY2lpLWZvbnQtZmFtaWx5OiDrp5HsnYAg6rOg65SVOyBtc28tYXNjaWktdGhlbWUtZm9udDogbWlub3ItZmFyZWFzdDsgbXNvLWhhbnNpLWZvbnQtZmFtaWx5OiDrp5HsnYAg6rOg65SVOyBtc28taGFuc2ktdGhlbWUtZm9udDogbWlub3ItZmFyZWFzdDsgbXNvLWZvbnQta2VybmluZzogMHB0OyBtc28tYmlkaS1mb250LXNpemU6IDEwLjBwdDsiPjxmb250IGZhY2U9IuunkeydgCDq!
s6DrlJUiPiZuYnNwOzwvZm9udD48L3NwYW4+PC9wPjxwPjwvcD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9ImJhY2tncm91bmQ6IHdoaXRlOyBtYXJnaW46IDBjbSAyNy4xcHQgMHB0IDBjbTsgdGV4dC1hbGlnbjogbGVmdDsgbGluZS1oZWlnaHQ6IG5vcm1hbDsgLW1zLXdvcmQtYnJlYWs6IGtlZXAtYWxsOyBtc28tcGFnaW5hdGlvbjogd2lkb3ctb3JwaGFuOyBtc28tcGFyYS1tYXJnaW4tdG9wOiAwY207IG1zby1wYXJhLW1hcmdpbi1yaWdodDogMi43MWdkOyBtc28tcGFyYS1tYXJnaW4tYm90dG9tOiAuMDAwMXB0OyBtc28tcGFyYS1tYXJnaW4tbGVmdDogMGNtOyI+PGZvbnQgZmFjZT0i66eR7J2AIOqzoOuUlSI+PHNwYW4gbGFuZz0iRU4tVVMiIHN0eWxlPSJjb2xvcjogYmxhY2s7IGZvbnQtc2l6ZTogMTFwdDsgbXNvLWJpZGktZm9udC1mYW1pbHk6IEFyaWFsOyBtc28tYXNjaWktZm9udC1mYW1pbHk6IOunkeydgCDqs6DrlJU7IG1zby1hc2NpaS10aGVtZS1mb250OiBtaW5vci1mYXJlYXN0OyBtc28taGFuc2ktZm9udC1mYW1pbHk6IOunkeydgCDqs6DrlJU7IG1zby1oYW5zaS10aGVtZS1mb250OiBtaW5vci1mYXJlYXN0OyBtc28tZm9udC1rZXJuaW5nOiAwcHQ7IG1zby1iaWRpLWZvbnQtc2l6ZTogMTIuMHB0OyI+PHN0cm9uZz5QSkNvbnN1bHRpbmcgKDwvc3Ryb25nPjxzdHJvbmc+IDwvc3Ryb25nPjxhIGhyZWY9Imh0dHBzOi8vZGlyZWN0c2VuZC5jby5rci9pbmRleC5waHAvbWFpbF9yZXBvcnRf!
YXBpL2NsaWNrLzEwMjQ2NzUvYUhSMGNEb3ZMM2QzZHk1d2FtTnZibk4xYkhScGJtY3VibVYwTHcvMjYyNzA3NDI0L21rdEBjb210cnVlLmNvbS8xIiB0YXJnZXQ9Il9ibGFuayI+PHN0cm9uZz5odHRwOi8vd3d3LnBqY29uc3VsdGluZy5uZXQ8L3N0cm9uZz48L2E+Jm5ic3A7KTwvc3Bhbj48L2ZvbnQ+PC9wPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0iYmFja2dyb3VuZDogd2hpdGU7IG1hcmdpbjogMGNtIDI3LjFwdCAwcHQgMGNtOyB0ZXh0LWFsaWduOiBsZWZ0OyBsaW5lLWhlaWdodDogbm9ybWFsOyAtbXMtd29yZC1icmVhazoga2VlcC1hbGw7IG1zby1wYWdpbmF0aW9uOiB3aWRvdy1vcnBoYW47IG1zby1wYXJhLW1hcmdpbi10b3A6IDBjbTsgbXNvLXBhcmEtbWFyZ2luLXJpZ2h0OiAyLjcxZ2Q7IG1zby1wYXJhLW1hcmdpbi1ib3R0b206IC4wMDAxcHQ7IG1zby1wYXJhLW1hcmdpbi1sZWZ0OiAwY207Ij48Zm9udCBmYWNlPSLrp5HsnYAg6rOg65SVIj48YiBzdHlsZT0ibXNvLWJpZGktZm9udC13ZWlnaHQ6IG5vcm1hbDsiPjxzcGFuIGxhbmc9IkVOLVVTIiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsgZm9udC1zaXplOiAxMXB0OyBtc28tYmlkaS1mb250LWZhbWlseTogQXJpYWw7IG1zby1hc2NpaS1mb250LWZhbWlseTog66eR7J2AIOqzoOuUlTsgbXNvLWFzY2lpLXRoZW1lLWZvbnQ6IG1pbm9yLWZhcmVhc3Q7IG1zby1oYW5zaS1mb250LWZhbWlseTog66eR7J2AIOqzoOuUlTsgbXNvLWhhbnNpLXRoZW1lLWZvbnQ6IG1pbm9yLWZhcmVhc3Q7IG1zby1mb250LWtlcm5pbmc6IDBwdDsgbXN!
vLWJpZGktZm9udC1zaXplOiAxMi4wcHQ7Ij7shJzsmrjtirnrs4Tsi5wg6rCV64Ko6rWsIO2FjO2XpOuegOuhnDgy6ri4IDE1ICjrjIDsuZjrj5ksIOuUlOyVhOydtO2DgOybjCk5NzTtmLg8L3NwYW4+PC9iPjwvZm9udD48L3A+PHAgYWxpZ249ImxlZnQiIHN0eWxlPSJiYWNrZ3JvdW5kOiB3aGl0ZTsgbWFyZ2luOiAwY20gMjcuMXB0IDBwdCAwY207IHRleHQtYWxpZ246IGxlZnQ7IGxpbmUtaGVpZ2h0OiBub3JtYWw7IC1tcy13b3JkLWJyZWFrOiBrZWVwLWFsbDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhhbjsgbXNvLXBhcmEtbWFyZ2luLXRvcDogMGNtOyBtc28tcGFyYS1tYXJnaW4tcmlnaHQ6IDIuNzFnZDsgbXNvLXBhcmEtbWFyZ2luLWJvdHRvbTogLjAwMDFwdDsgbXNvLXBhcmEtbWFyZ2luLWxlZnQ6IDBjbTsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPjxiIHN0eWxlPSJtc28tYmlkaS1mb250LXdlaWdodDogbm9ybWFsOyI+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7IGZvbnQtc2l6ZTogMTFwdDsiPlRFTC4gMDItNTAxLTcyNDQmbmJzcDsmbmJzcDsmbmJzcDsgRkFYLiAwNTAtNDM4OS05NDE2PC9zcGFuPjwvYj48L2ZvbnQ+PC9wPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0iYmFja2dyb3VuZDogd2hpdGU7IG1hcmdpbjogMGNtIDI3LjFwdCAwcHQgMGNtOyB0ZXh0LWFsaWduOiBsZWZ0OyBsaW5lLWhlaWdodDogbm9ybWFsOyAtbXMtd29yZC1icmVhazoga2VlcC1hbGw!
7IG1zby1wYWdpbmF0aW9uOiB3aWRvdy1vcnBoYW47IG1zby1wYXJhLW1hcmdpbi10b3A6IDBjbTsgbXNvLXBhcmEtbWFyZ2luLXJpZ2h0OiAyLjcxZ2Q7IG1zby1wYXJhLW1hcmdpbi1ib3R0b206IC4wMDAxcHQ7IG1zby1wYXJhLW1hcmdpbi1sZWZ0OiAwY207Ij48Zm9udCBmYWNlPSLrp5HsnYAg6rOg65SVIj48YiBzdHlsZT0ibXNvLWJpZGktZm9udC13ZWlnaHQ6IG5vcm1hbDsiPjxzcGFuIGxhbmc9IkVOLVVTIiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsgZm9udC1zaXplOiAxMXB0OyBtc28tYmlkaS1mb250LWZhbWlseTogQXJpYWw7IG1zby1hc2NpaS1mb250LWZhbWlseTog66eR7J2AIOqzoOuUlTsgbXNvLWFzY2lpLXRoZW1lLWZvbnQ6IG1pbm9yLWZhcmVhc3Q7IG1zby1oYW5zaS1mb250LWZhbWlseTog66eR7J2AIOqzoOuUlTsgbXNvLWhhbnNpLXRoZW1lLWZvbnQ6IG1pbm9yLWZhcmVhc3Q7IG1zby1mb250LWtlcm5pbmc6IDBwdDsgbXNvLWJpZGktZm9udC1zaXplOiAxMi4wcHQ7Ij5Nb2JpbGUuIDAxMC01ODEyLTEzMTIgLCAwMTAtMjAxOS0yODMxPC9zcGFuPjwvYj48L2ZvbnQ+PC9wPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0iYmFja2dyb3VuZDogd2hpdGU7IG1hcmdpbjogMGNtIDI3LjFwdCAwcHQgMGNtOyB0ZXh0LWFsaWduOiBsZWZ0OyBsaW5lLWhlaWdodDogbm9ybWFsOyAtbXMtd29yZC1icmVhazoga2VlcC1hbGw7IG1zby1wYWdpbmF0aW9uOiB3aWRvdy1vcnBoYW47IG1zby1wYXJhLW1hcmdpbi10b3A6IDBjbTsgbXNvLXBhcmEtbWFyZ2luLXJpZ2h0OiAyLjcxZ2Q7IG!
1zby1wYXJhLW1hcmdpbi1ib3R0b206IC4wMDAxcHQ7IG1zby1wYXJhLW1hcmdpbi1sZWZ0OiAwY207Ij48Zm9udCBmYWNlPSLrp5HsnYAg6rOg65SVIj48YiBzdHlsZT0ibXNvLWJpZGktZm9udC13ZWlnaHQ6IG5vcm1hbDsiPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDApOyBmb250LXNpemU6IDExcHQ7Ij5FLW1haWwuIHBqY29uc3VsdGluZ0DrhKTsnbTrsoTrqZTsnbw8L3NwYW4+PC9iPjwvZm9udD48L3A+PHAgYWxpZ249ImxlZnQiIHN0eWxlPSJiYWNrZ3JvdW5kOiB3aGl0ZTsgbWFyZ2luOiAwY20gMjcuMXB0IDBwdCAwY207IHRleHQtYWxpZ246IGxlZnQ7IGxpbmUtaGVpZ2h0OiBub3JtYWw7IC1tcy13b3JkLWJyZWFrOiBrZWVwLWFsbDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhhbjsgbXNvLXBhcmEtbWFyZ2luLXRvcDogMGNtOyBtc28tcGFyYS1tYXJnaW4tcmlnaHQ6IDIuNzFnZDsgbXNvLXBhcmEtbWFyZ2luLWJvdHRvbTogLjAwMDFwdDsgbXNvLXBhcmEtbWFyZ2luLWxlZnQ6IDBjbTsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6IDExcHQ7Ij48c3Ryb25nPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDApOyI+4oCLQmxvZy4gPC9zcGFuPjwvc3Ryb25nPjxhIGhyZWY9Imh0dHBzOi8vZGlyZWN0c2VuZC5jby5rci9pbmRleC5waHAvbWFpbF9yZXBvcnRfYXBpL2NsaWNrLzEwMjQ2NzUvYUhSMGNEb3ZMMkpzYjJjdWJtRj!
JaWEl1WTI5dEwzQnFZMjl1YzNWc2RHbHVady8yNjI3MDc0MjQvbWt0QGNvbXRydWUuY29tLzIiIHRhcmdldD0iX2JsYW5rIj48c3Ryb25nPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDApOyI+aHR0cDovL2Jsb2cubmF2ZXIuY29tL3BqY29uc3VsdGluZzwvc3Bhbj48L3N0cm9uZz48L2E+PC9zcGFuPjwvZm9udD48L3A+PHAgYWxpZ249ImxlZnQiIHN0eWxlPSJiYWNrZ3JvdW5kOiB3aGl0ZTsgbWFyZ2luOiAwY20gMjcuMXB0IDBwdCAwY207IHRleHQtYWxpZ246IGxlZnQ7IGxpbmUtaGVpZ2h0OiBub3JtYWw7IC1tcy13b3JkLWJyZWFrOiBrZWVwLWFsbDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhhbjsgbXNvLXBhcmEtbWFyZ2luLXRvcDogMGNtOyBtc28tcGFyYS1tYXJnaW4tcmlnaHQ6IDIuNzFnZDsgbXNvLXBhcmEtbWFyZ2luLWJvdHRvbTogLjAwMDFwdDsgbXNvLXBhcmEtbWFyZ2luLWxlZnQ6IDBjbTsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6IDExcHQ7Ij48YnI+PC9zcGFuPjwvZm9udD48L3A+PHAgYWxpZ249ImxlZnQiIHN0eWxlPSJiYWNrZ3JvdW5kOiB3aGl0ZTsgbWFyZ2luOiAwY20gMjcuMXB0IDBwdCAwY207IHRleHQtYWxpZ246IGxlZnQ7IGxpbmUtaGVpZ2h0OiBub3JtYWw7IC1tcy13b3JkLWJyZWFrOiBrZWVwLWFsbDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhhbjsgbXNvLXBhcmEtbWFyZ2luLXRvcDogMGNtOyBtc28tcGFyYS1tYXJnaW4tcmlnaHQ6IDIuNzFnZDsgbXNvLXBhcmEtbWFyZ2luLWJvdHRvb!
TogLjAwMDFwdDsgbXNvLXBhcmEtbWFyZ2luLWxlZnQ6IDBjbTsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6IDExcHQ7Ij48dT48L3U+PC9zcGFuPjwvZm9udD48cCBhbGlnbj0iY2VudGVyIiBzdHlsZT0idGV4dC1hbGlnbjogbGVmdDsiPjxicj48L3A+PGZvbnQgZmFjZT0i66eR7J2AIOqzoOuUlSI+PHAgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48L3A+PHU+PHAgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxpbWcgd2lkdGg9IjEyOTciIGhlaWdodD0iNjcwIiBjbGFzcz0idHhjLWltYWdlIiBzdHlsZT0id2lkdGg6IDU0MnB4OyBoZWlnaHQ6IDI3NnB4OyBjbGVhcjogbm9uZTsgZmxvYXQ6IG5vbmU7IiBzcmM9Imh0dHBzOi8vZGlyZWN0c2VuZC5jby5rci91cGxvYWRfaW1hZ2VzLzE1MTQ4MTkwNzlhZjcxOTg4NDM5MDdjNDYwNmI4ZDEwNWNmOThlNmI5Zi5wbmciPjxkaXYgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjwvZGl2PjxwPjwvcD48L3U+PC9mb250PjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBsZWZ0OyI+PGZvbnQgZmFjZT0i66eR7J2AIOqzoOuUlSI+PHU+IDwvdT48L2ZvbnQ+PC9wPjxwPjwvcD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9ImJhY2tncm91bmQ6IHdoaXRlOyBtYXJnaW46IDBjbSAyNy4xcHQgMHB0IDBjbTsgdGV4dC1hbGlnbjogbGVmdDsgb!
GluZS1oZWlnaHQ6IG5vcm1hbDsgLW1zLXdvcmQtYnJlYWs6IGtlZXAtYWxsOyBtc28tcGFnaW5hdGlvbjogd2lkb3ctb3JwaGFuOyBtc28tcGFyYS1tYXJnaW4tdG9wOiAwY207IG1zby1wYXJhLW1hcmdpbi1yaWdodDogMi43MWdkOyBtc28tcGFyYS1tYXJnaW4tYm90dG9tOiAuMDAwMXB0OyBtc28tcGFyYS1tYXJnaW4tbGVmdDogMGNtOyI+PGZvbnQgZmFjZT0i66eR7J2AIOqzoOuUlSI+PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZTogMTFwdDsiPjx1Pjxicj48L3U+PC9zcGFuPjwvZm9udD48L3A+PHAgYWxpZ249ImxlZnQiIHN0eWxlPSJiYWNrZ3JvdW5kOiB3aGl0ZTsgbWFyZ2luOiAwY20gMjcuMXB0IDBwdCAwY207IHRleHQtYWxpZ246IGxlZnQ7IGxpbmUtaGVpZ2h0OiAwLjU7IC1tcy13b3JkLWJyZWFrOiBrZWVwLWFsbDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhhbjsgbXNvLXBhcmEtbWFyZ2luLXRvcDogMGNtOyBtc28tcGFyYS1tYXJnaW4tcmlnaHQ6IDIuNzFnZDsgbXNvLXBhcmEtbWFyZ2luLWJvdHRvbTogLjAwMDFwdDsgbXNvLXBhcmEtbWFyZ2luLWxlZnQ6IDBjbTsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyA8L2ZvbnQ+PC9wPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPjxwIGFsaWduPSJjZW50ZXIiIHN0eWxlPSJiYWNrZ3JvdW5kOiB3aGl0ZTsgbWFyZ2luOiAwY20gMjcuMXB0IDBwdCAwY207IHRleHQtYWxpZ246IGNlbnRlcjsgbGluZS1oZWlnaHQ6IG5v!
cm1hbDsgLW1zLXdvcmQtYnJlYWs6IGtlZXAtYWxsOyBtc28tcGFnaW5hdGlvbjogd2lkb3ctb3JwaGFuOyBtc28tcGFyYS1tYXJnaW4tdG9wOiAwY207IG1zby1wYXJhLW1hcmdpbi1yaWdodDogMi43MWdkOyBtc28tcGFyYS1tYXJnaW4tYm90dG9tOiAuMDAwMXB0OyBtc28tcGFyYS1tYXJnaW4tbGVmdDogMGNtOyI+PGltZyB3aWR0aD0iMTM5NCIgaGVpZ2h0PSIxOTgiIGNsYXNzPSJ0eGMtaW1hZ2UiIHN0eWxlPSJ3aWR0aDogNDA4cHg7IGhlaWdodDogNTlweDsgY2xlYXI6IG5vbmU7IGZsb2F0OiBub25lOyIgc3JjPSJodHRwczovL2RpcmVjdHNlbmQuY28ua3IvdXBsb2FkX2ltYWdlcy8xNTExOTE2MTM3MjQ2OTc2ODM0NThlMjQ0N2ViZDlmZDI1ZWZkYmNkYWQucG5nIj48ZGl2IGFsaWduPSJjZW50ZXIiIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij48L2Rpdj48cD48L3A+PHA+PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZTogMTFwdDsiPu+7vzwvc3Bhbj4mbmJzcDs8L3A+PHA+PC9wPjwvZm9udD48cCBhbGlnbj0iY2VudGVyIiBzdHlsZT0iYmFja2dyb3VuZDogd2hpdGU7IG1hcmdpbjogMGNtIDI3LjFwdCAwcHQgMGNtOyB0ZXh0LWFsaWduOiBsZWZ0OyBsaW5lLWhlaWdodDogbm9ybWFsOyAtbXMtd29yZC1icmVhazoga2VlcC1hbGw7IG1zby1wYWdpbmF0aW9uOiB3aWRvdy1vcnBoYW47IG1zby1wYXJhLW1hcmdpbi10b3A6IDBjbTsgbXNvLXBhcmEtbWFyZ2luLXJpZ2h0OiAyLjcxZ2Q7IG1zby1w!
YXJhLW1hcmdpbi1ib3R0b206IC4wMDAxcHQ7IG1zby1wYXJhLW1hcmdpbi1sZWZ0OiAwY207Ij48L3A+PC90ZD48L3RyPjwvdGJvZHk+PC90YWJsZT48cD48L3A+PC9zcGFuPjwvZm9udD48cD48YnI+PC9wPgkJCQoJCQkJCTwvZGl2PgkKCQkKCQkJCQkJCTwhLS0gc3RhcnQgZm9vdGVyIC0tPgoKCQkJPHRhYmxlIHdpZHRoPSIxMDAlImJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIxNSIgc3R5bGU9ImJvcmRlcjpub25lIj4KCQkJCTx0Ym9keT4KCQkJCQk8dHI+CgkJCQkJCQkJCQkJCQk8dGQgaWQ9InByZXZpZXdfbG9nbyIgd2lkdGg9IjE1MCIgYmdjb2xvcj0iI2Y1ZjVmNSIgdmFsaWduPSJib3R0b20iIHN0eWxlPSJtYXgtd2lkdGg6MTUwcHg7cGFkZGluZzoxNXB4O2JvcmRlcjpub25lOyI+CgkJCQkJCQkJPGltZyBpZD0idGVtcF9sb2dvX2ltYWdlIiBzcmM9Imh0dHBzOi8vZGlyZWN0c2VuZC5jby5rci91cGxvYWRfaW1hZ2VzLzE1MTA3MzEyNjc1MDcxM2Q4NWNhOTYxZWJiYzc2MTU1MTFjMjg0NDQxZS5qcGciIHN0eWxlPSJtYXJnaW46YXV0bzttYXgtd2lkdGg6MTUwcHg7IiBhbHQ9ImxvZ28iPgoJCQkJCQkJPC90ZD4KCQkJCQkJCQkJCQkJPHRkIGJnY29sb3I9IiNmNWY1ZjUiIHZhbGlnbj0ibWlkZGxlIiBzdHlsZT0icGFkZGluZzoxNXB4O2JvcmRlcjpub25lO2ZvbnQtZmFtaWx5OidOYW51bUJhcnVuR290aGljJywnTWFsZ3VuIEdvdGhpYycsJ05hbnVtR290aGljJywn66eR7J2AIOqzoOuUlScgLCfrgpjriJQg6rOg65SVJyxkb3R1bSxIZWx2ZXRpY2Esc2Fucy1!
zZXJpZjtmb250LXNpemU6MTJweDtsZXR0ZXItc3BhY2luZzotMC4zNXB4O2NvbG9yOiM2NjYiPgoJCQkJCQkJCQkJCQkJCQk8cCBzdHlsZT0ibWFyZ2luOjA7dGV4dC1hbGlnbjpsZWZ0O2xpbmUtaGVpZ2h0OjE4cHg7Ij4KCQkJCQkJCQkJCQkJCQkJCQkJ67O466mU7J287J2AIDIwMTgtMDEtMjIgMDA6MTk6NDQg6riw7KSALCDtmozsm5Dri5jsnZgg7IiY7Iug64+Z7J2YIOyXrOu2gOulvCDtmZXsnbjtlZwg6rKw6rO8IO2ajOybkOuLmOq7mOyEnCDsiJjsi6Drj5nsnZjrpbwg7ZWY7IWo6riw7JeQIOuwnOyGoeuQmOyXiOyKteuLiOuLpC4JCQkJCQkJCTwvcD4KCQkJCQkJCQoJCQkJCQkJCQkJCQkJCQk8cCBzdHlsZT0ibWFyZ2luOjA7dGV4dC1hbGlnbjpsZWZ0O2xpbmUtaGVpZ2h0OjE4cHg7Ij4KCQkJCQkJCQkJ66mU7J28IOyImOyLoOydhCDsm5DsuZgg7JWK7Jy87Iuc66m0IDxhIHRhcmdldD0nX2JsYW5rJyBocmVmPSdodHRwczovL2RpcmVjdHNlbmQuY28ua3IvaW5kZXgucGhwL21haWxfcmVwb3J0X2FwaS9yZWplY3QvSy8xNTY0NzA1OTMvMjYyNzA3NDI0L21rdEBjb210cnVlLmNvbSc+PGI+W+yImOyLoOqxsOu2gF08L2I+PC9hPuulvCDtgbTrpq3tlZjshLjsmpQuPGJyIC8+SWYgeW91IGRvbid0IHdhbnQgdGhpcyB0eXBlIG9mIGluZm9ybWF0aW9uIG9yIGUtbWFpbCwgcGxlYXNlIGNsaWNrIHRoZSA8YSB0YXJnZXQ9J19ibGFuaycgaHJlZj0naHR0cHM6Ly9kaXJlY3RzZW5kLmNvLmtyL2luZGV!
4LnBocC9tYWlsX3JlcG9ydF9hcGkvcmVqZWN0L0UvMTU2NDcwNTkzLzI2MjcwNzQyNC9ta3RAY29tdHJ1ZS5jb20nPjxiPlt1bnN1YnNjcmlwdGlvbl08L2I+PC9hPgkJCQkJCQkJPC9wPgoJCQkJCQkJCgkJCQkJCQkJCQkJCQkJCTxwIGNsYXNzPSJzZW5kZXJfaW5mbyIgc3R5bGU9InRleHQtYWxpZ246bGVmdDtsaW5lLWhlaWdodDoxOHB4OyI+CgkJCQkJCQkJCeyCrOyXheyekCDrk7HroZ3rsojtmLg6NTEwLTE2LTUyOTcxIOyGjOyerOyngDrshJzsmrjtirnrs4Tsi5wg6rCV64Ko6rWsIO2FjO2XpOuegOuhnDgy6ri4IDE1IDk3NO2YuCBURUw6MDItNTAxLTcyNDQgPGJyIC8+RW1haWw6IDxhIGhyZWY9J21haWx0bzpwamNvbnN1bHRpbmdAbmF2ZXIuY29tJz5wamNvbnN1bHRpbmdAbmF2ZXIuY29tPC9hPgkJCQkJCQkJPC9wPgoJCQkJCQkJCQkJCQkJPC90ZD4KCQkJCQk8L3RyPgoJCQkJPC90Ym9keT4KCQkJPC90YWJsZT4KCQkJPCEtLSBlbmQgZm9vdGVyIC0tPgoJCQkKCQkJPCEtLSBvcGVuIHRlbXBsYXRlIC0tPgoJCQk8aW1nIHNyYz0naHR0cHM6Ly9kaXJlY3RzZW5kLmNvLmtyL2luZGV4LnBocC9tYWlsX3JlcG9ydF9hcGkvb3Blbi8xMDI0Njc1LzI2MjcwNzQyNC9ta3RAY29tdHJ1ZS5jb20nIHN0eWxlPSdkaXNwbGF5Om5vbmUnPgkJCQoJCTwvZGl2PgoJCTwhLS0gZW5kIGRpdiBmaXJzdCAtLT4KPC9odG1sPgo=
----82be5ca2-6dee-48ed-b547-ff9b31858929
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: base64
PGh0bWwgbGFuZz0ia28iPgo8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CgoJPGRpdiBpZD0iZHNfYm94IiBzdHlsZT0iZm9udC1mYW1pbHk6ICfrp5HsnYAg6rOg65SVJywn64KY64iUIOqzoOuUlScsZG90dW0sSGVsdmV0aWNhLHNhbnMtc2VyaWY7bGluZS1oZWlnaHQ6MS41O2ZvbnQtc2l6ZToxMnB4O2NvbG9yOiM2NjY7KndvcmQtYnJlYWs6YnJlYWstYWxsOy1tcy13b3JkLWJyZWFrOmJyZWFrLWFsbDtwYWRkaW5nOjBweCAxMHB4OyI+CgkKCQk8ZGl2IGNsYXNzPSJkc19hcnRpY2xlIiBzdHlsZT0iY2xlYXI6Ym90aDttYXJnaW46M2VtIDAiPgkKCQkJPHAgYWxpZ249Imp1c3RpZnkiIHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyBsaW5lLWhlaWdodDogMC41OyI+Jm5ic3A7PC9wPjxmb250IHNpemU9IjMiPjxwIHN0eWxlPSJsaW5lLWhlaWdodDogMC41OyI+PGJyPjwvcD48c3BhbiBzdHlsZT0iZm9udC1zaXplOiAxMnB0OyI+PHAgc3R5bGU9ImxpbmUtaGVpZ2h0OiAwLjU7Ij48YnI+PHRhYmxlIGNsYXNzPSJfX3NlX3RibCIgc3R5bGU9ImJvcmRlci13aWR0aDogMXB4IDFweCAwcHggMHB4OyBib3JkZXItc3R5bGU6IHNvbGlkIHNvbGlkIG5vbmUgbm9uZTsgYm9yZGVyLWNvbG9yOiByZ2IoMjA0LCAyMDQsIDIwNCkgcmdiKDIwNCwgMjA0LCAyMDQpIGN1cnJlbnRDb2xvciBjdXJyZW50Q29sb3I7IGJvcmRlci1pbWFnZTogbm9uZTsiIGJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nP!
SIwIj48dGJvZHk+PHRyPjx0ZCBzdHlsZT0iYm9yZGVyLXdpZHRoOiAwcHggMHB4IDFweCAxcHg7IGJvcmRlci1zdHlsZTogbm9uZSBub25lIHNvbGlkIHNvbGlkOyBib3JkZXItY29sb3I6IGN1cnJlbnRDb2xvciBjdXJyZW50Q29sb3IgcmdiKDIwNCwgMjA0LCAyMDQpIHJnYigyMDQsIDIwNCwgMjA0KTsgYm9yZGVyLWltYWdlOiBub25lOyB3aWR0aDogODY0cHg7IGhlaWdodDogMTg3MHB4OyBiYWNrZ3JvdW5kLWNvbG9yOiByZ2IoMjU1LCAyNTUsIDI1NSk7Ij48cD48c3Ryb25nPjwvc3Ryb25nPjwvcD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48c3Ryb25nPjxicj48L3N0cm9uZz4mbmJzcDs8c3BhbiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsiPuyghOyekOqysOygnOyImOuLqOydmCDrsJzri6zroZwg7ZmI7Ie87ZWRLCZuYnNwO+yduO2EsOuEt+yHvO2VkSwg7Iud64u5IOyWtOuKkOqzs+ydtOuToCZuYnNwO+qzoOyVoeydmCDrjIDquIjrj4Qg66ek64usIO2VoOu2gOuhnCDqs4TsgrDsnbQg6rCA64ql7ZWcIOyLnOuMgOyeheuLiOuLpC4g6riw7JeF65Ok7J2AJm5ic3A76rOg6rCd7Li17J2YIOuLpOyWke2VnCDqtazrp6QmbmJzcDvsmIjsgrDsl5Ag64yA7J2R7ZWY6rOg7J6QIOqysOygnCDsobDqsbTqs7wg6rKw7KCcIOyImOuLqOydhCDri6Trs4DtmZTtlZjsl6wg66ek7Lac7J2EIOq3ueuMgO2ZlCDtlZjquLAg7JyE7ZW0IOunjuydgCDruYTsmqnsnYQg7KeA6!
7aI7ZWY66mwIOuFuOugpe2VmOqzoCDsnojsirXri4jri6QuJm5ic3A77ZWA7YWM7YGsIOq4sOyIoOydmCDrsJzri6zroZwg6rCB7KKFIO2OmOydtOuTpOqzvCDsmpTsppgmbmJzcDvsgqztmozsoIEg66y47KCc66GcIOq4iSDrtoDsg4HtlZjqs6Ag7J6I64qUIOqwgOyDge2ZlO2PkOyZgCDqsJnsnYAmbmJzcDvsp4Drtogg7IiY64uo7J20Jm5ic3A77IOd6rmA7Jy866GcJm5ic3A76riw7JeF7J2AIO2VreyDgSDshozruYTsnpDrk6TsnZgg64uI7KaI66W8IOyVnuyEnOqwgOqzoCDsnojsirXri4jri6QuPC9zcGFuPjwvcD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48YnI+PC9wPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0idGV4dC1hbGlnbjogbGVmdDsiPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDApOyI+Jm5ic3A76re465+s64KYIOyghCDqta3rr7zsnYQg64yA7IOB7Jy866GcIO2VmOuKlCZuYnNwO+yEuOq4iCDrgqnrtoDripQmbmJzcDvsnbTrn7Ag7ZiE7Iuk7JeQ7IScIOyYiOyZuOqwgCDslYTri5Ag7IiYIOyXhuyKteuLiOuLpC4g7KCV67aA64qUIOqzvOyEuCDsnqzsm5Ag7ZmV7Lap7JeQ66eMIOyXtOydhCDsmKzrpqzqs6Ag7IS46riIIOuCqeu2gCDrsKnsi53snYAg7IiY7Iut64WE7J20IOyngOuCmOuPhCDri6zrnbzsp4Dsp4Ag7JWK7JWY7Iq164uI64ukLiDstZzqt7zrk6TslrQg7Iug7Jqp7Lm065Oc66GcIOuCqeu2gOqwgCDqsIDriqXtlbTsoYzri6Tqs6DripQg7ZWY7KeA66eMIDEl64KYIOuQmOuKlCZuYnNwO+y5tOuTnCDsiJjsiJjro4wg65iQ!
7ZWcJm5ic3A764Kp7IS47J6Q7J2YIOu2gOuLtOyduCDsoJDsnYQg6rOg66Ck7ZWY66m0IOydtOuKlCA8c3Ryb25nPuqwgOyCsOyEuOyZgCDri6TrpoQg7JeG64qUIOu2iOydtOydtTwvc3Ryb25nPuydtOudvCDrs7wg7IiYIOyeiOyKteuLiOuLpC4g7J2067+Q66eMIOyVhOuLiOudvCZuYnNwO+qwgeyihSDshLjslaEg6rCQ66m0IOuTsSDsobDshLgg7Zic7YOd7J2AIDxzdHJvbmc+67O17J6h7ZWcIOyalOqxtDwvc3Ryb25nPuydhCDqtazruYTtlbTslbzrp4wg7KCB7Jqp67Cb7J2EIOyImCDsnojslrQg7KCV67aA64qUIOuCqeyEuOyekOuTpOyXkOuKlCDqsrDsvZQg7Lmc7KCI7ZWY7KeAIOyViuydgCDtmITsi6TsnoXri4jri6QuPC9zcGFuPjwvcD48cD48YnI+PC9wPjxwIGFsaWduPSJqdXN0aWZ5IiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeTsiPjwvcD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48Zm9udCBzaXplPSIzIj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsgZm9udC1zaXplOiAxMnB0OyI+Jm5ic3A7PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7Ij4yMDE464WEIOyYrO2VtOuPhCDshozrk53shLjrspXsnbQg7JWE656Y7JmAIOqwmeydtCDqsJzsoJXrkJjslrQg6riw7JeFIOuwjyBDRU/qu5jshJzripQg67mg66W4IOuMgOu5hOulvCDtlZjshZTslbwg7IaM7KSR7ZWcIOyerOyCsOydhCDsp4Dtgqwg7IiYIOyeiOyKteuLiOuLpC48!
L3NwYW4+PC9zcGFuPjwvZm9udD48L3A+PHAgYWxpZ249Imp1c3RpZnkiIHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyBsaW5lLWhlaWdodDogMC41OyI+PGZvbnQgc2l6ZT0iMyI+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7IGZvbnQtc2l6ZTogMTJwdDsiPuKAizwvc3Bhbj48L2ZvbnQ+PGJyPjwvcD48Zm9udCBzaXplPSIzIj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsgZm9udC1zaXplOiAxMnB0OyI+PHAgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxzdHJvbmc+Jmx0OzIwMTjrhYQg6rCc7KCVIOyEuOycqOqzvCDsho3sgrDtkZwmZ3Q7Jm5ic3A7PC9zdHJvbmc+PC9wPjwvc3Bhbj48L2ZvbnQ+PGZvbnQgc2l6ZT0iMyI+PHAgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxpbWcgd2lkdGg9IjkwMSIgaGVpZ2h0PSI0NzciIGNsYXNzPSJ0eGMtaW1hZ2UiIHN0eWxlPSJ3aWR0aDogNTE2cHg7IGhlaWdodDogMjc4cHg7IGNsZWFyOiBub25lOyBmbG9hdDogbm9uZTsiIHNyYz0iaHR0cHM6Ly9kaXJlY3RzZW5kLmNvLmtyL3VwbG9hZF9pbWFnZXMvMTUxNjE1MDEwNGJmYWM4M2QyNDNmNTc3NGQyNDEyZDllNjlkZDNhM2Y4LmpwZyI+PC9wPjxkaXYgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjwvZGl2PjxwPjwvcD48L2ZvbnQ+PGZvbnQgc2l6ZT0iMyI+PHAgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxzcGFuIHN0eWxlPSJjb2xvcjo!
gcmdiKDAsIDAsIDApOyBmb250LXNpemU6IDlwdDsiPmV4KSDsho3sgrDtkZwg6rOE7IKwIOuwqeuylTxicj48L3NwYW4+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7IGZvbnQtc2l6ZTogOXB0OyI+LSDshozrk53snbQgNeyynOunjOybkOyduCDqsr3smrAgOiA17LKc66eM7JuQIFggMjQlIC0gNTIy66eM7JuQID0gNjc466eM7JuQPC9zcGFuPjxzcGFuPjxicj48L3NwYW4+PHNwYW4+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7IGZvbnQtc2l6ZTogOXB0OyI+LSDshozrk53snbQgMeyWtSA47LKc66eM7JuQ7J24IOqyveyasCA6IDHslrU47LKc66eM7JuQIFggMzglIC0gMSw5NDDrp4zsm5AgPSA0LDkwMOunjOybkDwvc3Bhbj48YnI+PC9zcGFuPjxzcGFuPjxicj48L3NwYW4+PC9wPjwvZm9udD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48Zm9udCBzaXplPSIzIj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsgZm9udC1zaXplOiAxMnB0OyI+Jm5ic3A7PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7Ij7qsJzsoJUg7IaM65Od7IS467KV7J2AIOyLoOyEpOuQmOuKlCDstZzqs6Ag7IS47Jyo6rO8IOuIhOynhCDqtazqsITsnZgg7LaU6rCA66GcJm5ic3A76rOg7IaM65Od7J6Q7JeQ6rKM64qUIOyEuOu2gOuLtOydtCDrjZTsmrEg6rCA7KSR65CY7JeI7Iq164uI64ukLiDtirntnogg7KSR7IaM6riw7JeF7J2YIENFT+q7mOy!
EnOuKlCDtj4nqt6Drs7Tri6Qg64aS7J2AIOyImOykgOydmCDshozrk53snYQmbmJzcDvsp4DquInrsJvqs6Ag6rOE7Iuc6riw7JeQIOyEuOuylSDqsJzsoJUg7IKs7ZWt7J2YIOyYge2WpeydhCDrp47snbQg67Cb7J2EIOyImCDrsJbsl5Ag7JeG7Iq164uI64ukLiZuYnNwOyZuYnNwO+q3vOuhnOyGjOuTneydtCDrp47snYzsl5Drj4QmbmJzcDvshLjrspXsg4Eg6rO17KCc7JWh7J2AIO2EsOustOuLiCDsl4bsnbQg7KCB7Ja0IOyGjOuTneyEuOyZgCDso7zrr7zshLjrpbwg7Y+s7ZWo7ZWY66m0IOyGjOuTneydmCDqsbDsnZggPHN0cm9uZz7soIjrsJjsl5Ag6rCA6rmM7Jq0IOq4iOyVoeydhCDshLjquIg8L3N0cm9uZz7snLzroZwg64Kp67aA7ZW07JW8IO2VmOuKlCDsi5zrjIDqsIAg64+E656Y7ZWY7JiA7Iq164uI64ukLiA8L3NwYW4+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7IGZvbnQtc2l6ZTogMTBwdDsiPijqt7zroZzshozrk50gMeyWteybkCDstIjqs7zsi5wg6rO17KCc7JyoIDIlKTwvc3Bhbj48L3NwYW4+PC9mb250PjwvcD48Zm9udCBzaXplPSIzIj48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48YnI+PC9wPjwvZm9udD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48Zm9udCBzaXplPSIzIj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsiPiZuYnNwO+yggO2drCDtlLzsoJzsnbTsu6jshKTtjIXsl5DshJzripQg6rOg7IaM65OdIENFT+u2hOuTpOydmCDsoIjshLgg64+E7Jqw66+466GcIOuCmOyEnC!
A8c3Ryb25nPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDI1NSwgMCwgMCk7Ij7qt7zroZzshozrk53qs7wg67mE6rWQ7ZWY66m0IDgwJSDsoIjqsJA8L3NwYW4+PC9zdHJvbmc+65CcIOygiOyEuCDshJzruYTsiqTrpbwg7KCc6rO17ZW0IOuTnOumrOqzoOyekCDtlanri4jri6QuIO2YhOq4iCDsnbzsi5zrtogg64Kp67aA66W8IOybkOy5meycvOuhnCDtlZjripQg7IS46riI64Kp67aA64qUIOygiOyEuOunjCDshLHqs7XtlZjsl6zrj4Qg7JeE7LKt64KcIO2YhOq4iO2dkOumhCDqsJzshKDtmqjqs7zrpbwg6rCA7KC47Jio64uk6rOgIO2VoCDsiJgg7J6I7Iq164uI64ukLiDsi6TsoJzroZwg7IiY66eO7J2AIENFT+q7mOyEnOuPhCDtlLzsoJzsnbTsu6jshKTtjIXsnZgg7KCI7IS4IOyEnOu5hOyKpOuhnCZuYnNwO+2BsCDrp4zsobHsnYQg7Ja76rOgIOqzhOyLreuLiOuLpC48L3NwYW4+PC9mb250PjwvcD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48YnI+PC9wPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0idGV4dC1hbGlnbjogbGVmdDsiPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDApOyI+Jm5ic3A7PHN0cm9uZz7tlLzsoJzsnbTsu6jshKTtjIU8L3N0cm9uZz7snZggPC9zcGFuPjxzdHJvbmc+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7Ij7tirntl4jsnpDrs7jtmZQ8L3NwYW4+PC9zdHJvbmc+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMC!
k7Ij7rnbwg67aI66as64qUIOyCsOyXheyerOyCsOq2jOydhCDtmZzsmqntlZwmbmJzcDvsu6jshKTtjIXsnYAmbmJzcDvqt7zroZzshozrk53shLjsnZggMjAl67CW7JeQIOyViOuQmOuKlCDshLjquIjsnLzroZwgQ0VP7J2YJm5ic3A77ZmV7Iuk7ZWcIOygiOyEuCDrj4TsmrDrr7jroZwg7J6Q66as66ek6rmA7ZWY7JiA7Iq164uI64ukLiDslYTrnpjsnZgg7ZGc64qUIOyGjOuTnSDrtoTrpZjsl5Ag65Sw66W4IOyEuOq4iCDrgqnrtoDslaEg67mE6rWQ7J6F64uI64ukLiZuYnNwOzwvc3Bhbj48L3A+PHNwYW4+PHAgYWxpZ249Imp1c3RpZnkiIHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+PGJyPjwvcD48cCBhbGlnbj0iY2VudGVyIiBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyI+PGltZyB3aWR0aD0iNzk5IiBoZWlnaHQ9IjMzOCIgY2xhc3M9InR4Yy1pbWFnZSIgc3R5bGU9IndpZHRoOiA2MTlweDsgaGVpZ2h0OiAyNDlweDsgY2xlYXI6IG5vbmU7IGZsb2F0OiBub25lOyIgc3JjPSJodHRwczovL2RpcmVjdHNlbmQuY28ua3IvdXBsb2FkX2ltYWdlcy8xNTE2MTgzOTkyNmI1NmUzNDg2YTNmOTIyYWIzOTAyYjg0MzZlMzQyYjAuanBnIj48ZGl2IGFsaWduPSJjZW50ZXIiIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij48L2Rpdj48cD48L3A+PHAgYWxpZ249Imp1c3RpZnkiIHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5OyI+PGJyPjwvcD48cD48L3A+PC9zcGFuPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0idGV4dC1hbGlnbjogbGVmdDsiPiZuYnNwOzxzcGFuIHN0eWxlPSJjb2xvcjogc!
mdiKDAsIDAsIDApOyI+7ZGc7JeQIOydmO2VmOuptCZuYnNwO+qwmeydgCAxMOyWteybkOydmCDshozrk53snbQg67Cc7IOd7ZWY7JiA7Ja064+EIOyGjOuTneydmCDsooXrpZjsl5Ag65Sw6528IOyLpOyImOugueyVoeydgCA8c3Ryb25nPjPslrXsm5A8L3N0cm9uZz4g7J207IOBJm5ic3A77LCo7J206rCAIOuCqeuLiOuLpC4g66ek64WEIOqzoOycqOydmCDshLjquIjrtoDri7TsnYQg7IiY67CY7ZWY64qUIOq3vOuhnOyGjOuTneqzvCDrsLDri7nquIgg7J247LacIOuMgOyLoOyXkCDtlLzsoJzsnbTsu6jshKTtjIXsnZggPC9zcGFuPjxzdHJvbmc+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7Ij7tirntl4jsnpDrs7jtmZQ8L3NwYW4+PC9zdHJvbmc+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7Ij7rpbwg6rK97ZeY7ZWY7Iuc7Ja0Jm5ic3A77IiY7LKc66eM7JuQIOuCtOyngCA8c3Ryb25nPuyImOyWteybkOydmCDsoIjshLjtmqjqs7w8L3N0cm9uZz7smYAg64+Z7Iuc7JeQIOq4sOyXheydmCDquLDsiKDroKXrj4Qg7ZmV67O07ZWY7Iuc64qUIDIwMTjrhYTrj4Qg7ZWc7ZW06rCAIOuQmOyLnOq4uCDrsJTrno3ri4jri6QuIDwvc3Bhbj48cCBhbGlnbj0ibGVmdCIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48YnI+PC9wPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0idGV4dC1hbGlnbjogbGVmdDsiPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDApOyI+642UIOyekOyEu!
O2VnCDsgqztla3snYAg7JWE656Y7J2YIOyXsOudveyymOuhnCDrrLjsnZgg7KO87Iuc66m0IOu5oOuluCDsi5zsnbzrgrTsl5Ag67Cp66y4IOyDgeuLtCDrk5zrpqzqsqDsirXri4jri6QuJm5ic3A7PC9zcGFuPjxwPjwvcD48cCBzdHlsZT0idGV4dC1hbGlnbjogbGVmdDsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPiZuYnNwOzwvZm9udD48c3BhbiBsYW5nPSJFTi1VUyIgc3R5bGU9ImNvbG9yOiBibGFjazsgZm9udC1zaXplOiAxMnB0OyBtc28tYmlkaS1mb250LWZhbWlseTogQXJpYWw7IG1zby1hc2NpaS1mb250LWZhbWlseTog66eR7J2AIOqzoOuUlTsgbXNvLWFzY2lpLXRoZW1lLWZvbnQ6IG1pbm9yLWZhcmVhc3Q7IG1zby1oYW5zaS1mb250LWZhbWlseTog66eR7J2AIOqzoOuUlTsgbXNvLWhhbnNpLXRoZW1lLWZvbnQ6IG1pbm9yLWZhcmVhc3Q7IG1zby1mb250LWtlcm5pbmc6IDBwdDsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPiZuYnNwOzwvZm9udD48L3NwYW4+PHNwYW4gbGFuZz0iRU4tVVMiIHN0eWxlPSJjb2xvcjogYmxhY2s7IG1zby1iaWRpLWZvbnQtZmFtaWx5OiBBcmlhbDsgbXNvLWFzY2lpLWZvbnQtZmFtaWx5OiDrp5HsnYAg6rOg65SVOyBtc28tYXNjaWktdGhlbWUtZm9udDogbWlub3ItZmFyZWFzdDsgbXNvLWhhbnNpLWZvbnQtZmFtaWx5OiDrp5HsnYAg6rOg65SVOyBtc28taGFuc2ktdGhlbWUtZm9udDogbWlub3ItZmFyZWFzdDsgbXNvLWZvbnQta2VybmluZzogMHB0OyBtc28tYmlkaS1mb250LXNpemU6IDEwLjBwdDsiPjxmb250IGZhY2U9IuunkeydgCDq!
s6DrlJUiPiZuYnNwOzwvZm9udD48L3NwYW4+PC9wPjxwPjwvcD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9ImJhY2tncm91bmQ6IHdoaXRlOyBtYXJnaW46IDBjbSAyNy4xcHQgMHB0IDBjbTsgdGV4dC1hbGlnbjogbGVmdDsgbGluZS1oZWlnaHQ6IG5vcm1hbDsgLW1zLXdvcmQtYnJlYWs6IGtlZXAtYWxsOyBtc28tcGFnaW5hdGlvbjogd2lkb3ctb3JwaGFuOyBtc28tcGFyYS1tYXJnaW4tdG9wOiAwY207IG1zby1wYXJhLW1hcmdpbi1yaWdodDogMi43MWdkOyBtc28tcGFyYS1tYXJnaW4tYm90dG9tOiAuMDAwMXB0OyBtc28tcGFyYS1tYXJnaW4tbGVmdDogMGNtOyI+PGZvbnQgZmFjZT0i66eR7J2AIOqzoOuUlSI+PHNwYW4gbGFuZz0iRU4tVVMiIHN0eWxlPSJjb2xvcjogYmxhY2s7IGZvbnQtc2l6ZTogMTFwdDsgbXNvLWJpZGktZm9udC1mYW1pbHk6IEFyaWFsOyBtc28tYXNjaWktZm9udC1mYW1pbHk6IOunkeydgCDqs6DrlJU7IG1zby1hc2NpaS10aGVtZS1mb250OiBtaW5vci1mYXJlYXN0OyBtc28taGFuc2ktZm9udC1mYW1pbHk6IOunkeydgCDqs6DrlJU7IG1zby1oYW5zaS10aGVtZS1mb250OiBtaW5vci1mYXJlYXN0OyBtc28tZm9udC1rZXJuaW5nOiAwcHQ7IG1zby1iaWRpLWZvbnQtc2l6ZTogMTIuMHB0OyI+PHN0cm9uZz5QSkNvbnN1bHRpbmcgKDwvc3Ryb25nPjxzdHJvbmc+IDwvc3Ryb25nPjxhIGhyZWY9Imh0dHBzOi8vZGlyZWN0c2VuZC5jby5rci9pbmRleC5waHAvbWFpbF9yZXBvcnRf!
YXBpL2NsaWNrLzEwMjQ2NzUvYUhSMGNEb3ZMM2QzZHk1d2FtTnZibk4xYkhScGJtY3VibVYwTHcvMjYyNzA3NDI0L21rdEBjb210cnVlLmNvbS8xIiB0YXJnZXQ9Il9ibGFuayI+PHN0cm9uZz5odHRwOi8vd3d3LnBqY29uc3VsdGluZy5uZXQ8L3N0cm9uZz48L2E+Jm5ic3A7KTwvc3Bhbj48L2ZvbnQ+PC9wPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0iYmFja2dyb3VuZDogd2hpdGU7IG1hcmdpbjogMGNtIDI3LjFwdCAwcHQgMGNtOyB0ZXh0LWFsaWduOiBsZWZ0OyBsaW5lLWhlaWdodDogbm9ybWFsOyAtbXMtd29yZC1icmVhazoga2VlcC1hbGw7IG1zby1wYWdpbmF0aW9uOiB3aWRvdy1vcnBoYW47IG1zby1wYXJhLW1hcmdpbi10b3A6IDBjbTsgbXNvLXBhcmEtbWFyZ2luLXJpZ2h0OiAyLjcxZ2Q7IG1zby1wYXJhLW1hcmdpbi1ib3R0b206IC4wMDAxcHQ7IG1zby1wYXJhLW1hcmdpbi1sZWZ0OiAwY207Ij48Zm9udCBmYWNlPSLrp5HsnYAg6rOg65SVIj48YiBzdHlsZT0ibXNvLWJpZGktZm9udC13ZWlnaHQ6IG5vcm1hbDsiPjxzcGFuIGxhbmc9IkVOLVVTIiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsgZm9udC1zaXplOiAxMXB0OyBtc28tYmlkaS1mb250LWZhbWlseTogQXJpYWw7IG1zby1hc2NpaS1mb250LWZhbWlseTog66eR7J2AIOqzoOuUlTsgbXNvLWFzY2lpLXRoZW1lLWZvbnQ6IG1pbm9yLWZhcmVhc3Q7IG1zby1oYW5zaS1mb250LWZhbWlseTog66eR7J2AIOqzoOuUlTsgbXNvLWhhbnNpLXRoZW1lLWZvbnQ6IG1pbm9yLWZhcmVhc3Q7IG1zby1mb250LWtlcm5pbmc6IDBwdDsgbXN!
vLWJpZGktZm9udC1zaXplOiAxMi4wcHQ7Ij7shJzsmrjtirnrs4Tsi5wg6rCV64Ko6rWsIO2FjO2XpOuegOuhnDgy6ri4IDE1ICjrjIDsuZjrj5ksIOuUlOyVhOydtO2DgOybjCk5NzTtmLg8L3NwYW4+PC9iPjwvZm9udD48L3A+PHAgYWxpZ249ImxlZnQiIHN0eWxlPSJiYWNrZ3JvdW5kOiB3aGl0ZTsgbWFyZ2luOiAwY20gMjcuMXB0IDBwdCAwY207IHRleHQtYWxpZ246IGxlZnQ7IGxpbmUtaGVpZ2h0OiBub3JtYWw7IC1tcy13b3JkLWJyZWFrOiBrZWVwLWFsbDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhhbjsgbXNvLXBhcmEtbWFyZ2luLXRvcDogMGNtOyBtc28tcGFyYS1tYXJnaW4tcmlnaHQ6IDIuNzFnZDsgbXNvLXBhcmEtbWFyZ2luLWJvdHRvbTogLjAwMDFwdDsgbXNvLXBhcmEtbWFyZ2luLWxlZnQ6IDBjbTsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPjxiIHN0eWxlPSJtc28tYmlkaS1mb250LXdlaWdodDogbm9ybWFsOyI+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwgMCwgMCk7IGZvbnQtc2l6ZTogMTFwdDsiPlRFTC4gMDItNTAxLTcyNDQmbmJzcDsmbmJzcDsmbmJzcDsgRkFYLiAwNTAtNDM4OS05NDE2PC9zcGFuPjwvYj48L2ZvbnQ+PC9wPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0iYmFja2dyb3VuZDogd2hpdGU7IG1hcmdpbjogMGNtIDI3LjFwdCAwcHQgMGNtOyB0ZXh0LWFsaWduOiBsZWZ0OyBsaW5lLWhlaWdodDogbm9ybWFsOyAtbXMtd29yZC1icmVhazoga2VlcC1hbGw!
7IG1zby1wYWdpbmF0aW9uOiB3aWRvdy1vcnBoYW47IG1zby1wYXJhLW1hcmdpbi10b3A6IDBjbTsgbXNvLXBhcmEtbWFyZ2luLXJpZ2h0OiAyLjcxZ2Q7IG1zby1wYXJhLW1hcmdpbi1ib3R0b206IC4wMDAxcHQ7IG1zby1wYXJhLW1hcmdpbi1sZWZ0OiAwY207Ij48Zm9udCBmYWNlPSLrp5HsnYAg6rOg65SVIj48YiBzdHlsZT0ibXNvLWJpZGktZm9udC13ZWlnaHQ6IG5vcm1hbDsiPjxzcGFuIGxhbmc9IkVOLVVTIiBzdHlsZT0iY29sb3I6IHJnYigwLCAwLCAwKTsgZm9udC1zaXplOiAxMXB0OyBtc28tYmlkaS1mb250LWZhbWlseTogQXJpYWw7IG1zby1hc2NpaS1mb250LWZhbWlseTog66eR7J2AIOqzoOuUlTsgbXNvLWFzY2lpLXRoZW1lLWZvbnQ6IG1pbm9yLWZhcmVhc3Q7IG1zby1oYW5zaS1mb250LWZhbWlseTog66eR7J2AIOqzoOuUlTsgbXNvLWhhbnNpLXRoZW1lLWZvbnQ6IG1pbm9yLWZhcmVhc3Q7IG1zby1mb250LWtlcm5pbmc6IDBwdDsgbXNvLWJpZGktZm9udC1zaXplOiAxMi4wcHQ7Ij5Nb2JpbGUuIDAxMC01ODEyLTEzMTIgLCAwMTAtMjAxOS0yODMxPC9zcGFuPjwvYj48L2ZvbnQ+PC9wPjxwIGFsaWduPSJsZWZ0IiBzdHlsZT0iYmFja2dyb3VuZDogd2hpdGU7IG1hcmdpbjogMGNtIDI3LjFwdCAwcHQgMGNtOyB0ZXh0LWFsaWduOiBsZWZ0OyBsaW5lLWhlaWdodDogbm9ybWFsOyAtbXMtd29yZC1icmVhazoga2VlcC1hbGw7IG1zby1wYWdpbmF0aW9uOiB3aWRvdy1vcnBoYW47IG1zby1wYXJhLW1hcmdpbi10b3A6IDBjbTsgbXNvLXBhcmEtbWFyZ2luLXJpZ2h0OiAyLjcxZ2Q7IG!
1zby1wYXJhLW1hcmdpbi1ib3R0b206IC4wMDAxcHQ7IG1zby1wYXJhLW1hcmdpbi1sZWZ0OiAwY207Ij48Zm9udCBmYWNlPSLrp5HsnYAg6rOg65SVIj48YiBzdHlsZT0ibXNvLWJpZGktZm9udC13ZWlnaHQ6IG5vcm1hbDsiPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDApOyBmb250LXNpemU6IDExcHQ7Ij5FLW1haWwuIHBqY29uc3VsdGluZ0DrhKTsnbTrsoTrqZTsnbw8L3NwYW4+PC9iPjwvZm9udD48L3A+PHAgYWxpZ249ImxlZnQiIHN0eWxlPSJiYWNrZ3JvdW5kOiB3aGl0ZTsgbWFyZ2luOiAwY20gMjcuMXB0IDBwdCAwY207IHRleHQtYWxpZ246IGxlZnQ7IGxpbmUtaGVpZ2h0OiBub3JtYWw7IC1tcy13b3JkLWJyZWFrOiBrZWVwLWFsbDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhhbjsgbXNvLXBhcmEtbWFyZ2luLXRvcDogMGNtOyBtc28tcGFyYS1tYXJnaW4tcmlnaHQ6IDIuNzFnZDsgbXNvLXBhcmEtbWFyZ2luLWJvdHRvbTogLjAwMDFwdDsgbXNvLXBhcmEtbWFyZ2luLWxlZnQ6IDBjbTsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6IDExcHQ7Ij48c3Ryb25nPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDApOyI+4oCLQmxvZy4gPC9zcGFuPjwvc3Ryb25nPjxhIGhyZWY9Imh0dHBzOi8vZGlyZWN0c2VuZC5jby5rci9pbmRleC5waHAvbWFpbF9yZXBvcnRfYXBpL2NsaWNrLzEwMjQ2NzUvYUhSMGNEb3ZMMkpzYjJjdWJtRj!
JaWEl1WTI5dEwzQnFZMjl1YzNWc2RHbHVady8yNjI3MDc0MjQvbWt0QGNvbXRydWUuY29tLzIiIHRhcmdldD0iX2JsYW5rIj48c3Ryb25nPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsIDAsIDApOyI+aHR0cDovL2Jsb2cubmF2ZXIuY29tL3BqY29uc3VsdGluZzwvc3Bhbj48L3N0cm9uZz48L2E+PC9zcGFuPjwvZm9udD48L3A+PHAgYWxpZ249ImxlZnQiIHN0eWxlPSJiYWNrZ3JvdW5kOiB3aGl0ZTsgbWFyZ2luOiAwY20gMjcuMXB0IDBwdCAwY207IHRleHQtYWxpZ246IGxlZnQ7IGxpbmUtaGVpZ2h0OiBub3JtYWw7IC1tcy13b3JkLWJyZWFrOiBrZWVwLWFsbDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhhbjsgbXNvLXBhcmEtbWFyZ2luLXRvcDogMGNtOyBtc28tcGFyYS1tYXJnaW4tcmlnaHQ6IDIuNzFnZDsgbXNvLXBhcmEtbWFyZ2luLWJvdHRvbTogLjAwMDFwdDsgbXNvLXBhcmEtbWFyZ2luLWxlZnQ6IDBjbTsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6IDExcHQ7Ij48YnI+PC9zcGFuPjwvZm9udD48L3A+PHAgYWxpZ249ImxlZnQiIHN0eWxlPSJiYWNrZ3JvdW5kOiB3aGl0ZTsgbWFyZ2luOiAwY20gMjcuMXB0IDBwdCAwY207IHRleHQtYWxpZ246IGxlZnQ7IGxpbmUtaGVpZ2h0OiBub3JtYWw7IC1tcy13b3JkLWJyZWFrOiBrZWVwLWFsbDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhhbjsgbXNvLXBhcmEtbWFyZ2luLXRvcDogMGNtOyBtc28tcGFyYS1tYXJnaW4tcmlnaHQ6IDIuNzFnZDsgbXNvLXBhcmEtbWFyZ2luLWJvdHRvb!
TogLjAwMDFwdDsgbXNvLXBhcmEtbWFyZ2luLWxlZnQ6IDBjbTsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6IDExcHQ7Ij48dT48L3U+PC9zcGFuPjwvZm9udD48cCBhbGlnbj0iY2VudGVyIiBzdHlsZT0idGV4dC1hbGlnbjogbGVmdDsiPjxicj48L3A+PGZvbnQgZmFjZT0i66eR7J2AIOqzoOuUlSI+PHAgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGxlZnQ7Ij48L3A+PHU+PHAgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxpbWcgd2lkdGg9IjEyOTciIGhlaWdodD0iNjcwIiBjbGFzcz0idHhjLWltYWdlIiBzdHlsZT0id2lkdGg6IDU0MnB4OyBoZWlnaHQ6IDI3NnB4OyBjbGVhcjogbm9uZTsgZmxvYXQ6IG5vbmU7IiBzcmM9Imh0dHBzOi8vZGlyZWN0c2VuZC5jby5rci91cGxvYWRfaW1hZ2VzLzE1MTQ4MTkwNzlhZjcxOTg4NDM5MDdjNDYwNmI4ZDEwNWNmOThlNmI5Zi5wbmciPjxkaXYgYWxpZ249ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjwvZGl2PjxwPjwvcD48L3U+PC9mb250PjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBsZWZ0OyI+PGZvbnQgZmFjZT0i66eR7J2AIOqzoOuUlSI+PHU+IDwvdT48L2ZvbnQ+PC9wPjxwPjwvcD48cCBhbGlnbj0ibGVmdCIgc3R5bGU9ImJhY2tncm91bmQ6IHdoaXRlOyBtYXJnaW46IDBjbSAyNy4xcHQgMHB0IDBjbTsgdGV4dC1hbGlnbjogbGVmdDsgb!
GluZS1oZWlnaHQ6IG5vcm1hbDsgLW1zLXdvcmQtYnJlYWs6IGtlZXAtYWxsOyBtc28tcGFnaW5hdGlvbjogd2lkb3ctb3JwaGFuOyBtc28tcGFyYS1tYXJnaW4tdG9wOiAwY207IG1zby1wYXJhLW1hcmdpbi1yaWdodDogMi43MWdkOyBtc28tcGFyYS1tYXJnaW4tYm90dG9tOiAuMDAwMXB0OyBtc28tcGFyYS1tYXJnaW4tbGVmdDogMGNtOyI+PGZvbnQgZmFjZT0i66eR7J2AIOqzoOuUlSI+PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZTogMTFwdDsiPjx1Pjxicj48L3U+PC9zcGFuPjwvZm9udD48L3A+PHAgYWxpZ249ImxlZnQiIHN0eWxlPSJiYWNrZ3JvdW5kOiB3aGl0ZTsgbWFyZ2luOiAwY20gMjcuMXB0IDBwdCAwY207IHRleHQtYWxpZ246IGxlZnQ7IGxpbmUtaGVpZ2h0OiAwLjU7IC1tcy13b3JkLWJyZWFrOiBrZWVwLWFsbDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhhbjsgbXNvLXBhcmEtbWFyZ2luLXRvcDogMGNtOyBtc28tcGFyYS1tYXJnaW4tcmlnaHQ6IDIuNzFnZDsgbXNvLXBhcmEtbWFyZ2luLWJvdHRvbTogLjAwMDFwdDsgbXNvLXBhcmEtbWFyZ2luLWxlZnQ6IDBjbTsiPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyA8L2ZvbnQ+PC9wPjxmb250IGZhY2U9IuunkeydgCDqs6DrlJUiPjxwIGFsaWduPSJjZW50ZXIiIHN0eWxlPSJiYWNrZ3JvdW5kOiB3aGl0ZTsgbWFyZ2luOiAwY20gMjcuMXB0IDBwdCAwY207IHRleHQtYWxpZ246IGNlbnRlcjsgbGluZS1oZWlnaHQ6IG5v!
cm1hbDsgLW1zLXdvcmQtYnJlYWs6IGtlZXAtYWxsOyBtc28tcGFnaW5hdGlvbjogd2lkb3ctb3JwaGFuOyBtc28tcGFyYS1tYXJnaW4tdG9wOiAwY207IG1zby1wYXJhLW1hcmdpbi1yaWdodDogMi43MWdkOyBtc28tcGFyYS1tYXJnaW4tYm90dG9tOiAuMDAwMXB0OyBtc28tcGFyYS1tYXJnaW4tbGVmdDogMGNtOyI+PGltZyB3aWR0aD0iMTM5NCIgaGVpZ2h0PSIxOTgiIGNsYXNzPSJ0eGMtaW1hZ2UiIHN0eWxlPSJ3aWR0aDogNDA4cHg7IGhlaWdodDogNTlweDsgY2xlYXI6IG5vbmU7IGZsb2F0OiBub25lOyIgc3JjPSJodHRwczovL2RpcmVjdHNlbmQuY28ua3IvdXBsb2FkX2ltYWdlcy8xNTExOTE2MTM3MjQ2OTc2ODM0NThlMjQ0N2ViZDlmZDI1ZWZkYmNkYWQucG5nIj48ZGl2IGFsaWduPSJjZW50ZXIiIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij48L2Rpdj48cD48L3A+PHA+PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZTogMTFwdDsiPu+7vzwvc3Bhbj4mbmJzcDs8L3A+PHA+PC9wPjwvZm9udD48cCBhbGlnbj0iY2VudGVyIiBzdHlsZT0iYmFja2dyb3VuZDogd2hpdGU7IG1hcmdpbjogMGNtIDI3LjFwdCAwcHQgMGNtOyB0ZXh0LWFsaWduOiBsZWZ0OyBsaW5lLWhlaWdodDogbm9ybWFsOyAtbXMtd29yZC1icmVhazoga2VlcC1hbGw7IG1zby1wYWdpbmF0aW9uOiB3aWRvdy1vcnBoYW47IG1zby1wYXJhLW1hcmdpbi10b3A6IDBjbTsgbXNvLXBhcmEtbWFyZ2luLXJpZ2h0OiAyLjcxZ2Q7IG1zby1w!
YXJhLW1hcmdpbi1ib3R0b206IC4wMDAxcHQ7IG1zby1wYXJhLW1hcmdpbi1sZWZ0OiAwY207Ij48L3A+PC90ZD48L3RyPjwvdGJvZHk+PC90YWJsZT48cD48L3A+PC9zcGFuPjwvZm9udD48cD48YnI+PC9wPgkJCQoJCQkJCTwvZGl2PgkKCQkKCQkJCQkJCTwhLS0gc3RhcnQgZm9vdGVyIC0tPgoKCQkJPHRhYmxlIHdpZHRoPSIxMDAlImJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIxNSIgc3R5bGU9ImJvcmRlcjpub25lIj4KCQkJCTx0Ym9keT4KCQkJCQk8dHI+CgkJCQkJCQkJCQkJCQk8dGQgaWQ9InByZXZpZXdfbG9nbyIgd2lkdGg9IjE1MCIgYmdjb2xvcj0iI2Y1ZjVmNSIgdmFsaWduPSJib3R0b20iIHN0eWxlPSJtYXgtd2lkdGg6MTUwcHg7cGFkZGluZzoxNXB4O2JvcmRlcjpub25lOyI+CgkJCQkJCQkJPGltZyBpZD0idGVtcF9sb2dvX2ltYWdlIiBzcmM9Imh0dHBzOi8vZGlyZWN0c2VuZC5jby5rci91cGxvYWRfaW1hZ2VzLzE1MTA3MzEyNjc1MDcxM2Q4NWNhOTYxZWJiYzc2MTU1MTFjMjg0NDQxZS5qcGciIHN0eWxlPSJtYXJnaW46YXV0bzttYXgtd2lkdGg6MTUwcHg7IiBhbHQ9ImxvZ28iPgoJCQkJCQkJPC90ZD4KCQkJCQkJCQkJCQkJPHRkIGJnY29sb3I9IiNmNWY1ZjUiIHZhbGlnbj0ibWlkZGxlIiBzdHlsZT0icGFkZGluZzoxNXB4O2JvcmRlcjpub25lO2ZvbnQtZmFtaWx5OidOYW51bUJhcnVuR290aGljJywnTWFsZ3VuIEdvdGhpYycsJ05hbnVtR290aGljJywn66eR7J2AIOqzoOuUlScgLCfrgpjriJQg6rOg65SVJyxkb3R1bSxIZWx2ZXRpY2Esc2Fucy1!
zZXJpZjtmb250LXNpemU6MTJweDtsZXR0ZXItc3BhY2luZzotMC4zNXB4O2NvbG9yOiM2NjYiPgoJCQkJCQkJCQkJCQkJCQk8cCBzdHlsZT0ibWFyZ2luOjA7dGV4dC1hbGlnbjpsZWZ0O2xpbmUtaGVpZ2h0OjE4cHg7Ij4KCQkJCQkJCQkJCQkJCQkJCQkJ67O466mU7J287J2AIDIwMTgtMDEtMjIgMDA6MTk6NDQg6riw7KSALCDtmozsm5Dri5jsnZgg7IiY7Iug64+Z7J2YIOyXrOu2gOulvCDtmZXsnbjtlZwg6rKw6rO8IO2ajOybkOuLmOq7mOyEnCDsiJjsi6Drj5nsnZjrpbwg7ZWY7IWo6riw7JeQIOuwnOyGoeuQmOyXiOyKteuLiOuLpC4JCQkJCQkJCTwvcD4KCQkJCQkJCQoJCQkJCQkJCQkJCQkJCQk8cCBzdHlsZT0ibWFyZ2luOjA7dGV4dC1hbGlnbjpsZWZ0O2xpbmUtaGVpZ2h0OjE4cHg7Ij4KCQkJCQkJCQkJ66mU7J28IOyImOyLoOydhCDsm5DsuZgg7JWK7Jy87Iuc66m0IDxhIHRhcmdldD0nX2JsYW5rJyBocmVmPSdodHRwczovL2RpcmVjdHNlbmQuY28ua3IvaW5kZXgucGhwL21haWxfcmVwb3J0X2FwaS9yZWplY3QvSy8xNTY0NzA1OTMvMjYyNzA3NDI0L21rdEBjb210cnVlLmNvbSc+PGI+W+yImOyLoOqxsOu2gF08L2I+PC9hPuulvCDtgbTrpq3tlZjshLjsmpQuPGJyIC8+SWYgeW91IGRvbid0IHdhbnQgdGhpcyB0eXBlIG9mIGluZm9ybWF0aW9uIG9yIGUtbWFpbCwgcGxlYXNlIGNsaWNrIHRoZSA8YSB0YXJnZXQ9J19ibGFuaycgaHJlZj0naHR0cHM6Ly9kaXJlY3RzZW5kLmNvLmtyL2luZGV!
4LnBocC9tYWlsX3JlcG9ydF9hcGkvcmVqZWN0L0UvMTU2NDcwNTkzLzI2MjcwNzQyNC9ta3RAY29tdHJ1ZS5jb20nPjxiPlt1bnN1YnNjcmlwdGlvbl08L2I+PC9hPgkJCQkJCQkJPC9wPgoJCQkJCQkJCgkJCQkJCQkJCQkJCQkJCTxwIGNsYXNzPSJzZW5kZXJfaW5mbyIgc3R5bGU9InRleHQtYWxpZ246bGVmdDtsaW5lLWhlaWdodDoxOHB4OyI+CgkJCQkJCQkJCeyCrOyXheyekCDrk7HroZ3rsojtmLg6NTEwLTE2LTUyOTcxIOyGjOyerOyngDrshJzsmrjtirnrs4Tsi5wg6rCV64Ko6rWsIO2FjO2XpOuegOuhnDgy6ri4IDE1IDk3NO2YuCBURUw6MDItNTAxLTcyNDQgPGJyIC8+RW1haWw6IDxhIGhyZWY9J21haWx0bzpwamNvbnN1bHRpbmdAbmF2ZXIuY29tJz5wamNvbnN1bHRpbmdAbmF2ZXIuY29tPC9hPgkJCQkJCQkJPC9wPgoJCQkJCQkJCQkJCQkJPC90ZD4KCQkJCQk8L3RyPgoJCQkJPC90Ym9keT4KCQkJPC90YWJsZT4KCQkJPCEtLSBlbmQgZm9vdGVyIC0tPgoJCQkKCQkJPCEtLSBvcGVuIHRlbXBsYXRlIC0tPgoJCQk8aW1nIHNyYz0naHR0cHM6Ly9kaXJlY3RzZW5kLmNvLmtyL2luZGV4LnBocC9tYWlsX3JlcG9ydF9hcGkvb3Blbi8xMDI0Njc1LzI2MjcwNzQyNC9ta3RAY29tdHJ1ZS5jb20nIHN0eWxlPSdkaXNwbGF5Om5vbmUnPgkJCQoJCTwvZGl2PgoJCTwhLS0gZW5kIGRpdiBmaXJzdCAtLT4KPC9odG1sPgo=
----82be5ca2-6dee-48ed-b547-ff9b31858929--
enmime does not enforce a line-length on text parts. It should wrap the content in a way that preserves the original bytes upon decoding.
Hi!
I'm using this excellent library on one of my project. I'm happy with it, but unfortunately upgrading dependencies breaks my code every now and then.
I know it's still a beta, but I think it would be great to create releases to help dependency management.
Of course I can still pin the commit hash but this is suboptimal. When a BC is introduced I have to try all the intermediate commit hashes between the version I've pinned and the latest release to find the most recent compatible version. This process would be a lot easier with SemVer.
Thanks for your help on this. And thanks again for all your work on this library!
path
is for URLs, filepath
is for OS file path manipulation
cmd/mime-dump/mime-dump.go:7: "path"
cmd/mime-dump/mime-dump.go:26: basename := path.Base(os.Args[1])
cmd/mime-extractor/mime-extractor.go:9: "path"
cmd/mime-extractor/mime-extractor.go:44: basename := path.Base(*mimefile)
cmd/mime-extractor/mime-extractor.go:59: newFileName := path.Join(*outdir, a.FileName)
It would be really nice to support some transfer encodings when building the email. UTF-8 Base64 is the main one I would like to use, but of course, built in a way to support other encodings.
There is a way to Base64 encode the subject as well.
=?utf-8?B?<SINGLE BASE64 LINE>?= =?utf-8?B?<ANOTHER BASE64 LINE?=
The point is so that the email can be sent without having to worry about special characters.
Would like to know if you like this idea or not?
Create fluent builder struct to simplify constructing a well formed message
net/mail.Address
NOTE: this issue is kind of related with the "Address Envelope's Parts with sensible IDs" issue.
Idea:
multipart/alternative
|-- text/plain
|-- multipart/related
| `-- text/html
`-- text/plain
I would like to read and store the content from each invidual text/HTML Part.
Right now, enmime creates two Envelope fields i.e. e.Text and e.HTML.
While creating the Envelope (EnvelopeFromPart), it reads the content buffer for text/HTML parts and appends them to the e.Text/e.HTML fields.
However, when I later try to read the content from one of the text/HTML Part, its content buffer is empty.
-> Ideally, I would like to be able to retrieve the text/HTML content from a specific text/HTML Part.
See this pull request for how this could be achieved: #37
Now that we have AddChild()
, the parent parameter is redundant.
Consider removing NewPart()
entirely.
Testing: mention -update flag in golden file failure text
String() string
should be renamed to Error
I have collected a small list of logs for unsupported charsets. Here's the list:-
As far as I understand ISO646-US is "us-ascii", ISO: Western is "iso8859" and cp936 is "gb2312". Is this correct?
I have been unable to figure out the rest of the encodings although cp-850 and ibm850 seem to be the same.
Does anyone have an idea about these charsets and if they can be supported in this library easily?
I try to export an email's attachment(Zip archive), but that exported file could not be unzip successfully.I compare this file to which exported by emali client, like follows:
50 4B 03 04 14 00 08 00 08 00 EF BF BD 02 29 4A
-->export by enmime
50 4B 03 04 14 00 08 00 08 00 C2 02 29 4A 00 00
-->export by email client
It's clearly that the byte 'C2' transfers to 'EF BF BD 02', I also check the implementation of Part's Read method:
return p.utf8Reader.Read(b)
OK, maybe it causes the issue when I need to read a binary file. So can export a METHOD for read the decoded binary content?
In such MIME Tree:
multipart/alternative
|-- text/plain
`-- text/plain
I have observed that enmime doesn't correctly set the Part.boundary field for the root.
Indeed, if I try to read root.boundary or the Part.Parent.boundary for the "text/plain" Parts, it outputs an empty result.
This fix also give us the possibility of simplifying func parseParts(parent *Part, reader *bufio.Reader, boundary string) error
into func parseParts(parent *Part, reader *bufio.Reader) error
cf. #39
See this pull request for how this could be achieved: #39
Implement the ability to create an email with enmime.
Envelope.Encode() should write out a well formed MIME email, providing the Envelope and its associate parts are properly configured.
Other work will need to be done, such as generating unique MIME part boundary strings.
multipart/altern
is not a valid Content-Type:
header.go: ctMultipartAltern = "multipart/altern"
envelope.go: if mediatype == ctMultipartAltern {
The code has been with us since early 2014: b986eca
It may not be necessary.
I have an email attachment that is being mishandled. Its a curious thing, probably some funky counting issue with the padding chars.
After some investigation I found that during the buffer sizing, or resizing, it is dropping the last quad of the base64 string... string input length is 12992, but only 12988 characters are being fed to the decoder OR the receiving buffer is sized to 9615 instead of the 9617, causing the last two bytes to be trimmed from the tail of the byte stream.
I don't know precisely which copy operation is causing the miscount and to be fare I have a service running with your processing engine and this fringe case is one out of 60,000 emails with an average of 3 attachments per.
other files process fine... perhaps we could take this offline to exchange my sample file because it contains confidential information and review it in attempt to reproduce the issue with a benign file exhibiting the same features.
fyi, I am able to decode the blob accurately using this:
f, _ := ioutil.ReadFile("base64.txt")
base64Bytes, _ := base64.StdEncoding.DecodeString(string(f))
file, _ := os.Create("decoded.xlsx")
defer file.Close()
writer := bufio.NewWriter(file)
writer.Write(base64Bytes)
defer writer.Flush()
Thoughts?
What I did:
N/A
What I expected:
I expect to always receive an Error or and *Error but the Envelope type has a []*Error
and the Part type has a []Error
What I got:
N/A
Release or branch I am using:
Master
(Please attach a sample message if you feel it will help reproduce the issue)
// Envelope is a simplified wrapper for MIME email messages.
type Envelope struct {
...
Errors []*Error // Errors encountered while parsing
...
}
// Part represents a node in the MIME multipart tree. The Content-Type, Disposition and File Name
// are parsed out of the header for easier access.
type Part struct {
...
Errors []Error // Errors encountered while parsing this part
...
}
I'm happy to make a PR if you agree that this is something which should be addressed. Thanks for the great library, btw!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.