万象直播app破解版_欧美国产日韩无遮挡在线一区二区,亚洲国产综合精品中久,强奷白丝女仆在线观看,超碰三级大陆在线

您的位置:首頁 > 軟件問答

魔獸世界私服313(聊幾款獲得移動超能版認(rèn)證的筆記本電腦)

導(dǎo)讀魔獸世界私服313文章列表:1、聊幾款獲得移動超能版認(rèn)證的筆記本電腦2、新蜂鳥開箱 沒想到入門級產(chǎn)品都已經(jīng)干得這么漂亮3、首發(fā)首日,裝313臺iPhone X的快遞車被洗劫,價值244萬

魔獸世界私服313文章列表:

魔獸世界私服313(聊幾款獲得移動超能版認(rèn)證的筆記本電腦)

聊幾款獲得移動超能版認(rèn)證的筆記本電腦

身為PC技術(shù)的上游供應(yīng)商,Intel這幾年一直在推出各種標(biāo)準(zhǔn),比如早期的“UltraBook超極本”、“2 in 1二合一筆記本”等等,老玩家應(yīng)該都比較熟悉,前者引領(lǐng)了筆記本電腦輕薄化,后者帶來了翻轉(zhuǎn)觸屏功能。

針對目前的輕薄本市場,Intel在年初又推行出一套全新的認(rèn)證標(biāo)準(zhǔn),叫做“移動超能版”:

移動超能版有[六大標(biāo)準(zhǔn)],細(xì)說的話太復(fù)雜,一句話總結(jié):擁有移動超能版認(rèn)證的筆記本,都是中高端的優(yōu)秀輕薄本。

今天我們就來舉個栗子,聊幾款最典型的[移動超能版]筆記本電腦:

戴爾 XPS13 9300

機(jī)身左側(cè)

機(jī)身右側(cè)

它的配置如下:

i7-1065G7 處理器

16GB 內(nèi)存

1TB 固態(tài)硬盤

13.4英寸 4K分辨率(16:10) 90?I-P3色域 IPS觸屏

厚 14.8mm

機(jī)身重 1.27kg

適配器重 221g

目前售價16999元

優(yōu)點:屏幕素質(zhì)極高,屏占比高,機(jī)身做工非常棒

缺點:接口種類單一,高負(fù)載下表面溫度較高

上圖是戴爾 XPS13 9300的拆機(jī)實拍圖,雙風(fēng)扇 單熱管 雙散熱鰭片的組合。

【購買建議】

Dell XPS13 9300是最新一批移動超能版筆記本,它的屏幕素質(zhì)表現(xiàn)極強(qiáng),4K分辨率的它實測色域容積為84.7?I P3,色域覆蓋為84.6?I P3,平均△E為2.1,最大△E為4.07。

PCMark10實測續(xù)航在4K屏下能達(dá)到9小時12分鐘(場景:現(xiàn)代辦公),符合Intel移動超能版認(rèn)證。

如果你對筆記本的顏值、做工,以及長續(xù)航時間和高性能有要求,那么這臺戴爾XPS13 9300比較適合你。

如果你對翻轉(zhuǎn)觸屏有需求,這臺電腦非常騷氣:

惠普 Spectre x360 13

機(jī)身左側(cè)

機(jī)身右側(cè)

它的配置如下:

i7-1065G7 處理器

8GB 內(nèi)存

1TB 固態(tài)硬盤

13.3英寸 1080p分辨率 100%sRGB色域 IPS觸屏

厚 17mm

機(jī)身重 1.2kg

適配器重 350g

目前售價10188元

優(yōu)點:做工精致,續(xù)航給力

缺點:i5版無16GB內(nèi)存可選,觸控筆需另購

上圖是惠普 Spectre x360 13的拆機(jī)實拍圖,3熱管雙風(fēng)扇的組合。它不再使用主板倒裝的設(shè)計,拆解簡單了許多,厚度加大的同時散熱模組也能得到升級。

【購買建議】

惠普Spectre x360 13同樣通過了“Intel移動超能版”認(rèn)證,其關(guān)鍵之一就是采用了i7-1065G7處理器。

續(xù)航是它的優(yōu)勢之一,經(jīng)過PCmark10續(xù)航測試后,成績?yōu)?4小時50分鐘(場景:現(xiàn)代辦公)這個成績遠(yuǎn)遠(yuǎn)超出intel所要求的9小時時長。

作為一臺翻轉(zhuǎn)觸摸本,Spectre x360 13的表現(xiàn)不錯,惠普也是非常擅長推出翻轉(zhuǎn)本的品牌,如果你的預(yù)算在萬元左右,那么這款超長續(xù)航的翻轉(zhuǎn)本一定很適合你。

上面那兩臺電腦都很高級,但性價比一般,下面這臺電腦依舊是移動超能版認(rèn)證,且?guī)в蟹D(zhuǎn)觸控功能,但相對更實惠一些:

聯(lián)想 YOGA C940

機(jī)身左側(cè)

機(jī)身右側(cè)

它的配置如下:

i7-1065G7 處理器

16GB 內(nèi)存

1TB 固態(tài)硬盤

14英寸 4K分辨率 90?I-P3色域 IPS觸屏

厚 14.2mm

機(jī)身重 1.35kg

適配器重 334g

目前售價10999元

優(yōu)點:廣色域DC調(diào)光4K屏 標(biāo)配壓感筆 16GB內(nèi)存

缺點:高負(fù)載下核心溫度會比較高,并且拆機(jī)不易

上圖是YOGA C940的拆機(jī)實拍圖,雙熱管,一大一小雙風(fēng)扇的組合。

相比上一代C930多了一根熱管,左側(cè)風(fēng)扇也明顯加大。

【購買建議】

YOGA C940是咱們今天要聊的幾臺機(jī)器中最薄的,它的厚度僅有14.2mm,這也是移動超能版筆記本的特性之一,結(jié)合超薄機(jī)身與性能。

值得一提的是,移動超能版筆記本支持“即時工作”特性。

可以看上圖,一樣是休眠模式喚醒,搭載“即時工作”功能的筆電亮屏速度與手機(jī)一樣迅速,這才是現(xiàn)代PC應(yīng)有的使用體驗。

這臺售價萬元的輕薄筆記本不僅保留了CNC工藝、玻璃面板,本身的性能也釋放也不錯,如果你對筆記本的存儲配置要求較高,那么標(biāo)配16GB內(nèi)存和1TB固態(tài)的C940顯然是你的菜。

一直在聊萬元以上的移動超能版筆記本,那么主流價位是否有綜合體驗不錯的認(rèn)證產(chǎn)品呢?

華碩 靈耀14

機(jī)身左側(cè)

機(jī)身右側(cè)

它的配置如下:

i7-1065G7 處理器

16GB 內(nèi)存

512GB 固態(tài)硬盤

14英寸 1080p分辨率 100%sRGB色域覆蓋 IPS屏

電池容量 67Wh

厚 15.1mm

機(jī)身重 1.19kg

適配器重 209g

首發(fā)售價6499元

優(yōu)點:同價位中做工較好,便攜性和接口拓展性都不錯

缺點:采用低性能QLC固態(tài),耳機(jī)接口需要轉(zhuǎn)接

上圖是華碩 靈耀14的拆機(jī)實拍圖,單熱管單風(fēng)扇的組合。

【購買建議】

這是我們今天的機(jī)器中最便宜的,但它配置并沒有因此縮水,依然采用i7-1065G7處理器,保證日常使用的峰值性能以及不錯的顯卡性能發(fā)揮。

接口方面,靈耀14擁有兩個Thunderbolt3接口,方便各類設(shè)備的拓展,甚至可以外接顯卡拓展塢獲得更好的性能。

需要注意的是,Thunderbolt3也是移動超能版認(rèn)證中的必要條件。

所以如果你的預(yù)算是在7000元左右,對于續(xù)航能力和外接拓展的能力有一定的需求,那么靈耀14的綜合表現(xiàn)不錯,可以考慮購買。

客觀地說,移動超能版認(rèn)證機(jī)型普遍偏貴,但也有宏碁SF313這種5000元以內(nèi)的性價比型號,并且無論是5000內(nèi)還是大幾萬,WiFi6都是標(biāo)配。

在我看來,該認(rèn)證所帶來的技術(shù)層面意義有限,但可以像當(dāng)年普及Ultrabook超極本一樣,不僅高端滿足認(rèn)證要求,入門級產(chǎn)品也能“接近認(rèn)證要求”,做不到超薄,也能比較薄嘛~

我相信,這才是設(shè)立認(rèn)證門檻,且能福利到消費者的關(guān)鍵所在。

新蜂鳥開箱 沒想到入門級產(chǎn)品都已經(jīng)干得這么漂亮

猜猜它賣多少錢?大膽點!

配備十代酷睿平臺的筆記本電腦產(chǎn)品已經(jīng)從高端逐步走向主流甚至曾經(jīng)的入門級別產(chǎn)品,比如剛剛到達(dá)CHIP實驗室的這款宏碁Swift 3 2020款(SF313-52-74F1)機(jī)型,已經(jīng)全部更新為10nm的Ice Lake-U平臺,并保持非常高的性價比,頂配機(jī)型也只要6000元出頭,配備酷睿i5的中配機(jī)型價格不到5000元。

依然樸素的宏碁式雙層無印刷瓦楞紙包裝,標(biāo)志著這款產(chǎn)品的市場定位。

再生紙卡擋、回收PET包裝袋、回收PP屏幕保護(hù)膜,全面環(huán)保的包裝。

專用圓形接口的65W電源,沒有直接配USB-C接口電源。

線條簡潔的外觀設(shè)計,金屬機(jī)身已經(jīng)普及到入門級產(chǎn)品上。

重點在這里,除了十代酷睿平臺之外,Iris Plus核顯為超薄平臺增色不少,無論是CPU還是GPU,傳統(tǒng)的性能與面向未來的AI性能都進(jìn)一步提升,大幅的!稍后的測試會帶來更多詳細(xì)數(shù)據(jù),敬請期待。

主要升級特性一目了然,重點都看到了嗎!

入門級產(chǎn)品配備全功能全速Thunderbolt 3接口!高規(guī)格,贊一個!當(dāng)然,這個特性能下放,與十代酷睿直接將控制器集成在平臺內(nèi)有100%的關(guān)聯(lián)度。用它一線連接,數(shù)據(jù)、網(wǎng)絡(luò)、擴(kuò)展、充電、顯示,一個接口全部搞定。

漂亮的腰線,真實的輕薄,而不是靠視覺欺騙實現(xiàn)。

屏幕長寬比從曾經(jīng)流行的16:9向3:2的變化,不僅使13英寸機(jī)型有了趕超14英寸機(jī)型的垂直視角,同時在確保全鍵盤尺寸前提下,帶來了更大的觸摸板。另一件有利的變化是位于觸摸板下方的電池模塊可以做得更大,整機(jī)續(xù)航時間更長。

三維尺寸變化,最顯著的是整機(jī)寬度的縮小,幾乎就是14英寸機(jī)型豎著裁掉了一塊。

借由功耗低、性能更好的酷睿平臺,Swift蜂鳥系列將輕薄再次演繹,今天的標(biāo)準(zhǔn)是56Wh電池、2K分辨率13英寸屏幕規(guī)格下,16mm厚1.19kg重,隱藏參數(shù)還包括Gb/s級別的Wi-Fi 6 、LPDDR4內(nèi)存、NVMe SSD,性能表現(xiàn)詳見稍后放出的測試。

---------------------------------------------------------

免責(zé)聲明:

1.本文援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息,僅代表作者本人觀點,與本網(wǎng)站無關(guān)。

2.本文僅供讀者參考,本網(wǎng)站未對該內(nèi)容進(jìn)行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。

首發(fā)首日,裝313臺iPhone X的快遞車被洗劫,價值244萬人民幣

據(jù)CNET報道,在iPhone X全球首發(fā)的今天,發(fā)生了一起惡意犯罪事件。

舊金山警方向KTSF電視臺講述稱,三名身穿連帽衫的男子駕駛一部道奇廂式貨車,搶劫了正向這里Apple Store(Stonestown店)運送iPhone X的UPS卡車。

卡車上的313臺iPhone X遭洗劫,總價值370000美元(約合人民幣244萬元)。

據(jù)悉,事件發(fā)生在當(dāng)?shù)貢r間11月2日上午11點15到11點30期間,也就是北京時間今天凌晨2點左右。

據(jù)警方報告,一個門衛(wèi)發(fā)現(xiàn)了嫌疑人卸箱的UPS卡車和道奇車并拍了照片。

知情人士透露,舊金山Stonestown蘋果店稱,當(dāng)?shù)?號開始的iPhone X首賣不會受到影響,預(yù)約用戶仍可以按時到手。

另據(jù)新京報消息,11月3日早上六點半,記者在北京市朝陽區(qū)三里屯的蘋果直營店看到,有50人左右正在排隊。今日購買仍然需要網(wǎng)上提前預(yù)約,所以沒有出現(xiàn)大面積排隊的現(xiàn)象。

由難到易,這3種自動發(fā)送測試報告的神仙方法,建議碼住

請點擊輸入圖片描述(最多18字)

前言

每當(dāng)測試結(jié)束后,測試人員都會輸出一份詳細(xì)的測試報告給到領(lǐng)導(dǎo)或者組內(nèi)人員,那么當(dāng)我們自動化測試結(jié)束后的時候,也可以讓其自動發(fā)送測試報告。

這樣領(lǐng)導(dǎo)和組內(nèi)的成員就能看到自動化測試每次測試的內(nèi)容了。安靜先介紹下如何通過Python發(fā)送郵件,再通過簡單的小例子在自動化測試過程中自動發(fā)送報告。

smtplib

smtplib是屬于Python發(fā)送郵件的一個庫。其簡單的原理是通過SMTP的方式來實現(xiàn)發(fā)送報告的。SMTP(Simple Mail Transfer Protocol)即簡單郵件傳輸協(xié)議,它是一組用于由源地址到目的地址傳送郵件的規(guī)則,由它來控制信件的中轉(zhuǎn)方式。

smtplib中對其SMTP的協(xié)議進(jìn)行了一個封裝,其中email是用來支持發(fā)送文本、圖片和攜帶附件等功能。

登錄郵箱

發(fā)送郵件前肯定需要登錄郵箱了,這里安靜先通過163的郵箱進(jìn)行介紹,登錄是通過smtplib這個庫進(jìn)行來完成的。

這里需要先確認(rèn)發(fā)件人的郵箱是否開通了SMTP郵箱權(quán)限,可以登錄到163郵箱中,選擇SMTP/IMAP中選擇開啟SMTP服務(wù)。勾選后進(jìn)行連接登錄:

import smtplib# 創(chuàng)建smtplib服務(wù)smtp = smtplib.SMTP()# 服務(wù)器地址smtpserver = 'smtp.163.com'# 發(fā)送賬號user = 'XXXXXXXX@163.com'# 發(fā)送密碼password = 'xxxxxxx'# 收件人receivers = '821006052@qq.com'# 連接服務(wù)器smtp.connect(smtpserver)# 登錄郵箱賬號smtp.login(user, password)

(左右滑動查看完整代碼)

郵件發(fā)送類型

郵件發(fā)送通過Python中的email的庫來實現(xiàn)的,其中email發(fā)送郵件可以支持多類型,比如純文本、純圖片、文本加附件等方法,這里安靜會一個個進(jìn)行介紹。

文本發(fā)送

發(fā)送郵件肯定包含發(fā)送人、收件人、郵件標(biāo)題、郵件內(nèi)容等內(nèi)容,這里email中的Mimetext的方法可以幫助我們實現(xiàn)發(fā)送純文本內(nèi)容。

import smtplibfrom email.mime.text import MIMEText# 創(chuàng)建smtplib服務(wù)smtp = smtplib.SMTP()# 服務(wù)器地址smtpserver = 'smtp.163.com'# 發(fā)送賬號user = 'xxxxxxx@163.com'# 發(fā)送密碼password = 'xxxxxxx'# 收件人receivers = '821006052@qq.com'# 郵件標(biāo)題subject = '自動化測試報告'# 發(fā)送內(nèi)容 (文本內(nèi)容,發(fā)送格式,編碼格式)message = MIMEText('這是測試文本內(nèi)容,自動化測試通過', 'HTML', 'utf-8')# 發(fā)送地址message['From'] = user# 接收地址message['To'] = receivers# 郵件標(biāo)題message['subject'] =subject# 連接服務(wù)器smtp.connect(smtpserver)# 登錄郵箱賬號smtp.login(user, password)# 發(fā)送賬號信息smtp.sendmail(user,receivers,message.as_string())# 關(guān)閉smtp.quit()

(左右滑動查看完整代碼)

通過執(zhí)行后可以發(fā)現(xiàn),QQ郵箱已經(jīng)成功的收到了郵件信息。

?

圖片發(fā)送

正常發(fā)送郵件只需要將郵件全部都復(fù)制粘貼到郵件中就行了。但是這里我們通過Python進(jìn)行發(fā)送郵箱,需要用到email中的MIMEimage的模塊了。

這個模塊可以幫助我們將我們需要的圖片內(nèi)容添加到郵件中,需要我們將本地的圖片導(dǎo)入到html中,通過html中進(jìn)行發(fā)送,如果你通過鏈接的形式發(fā)送會失敗,郵件會識別成惡意鏈接,從而進(jìn)行攔截。這里安靜這接在上面的代碼中進(jìn)行加入HTML格式,將圖片嵌套在html文本中發(fā)送:

import smtplibfrom email.mime.text import MIMETextfrom email.mime.image import MIMEImagefrom email.mime.multipart import MIMEMultipart# 創(chuàng)建smtplib服務(wù)smtp = smtplib.SMTP()# 服務(wù)器地址smtpserver = 'smtp.163.com'# 發(fā)送賬號user = 'xxxxxx@163.com'# 發(fā)送密碼password = 'xxxxxx'# 收件人receivers = '821006052@qq.com'# 郵件標(biāo)題subject = '自動化測試報告中加入圖片'# 發(fā)送內(nèi)容 (文本內(nèi)容,發(fā)送格式,編碼格式)text = '''<html><head>自動化測試報告中帶圖片</head><body><p><p><img src="cid:anjing"></p><p></body></html>'''message = MIMEMultipart()body = MIMEText(text, 'html', 'utf-8')f = open('123.jpg','rb')mag = MIMEImage(f.read())f.close()# 定義圖片ID在HTML中展示mag.add_header('Content-ID', 'anjing')# 添加圖片信息message.attach(mag)# 添加正文message.attach(body)# 發(fā)送地址message['From'] = user# 接收地址message['To'] = receivers# 郵件標(biāo)題message['subject'] =subject# 連接服務(wù)器smtp.connect(smtpserver)# 登錄郵箱賬號smtp.login(user, password)# 發(fā)送賬號信息smtp.sendmail(user,receivers,message.as_string())# 關(guān)閉smtp.quit()

(左右滑動查看完整代碼)

通過執(zhí)行上面的代碼可以看到QQ郵箱,已經(jīng)接收到了郵件信息,打開郵箱清楚的看到,圖片已經(jīng)在文本中添加了。

?

附件發(fā)送

發(fā)送郵件需要帶附件的情況下,我們可以使用email庫中的MIMEMUltipart模塊。

import smtplibfrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipart# 創(chuàng)建smtplib服務(wù)smtp = smtplib.SMTP()# 服務(wù)器地址smtpserver = 'smtp.163.com'# 發(fā)送賬號user = 'xxxxxx@163.com'# 發(fā)送密碼password = 'xxxxxx'# 收件人receivers = '821006052@qq.com'# 郵件標(biāo)題subject = '自動化測試報告中附件'message = MIMEMultipart()body = MIMEText('自動化測試報告攜帶附件內(nèi)容', 'html', 'utf-8')# 添加正文message.attach(body)att = MIMEText(open('123.jpg', 'rb').read(), 'base64', 'utf-8')att["Content-Type"] = 'application/octet-stream' # 死格式# filename 表示附件的名稱att["Content-Disposition"] = 'attachment; filename="fujian.jpg"'# 郵件中添加附件message.attach(att)# 發(fā)送地址message['From'] = user# 接收地址message['To'] = receivers# 郵件標(biāo)題message['subject'] =subject# 連接服務(wù)器smtp.connect(smtpserver)# 登錄郵箱賬號smtp.login(user, password)# 發(fā)送賬號信息smtp.sendmail(user,receivers,message.as_string())# 關(guān)閉smtp.quit()

(左右滑動查看完整代碼)

通過執(zhí)行代碼清楚的看到郵件中已經(jīng)攜帶了附件內(nèi)容,并且成功發(fā)送了。

zmail郵件

一些測試同學(xué)看到上面這么多代碼估計腦袋就大,安靜在給大家介紹一種簡單方便的發(fā)送郵件庫zmail,這個庫的目的就是為了方便發(fā)送郵件。

但是要注意zmail這個庫目前只支持Python3不支持Python2,想必都2021年了,沒人再用Python2了吧。

安裝:

pip install zmail

(左右滑動查看完整代碼)

文本發(fā)送

繼續(xù)從文本發(fā)送,先創(chuàng)建一個zmail服務(wù),將其發(fā)件人郵箱賬號以及郵箱授權(quán)碼(163設(shè)置中的SMTP打開)進(jìn)行連接通過zmail服務(wù)連接。編輯文本進(jìn)行發(fā)送:

import zmail# 發(fā)件人username = 'xxxxxx@163.com'# 授權(quán)碼密碼password = 'xxxxxx'# 創(chuàng)建zmail服務(wù)server= zmail.server(username,password)# 郵件主題body = { 'subject': "自動化測試報告", # 郵件標(biāo)題 "content_text": '這是郵件的文本內(nèi)容,自動化測試結(jié)果', # 郵件文本}# 收件人receivers = '821006052@qq.com'# 發(fā)送郵件server.send_mail(receivers,body)

(左右滑動查看完整代碼)

通過代碼就可以看出來很清楚的就講郵件內(nèi)容展現(xiàn)出來,執(zhí)行代碼,成功的收到郵件信息。

?

圖片發(fā)送

同樣文本發(fā)送完成后,繼續(xù)來我們的圖片發(fā)送。這里可以通過圖片的base64的格式加入到html的代碼中,然后放入到文本中進(jìn)行發(fā)送。

import zmail# 發(fā)件人username = 'xxxxx@163.com'# 授權(quán)碼密碼password = 'xxxxxx'# 創(chuàng)建zmail服務(wù)server= zmail.server(username,password)html = '''<p> 這是郵件的文本內(nèi)容,自動化測試結(jié)果 </p><img src='data:image/jpg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD//gAQTGF2YzU3LjI0LjEwMgD/2wBDAAgMDA4MDhAQEBAQEBMSExQUFBMTExMUFBQVFRUZGRkVFRUUFBUVGBgZGRscGxoaGRocHB4eHiQkIiIqKiszMz7/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsBAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKCxAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4 Tl5ufo6erx8vP09fb3 Pn6EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4 Tl5ufo6ery8/T19vf4 fr/wAARCAH0AfQDARIAAhIAAxIA/9oADAMBAAIRAxEAPwD3aigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACsV9Y0yJ2je/skdTgq1xCrA hBcEGgAA2qarBgCpDA9CDkUAADqKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAA898VWetX1v5OnPGkRRxOvmBJJckYRSU UYBz 8XduIbisPxzros7U6fCx8 5X95jPyQHIPOR80mNuOfl3ZxkUAAHzRSUAAGja313YsXtriWAnqY3Zcj0OCM/jWdQAAe1aJ49uYpVj1MiaFuPOWNRJGezFUwrKO4C7u4zjB8VoAAPuu1uoL2CO4t5BLFIMq69COnfBBBBBB5BGK VvDfim40NxE4M1ozZeP JM9XiPHPTIPyt7daAAD60pAQwBHfmgAAWigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAAPFn8AveXTXN/qck7SHdJshVHJxwFdndVC8ADy8bRgAV7TQAAcTZeEtFsowgtI5zxl7gCV2wT1z8g iqoPeu2oAAM3 z7LyPs32W38jj9yIkEfDbvuYC/e5rSoAAPM9Y8E6dqQVrcLYSL1MMa Ww/2ogUGR2KlevOeK9MoAAPAv FbNn/kJDH/AF7c/wDo/wCtdXrvjaz0wvDahbu4GVOD 5jbHG5h9/nGVT3G4EUAAHp6rtULknAAyepx3P8AWvlaXUfFHiD/AFYvGikZlC28bRwYY4KM6gKyjgfvXbA6nrQAAfVW4A4yMntmvkC48K67bRtLJYy7V67Hjlb8Fjd3I9SBigAA wa I4NW1G1P7m8uouckLNIATnPI3YPPXNAAB9uV8v6f491W2ZRc Vdx5G7cgSTbxna0e1c/7ytQAAfUFYOlaxZazCZbSTdtwHRhteNmGQGX q5U4OCcGgAA3qKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAK858Q LrTRt8EX7 728J/yzjJxgytx2OQq/NxzjINAAB2WoajaaXAZ7qVYkBwM8lmPRVUZZj9PcngGvjfUtUutWuHuLpg7tjHULGq5wka5wq8/nz1JoAAPRdR8Sap4nnNhp0LJFJuHlqcSSIP4pXyFRe5GQvOGLV5Qs0iAhHZNwKttONynqrYxkex4oAAPojRfAVtbrHNqJ8 bO7yVP7lfQNxukPr0XqMEc1x/gbV71dQh08yF7aRZf3bc WQjPuQ9Vyw5H3TuJxnmgAA kY444UWONFjRRhURQqqPQKMACpaAAAooAAOZuvDukXr ZNYwM WYsq WWLdS5j27z3 bPNZ/inWRo myOjhbibMcA77j95wP9hec9NxUHrQAAfKuppBHf3aW PJWeVYtrbh5YchcNk5GOhyc1lUAAHqPgEzDWv3eNhgl83/c XGPfzNldv8PdMkhhuL6RFAn2xwN/FsQt5h9lZtoHPJQ 1AAB7bRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAVXiuIZy4iljkMbFHCMrbHXqjYztYdwaAACxRQAAFFAAAUUAABWJqmrWmkQGa6kCjB2oMGSQj FF4yeRnsM8kUAAGvJIkSM8jKiICzMxAVQOpJOAB618ja94nvdcba37i3H3YEY7TzndIeN7dMcADsBk0AAHa IfHMsxa30xjHFyGueRI4Ix 7DAGMcn5vv9CNteZ6VpUmpPK24RQW8bS3E7KWSJFBPKjBZmxhVHzHn0NAABgkEYJB5GR78kZ9 a1dT1GTU7kzuiRDYkaRRjEUSIoASNf4V749SaAADGpaAAAr6O8EeHHs1/tK5xvmiAgT5W2xvhvMJwcMwxjBGFJz14AADX8HeHBpMAu5txuriIZU5UQxsQwjwcfPwC 7oRtHQk oUAABRQAAFeX MNYlghGm2SvJeXakFY0LssJBDEAZ Z8EDAOFDHjigAA8X8Wa2dY1BtjZt7ctHCOcHn5pOv8ZHHT5Qtel GPBSQL9p1SJXkP rtmwyxj 9JjKs57L91R1 boAAHE F/CU2rMtzdAxWisODkNcYPKr0ITsz/AILk5x9QIixqqqoVVACqoAAAGAABjA9KAABsUSQxpHGoREUKqrwFVRgAVLQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAAHyFr73Ol65qK29xNEWnMhaJ3iP73EuDtYZ278fhmuk IFgYNTS6CnbdRDLZGDLF8hAHUfJ5f50AAFvw/44uYZYrfUW8 FiqCf/lrFwAC2P8AWL/eJ fknJxivF6AAD72r5g8OeMTo9rNbXCSTqBm2C7cI5ySrkkEIxIORuI545oAAPdtb1200O3MkzB5CP3UAI3yN29dqf3m7e54r5I1HULnVLl7m5fe749goAwFUDoAP/r80AAEmp6ndavcvc3L7mboo 5GvZEHOFHbv1JySaxaAADf0fSp9Zu0toeM8u5BKxqBksxAOPQZ6kgV774C0prOwku5AQ92QVBHIiTO08gMN7En0K7TQAAYHi82uh6Tb6RZqE89vMlxglkTBLOTlsu 3B9EI6DFcb46uDPrcicYgiijHBB 7vOc98ucHpjFAAB5pRQAAeq DtEW9kkv7mLzba0DEIOTLMoDBNv8QVTkgkAkqORmvcvDtqul6LaJIwTEXmyF/k2mUmRg2Txs3bTn0oAAOsR1kVWUhlYAqwOQQRkEEZyPSuDvvGei2J2 eblh1W2XzPx35WM HoAAO/rwO7 I5 dbWxHX5JJpM5Hq0SKMfQSUAAHvlfKc/jrXJWyk0UA/uxwxkfnKJG/WgAA pliRCSAMk5LdyT79fYegAFfJDeL9eb/AJfn/wC/cI/lGMUAAH17XxgniLWY2yuo3h/3pncfkxIoAAPs vlODxzrkLhnminH9ySGML09YxG/H 9QAAfVleUaR47stQlENzEbJ2ICEv5kbEkAAvsTacnuu3g5IoAAPV6KAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAAOd1vR4Nbs2tpSU5DxyDrHIAQGxkbhyQVPUHjBwa6KgAA INS0250q5e2uU2OvQ87XXJAdCQNynHB/rX2Dq2j2esweTdJnGSjrw8ZI6q3P4g5U4HHAoAAPieu01zw3eaJJh/38RyVmjRtgXPAc4wj45K547E0AAHIMV2qApB53HP3ueMDHGPrzTkR5WVFV5HbCoqgsxJPCgDJPXgDvQAAd94O0c6pqSSSRLLbW53TbiMZKt5YKn7wLDkYxgHNTaZ4e8SxxtPZrPbZ4x5v2d3xnqrshwMfx46jHegAA quAMDgCvi291HV2DWt5c3vy/ehmeQHrkb1Y5POCN34UAAF/xW6Prl80cnmqZF bO7ny1yoPohyo9hXG0AABRQAAa15qV7qDbrq5mn9A7Eqv8Aur91f AgVLYaTf6m220tpZucFgMIDjPzSNhF/E0AAGJXtmn/AA8uZGRr2ZII rRxnzJvpu2iMfX5se9AAB4nWzqtrFZahdW0LM8cMzxqWILHacfMQAM568CgAAz4YZJ3EcUbSuSMIgJZuegA5P4V0Phy5NrrOnyDb/x8JGdw4Cyny2PUchXJB7GgAA2rXwTrlyRm3W3UjO aRAB7FULyA/8AAK sqAAD5yj HN8UYyXdqrgHaqiR1J7BmKoVB5yQrfQ19G0AAHyHqnhXVtIDSPEJYQDmaE71Ud9wIDrx1JXb719bTRJPG8UgDJIrIyn JWGCPxBoAAPg tTULKXTbua1mGHibBwcgjqrA jKQR35oAAO98OeMJdGjW1mi8 38zdu3HzIg2N2wHKkdWC/Lkk8815dQAAfdVrdQXsKT28iyxSDKuvf RBHQg8g8GvlHw34ln0GUqQZbaRgZIsnKnp5kfOA/r/eAAPYgAAPrqqdrdQ3sEdxA4kikXcrDv8A4EHII6ggigAAuUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAABmX94LKHft8x2YRwxAhTLK33Y1J6Z6k/wqCe1cJ4vvZNPfSbjEjQpeBpVQgBiBlQRkMWwGK87eu7qKAADT1DQH1BkgeUC2MbefLlvtk0jE8bhiHZ0YbkO0gBVAru6AADDsdIstOCeTCu5EEYkYBpNgJO3efmxljW5QAAFFAABk3 mWWqR Xd28cwHQsMMvIJ2uMOucDO0845rWoAAPnDxh4WttLt47uxjZYtwSZCzvsJ 64znAJyG3N94rt6173qNkmo2dxavjE0bJkru2sR8r44yUbDD6UAAHxdYywwXcEk8YmiSRGkjPR0B5HPt68U27tJbK4lt5l2yRMyt/wE9RnGQeo9RQAAfcEMUUMapEiRoB8qooVQPYDAFcR4Q1ZNU0uJc/vrVVglBxn5Vwj9ScOvc/xBvSgAA7eeZLeKSaQ4SJGdj6KoJJ/IVwPjTUEs9LaDzBG94fJUnPCYzIcBWJG35D/vigAA WLmdrmeWZ/vSyPI3 87Fj pqrQAAW7ZZHniWIFpC6BABkl8jaAO/Nd74J083uro 50W1XzyVxyQygISQRhs8/7IPTrQAAfV1FAAAUUAABRQAAeAfEHSZmli1GJC8YjEU21c7CrMVdsdm3bc9sAdxXv3WgAA Cq9d8X GDY3AuLCCZoJEeSVURnSApjJ3AfKhByN3TB7UAAHkVLQAAfYnhWD7Nodgm8PmLzMjoPNYybe/K7tp9wa8 HuqtIk2nSMx8oedD3CoWAdfb5mBH1PSgAA9yooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAADy3x5aNcaUsolKeRMjCPC4lZyIxzwwZQxIxxjOR0I7PW7WO80y8hkV3Uwu2EyX3IN67QMZO5Rgd lAABNpF39u0 0uC4dpIULsP egXDjHbDggj2rxnwHrdtbK2mTYieWXzIXJ V2YKpjP91/lG3 9yOuMgAB7/RQAAFFAAAUUAABRQAAeMeOtE8 D7fBCGdObhlGZCoXCv1 4nR9ozjB6LXpWqatY6VCZLuVV4O2PgySf7KJ1bqM/wjPzEUAAHyjoutS6PfQ3CD92uUkjH8UTkFlzkEnjcuTgMB24rI1GW1nu5pLSEwQM37uNmLlRgDknn5jlsZOM4ycUAAG34h1t9bv2uBvjiUBIYyRlEHUnaBy5yx69cZIArkKAABa918DeHY5lTVbj5trsII/lIyvBkbqchvuj5SCufSgAA7nwdobaRYmSYYnutjuuGBjQD5IyDjDDJLcA5OO1ej0AABRQAAFFAAAUUAABRQAAFFAAB5frfgmy1WY3EMn2OVvv7EDo7Z U3JhvXB569evqFAAB5roPg630S4 0m4luJgrKpx5UYDDBygZix/3m289MgGvSqAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAAPlbxposWkX6SW xIrkM6xDP7tkI3cc/IxIK/iMYFfRWraNZ61AIbpM7TlJFwJIycZ2MQcbsDI6HA9BQAAeBaf481O0EUVwkNyi4Bd9wmK44JdWKsR3JQs3c55rQvvh3dpIPsdxFLGf e26N168Harqw6cjHJ6UAAGm3xIALAaduGSA32ojI7HH2fI lcJ/wAIbraqd1i5Y42bZ7baPXf 8Pbp05oAAOwl JE5x5dhEnrvmZ/5InvXDr4P15uli/TPMkCjB so546dfzoAALF54w1y/DAXAt1xkrbqIyMHqHyZfTPz1px ANZcjcbSPKKxLSscE9UOyNvmXvjKejGgAA81mle4kMksryuwyzyFmYnHQscsfTNfQlj8O7OIhru5lucEHYgEKEdw3Luf AspoAAPAbOxudQmENtC80hx8qjOBkDcx6KvIyTgCvtKy0 006PyrWCOBf8AYHLY7s3LMfdiTQAAfNM3gTWobdZVSGVzjdCkg8xOM8ltqHHQ7Gb2zX1TQAAfKmiahfeGpFZoZMXG9WtpPl81o32fLwWjdG3D5gd3THNfQ p6FYathp4iJVGEnjYxzJ9GHXHYPuA545oAANGwv4dRgSaIkBhko BInJG11ydpyD VVtJ086XaR2xmafZu cqFJBckcAnnBwT/ABYzQAAblFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAV5nrniz yb5LWO2NztCtPhjlVcHAXAOGxhju6gj60AAHplVreeO6hiniO5JUWRD0yrAEHHbg0AAFmigAAKKAAAooAACigAAKKAAAooAACuL8QeJLXQYwG/e3EgzHApwcf33PO1M8Dux6dDgAAOuM0ayLEXUO4YqmRuYLjJC9SBkZ teA D7 51fX57q7kZ5BaPtwSqqvmRgIFXC7RuJx6/N15oAAPoSigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAzdQvY9OtJ7qTG2GNnwSF3ED5UB55dsKPcivLPH pCK3gsQf9afNlAbB8tDhAR3DPlv8AtnQAAeGzT3WpXbSuXmluZcKQT8zMQoVepA6Ko6AcYrv/AAbYC91JZWU7YEWbcP7yvhBn7vznkjG75KAAD3/SbI6dp9rasctDEisdzMN2MttLc7dxO30XAwOlbNAAAUUAABRQAAFFAAAUUAABXnHinxOmiRiKDZJdSdFJyIl/vuoOcnPyDjue2CAAE/iTxPDocfloBNdOpKJkbU6YaXkHHOQP4sdq UnkaZ2eRmd3bczMxLEsSSSTnJJPJPNAABfM1xqd1mXdcTTuFzn53ZjgAHn2AGMY4xXvng/wq nEX16MTkERQ8fulbgu5/56MOAv8IJz8xwAAA3vCfhz w7dpJsG5nA34wfKQciINzk/3yPlyBjOMn0SgAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKQkKCSQABkk9APU/1oAAFpoYMAQQQRkEdCPUH VAAA6igAAKzNRvEsLK4uXOBFEzc45bHyjnjLNgD3NAAB80 J7l9U1uYIquIm zRqxVSfJ3FmJJxt3lyOeRisC2sZL6SIQfvXmkwiv8APl8bju YcepZe2WwAaAAD3bwLYfZtNa5YfPdP68eXEWVdo7ZbcffIreutc0nQIEt5LgFoIljWGP95LiNVADAfdOMY8wrmgAA7SvnjUvHl5cjy9PhFuCf9a 2WTBPy/8ATOMnoQd/XqMUAAH0DJLHCpeR0jUdWZgoGBk8nHYV4X4b0u91eb7ZeNcJbjbhnkPmXL8blJOd0Lfxfd/ur0OAAA91jkSZEkjYOjqGRlOQysMgg9wR0pyIsaqqjAUAAew6etAAA uP8Ra9FoVrvwHnkysMeR97H33G4N5a8Zx3IHGc0AAGd4o8SR6HAEiKPdSfcQnOxe8jqO3ZQcbj64NfN6/atYvVMivd3Fy5HynDk9j93YqoO3CqB2AoAAMYma8n58yaWV/9p5Hdj LMzE/Uk19VeHfC1voo86TbNdMOZCOI8jlYunqQX4LDsASKAADnvC3g8WBW8v0BuAcxRZDLDjo7YyrPnlOoXg/e6ew0AABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAB5H8QHuRp1ukZxFJPiXBILFULIpHRl Uk57qvBr029s4dQt5badd8cq7WH8iOuCpwQfUUAAHyvoPiK50J22kSwM3z2xdhk4wHjYqwU8c4 90PQVa8R F7nRHWWItNbknEio2YgCoAmPKKWZsLjAbHQdKAAD3VPF htAkzXiJuGTGVcyqeMqyIrNkE/Q9iRzXySHKkEY46A4bGe/PegAA9r8WeLbTULT7HYlpFZkeWVlKqyqQRGqsoYndgtuCgbe a8WKldodGGRuGdwLKemPb0NAABbhleN22BVcHKyoxjMfXlXUjjn VMijEzJGqSsXO1Uiw7s3RRtwCcsf8KAACMKxbG3IJUFd3XgYy2f8A9Ve2eH/AzF0udSGF6i1OCx/umVlPy pUc9j3FAABkeH/AAvNq6R3MhS3szwoVmeWQI HA5AAbDDc dv8KV9HoiRoqIqoqgKqqAFVQMAKBgAAdBQAAJFGkMaRxqERFCqoGAqqMAD8OlS0AAGPql6unWU9ywc WhICKXOe3y8cdzyBjNeN L79jI6uzbM7YwNy UfL YMON5ZjyynbjA7UAAHASHUNcuk81jd3EyhY1BVSwAJB42xJsALFF24yS3PNbXhi1mnukeKRbUh8GViGeRTxIsXHyvg/MV65oAAPYfD gWvh2AyyvH9okA8yViAqDP8Aq42bGFzjP94gH0FdU m2cu0ywrKwz80uXb5hyMtnjjp0oAAMm48SabCrFJftJAB2wbXyPZiyx8d/m XjNaZ0jTSCDZWuDnI8mPnJyc/L3PWgAA8tuvHc2Qtrp 4vyhllJYDP8cUafLx0/eV6UdC0ouX xQAlSrBV2qwbGdyrhW6D7wNAAB4TceMtddx88FuMfMkMcbY52k/vTKcgnkZHT617sug6QuMadZDHP oi7nP938vSgAA eIPG2twy7nuYrlckbJIYlU 48pYmHt82K961m3sbXTLyT7PbpiGQKRCn sdSi4GByzMAPrQAAZfhvxOmtgwyoIbpV3FBnY6jbllzkrjcMqx9xkZx5N4Mgl/tmAqWIjjlZyDlSmwpnJx/GUB7gj0oAAPpuigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAAEIDAggEEEEHoR6H tLQAAec3vgrSbvlBJbHAH7sqV UHHEivj32la7W/vI9PtJ7mQgLFGz8kDcQOEGSOWOFA7kigAA Rl0/zrl7aF/Ok88wQE7lL4l2 YF 6FxliM/Lk mauG6ijMb2wNpKGdhPGHVvmQgbUXdn5SRlCNueaAAD3yx0/R/Cse R1NwwAkmZS8z5POyJAzIm49EX03E4zXzQZ2d2YysTjcZQzCSR3O47mySSecls9KAAD7Ds9TsdQLC2uIpin3lVhuX6rwwrw/wAGRu q7o1YpFFJ5ruqswLYUIz4G3eRuQddqn3oAAPoasm/1G30 MtK67sErHn5nwCcADJ7YBxjJA70AAHN IdXt7GIRNl2kJHlKTufaAxGQRtGOpPHNeG3ktzql/JdMjxNv3AHIXY21FjG8EK 373XnNAABnGSbVHed2ZFjK7cnKqrdIxnqRg/dHXPc10Qt94jSBHRUjXIRd5VgxBaPrlmyDJwwVgB3oAAL9vbywy262kbKP8Ali0ZMqvg7jkfKUfJw3zDeB1r1nw/potbUSSRCN5CZFQ78xK5D7GD4O4NljkZBPtQAAdbCnlxov8AdUD/AD/SlkkSFGeRlRFGWZiFVQOpJOAB60AAEteVap46srOQRWsf24gZd1k2RL7KwSQufXau0ZHPWgAA9Vr5hu/G2tSunlyJbB8EJFbqx2nphpt 4np8uOlAAB9PV8q/2/4mhnVRPeCSVQBG9srE7c8JE8OM9dxRfqTQAAeg M9Qlnkh063D8OHlcBsM5GEhXA dsNkqvzZK7eRXG G9ZOmalKdRhnL3D/M8hZPs3mNuaVo2AU Y23e3ysoX5c9KAAD1/wAL6D/Y9rvlUC6mA83B3CMdo1P5F8dW7kAV3YIYAggg8gjoR6j lAAAtFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAB8169c30l/NHcTBijyD7O26NEhJ QBm2IQw2MHxuZhzkCvbdW0O01cL5yAOv/LRVTftAbC5ZWyAzZH8 TQAAfKLtcYlU7UBUEhc/w9NnJ hx0yau3dpJZvNCyh3h3E7twGFyj7fm ZQc8NhqAADNZI4naE YRwVIjUMCQM9ycfQ9qJZkmji2o48tNrjORuHCkMAW bjhuM9KAAD1qz8WWel6PFb2sRS74D7wdrsR81xvI YsoGA33MheVWvGTsA3F95OPlAIBHcHpgj29QaAADuo2kvpJLuSWW4kdl3ldqSjI6ybQMqoC4VPu4xxVrwnp0t9qPD7VjVvOdWLMUdfl2sVZM7to7HGfSgAA2rPT7q4cxxoXnRFZs7osM2MO3mKfLbdz8u48EgV75bWyWsQjQuwH8Tuzux7lmYkmgAAxtO0W2sMPjfLsRdzYONuTkcD5ssct1bvXS0AAFO4n8heEeV2DbERWOWCk4ZgpWMHGAz4H41coAAPB7/TPEXiL55oTbpkbIZJBHGgz1CrvkY8At5qq2T8vHFe8UAAHzdq/hNdJ0x7m4ui8u6NY44kxFGzn5x8xaSQbQduNh9RivWfFse/R5WDiMxy27iQ/wAGJ0G/ofugmgAA5zwFd2dxaSQ VCl5Cx8xggEssZPyyMdoPyklCAflwOma4G81BYlttf065t4LyUeXfW25NzyAjdIsOSTHIV3P9VbqTQAAfToQA56n1PX8PQe1cZoPiey1uHIZYZ0C bC5AIJ6tGSfmTdwD1HG4DNAABzXj63jktLOTLrILkRoVyRh1LEMo5YZjXHoa0tVMWq61Y2Cuki2yvc3Kg52rwqAkHGWOAV67GPrQAAdZpeRYWgJckQRgl4zExIUA5jIGzkcDHFa1AAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFVbm5htInmmcRxoMsx/oBkk gXkngUAAFqvn3XfFU99cx2ti00cDoAQiDzp2LZ4YMfkK4wFZDhm3 lAAB6JrniSPTMwxIXlwD5hRmijBPOdpDOfZemRuPavCreOSWdncPHJvcLlVeIyoceRhm25I 8A3TgdKAACO686/uZJ5DGXc73kZPLRypIBwMHywpGSPm uK6aDSft0LSRW8cifdm3vJEgdRhjuwfK2MRiJemDng0AAHHpaedceUimSWTCouwBbhuzqAPlVsb8nbuGCtfRvhnRotNhlkXYzTMNpGSY0UAeVvYliA4Y/jQAAfOuuaLdaQ0RuTGTKm7g5K9Eyy4 U m0sDjt0rs/iBJGNWgDoW22qHG4jcDLJxx0YY6 maAACz8Pjuu7rb5e1bdc5UCUszjnPPy/Kc/VatfDwr5uobMhWS3I3csdplySRkcEkds8UAAHvFFAAAUUAAFS5uEtYmkfccDhVGXc44RRxlm7VUgXz5pZmbcFYxRp/CnlnDNj z5yfQCgAA5sjXtSRmWSLSozzEuzzrlhyP3pb5IweDhV3jpkY57qgAA8Su/BGo3anz9bluCASqypKy7sdOZzj0J2/hXttAAB8Qadp0 qXcdpbhTJJnG87VG1SzEnngAH3rY1BDpuuXDBCqwXzOoX5SFEu9QvoduMUAACav4d1HRFia6jXZIWCsjb13DnaeBgkcgd8HHQ1794wmtbzw55/Xzfs81ue4LFTu6jH7tmDHtmgAA abO utPlSe2kkhZcDcmBuGc7W42sDgZDBhVfZnvtHXH3sdhnH5CgAA qPCniCTXbaTzowk8GwOy/6uRX3bXUZJU/IQw6cZHXAg8G6Zc6dYSm4Tymnl3iMptkVVUIN CeuMhf4c980AAHo9FAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFeTeIPFhgQw6aVkkK5 0/K0Y bGIs5V24JLcoMDrngAAOu1jX7XR1w376dhlYEZd3ThnJ 4mcDOCf7oOK a57yN0iMbPNMrs4ciTzMO5d2lZi6t85Ow8nBJbrigAA1b/UL/AFaVJrqWNOdirHIfLt8sUIaLlsSjncMsQc7scVXt7E305toLUmRQw8uUGO4jQAN945BxjbHlUx NAABW wXNssnmxS8Mgkkjk2iHJO1Nq5Jbk4znqOK gNB8PrpyJLNuMwHyjO3YrAZWURt5csgPVsEcDHTNAABymh Gmn z3NyoiRCCsXlhHkMW5FMse3ZyuCHHzMD2yMeykgDJ4xQAAYtyFjEECbo0b5Mr0VSpXHOevY46j3otpDPcSlxIhQ7VVihQr/ejwofngtu9RQAAcnqWoano5 aaF0kl2xAwbURdp2qdpBwoXnndk56VxfifXjfTx21k0bwow/fK/DSkspQchDgfd5HcjgigAA4rxNqM19drNNGkWbaNAFZXWUozMGxyyLlj8pOfc1zU8TpIWnVssisC6bMqRgMBgKwYD5JB8pxQAAelfDtXF9ctjCG35 bHPmJt TcMjG75tpxjqM8s8Ahk1Ns7CGspCGGc/wCuh Vv93t9aAAD6OooAACigAApW8BgM3zllklaRVI/1e4DcuedwL7nGem7HQCqd7q1hpoBurmKHJwAzfMeR0QZY9Rk4470AAGzXmt54zs7fzljjd3jGYy5VIZwDyY5F80kY5BKDPHSgAA9Kr5Zv9f13WyYYiy5Gfs1osgdgQcqwGZHXacnPyGgAAg8bJGNcuWV1k3xxNiMg WyqEKyehwmce4rmL7RdR02KOe6t3hSU4UsUyWxkgqGLL/wIDNAABnzXlxcpAk0zyLAvlwoc4ROuFxgenvwPSvRfAMME2qyCVEkKW5lj3AHbIskeHUEH5lzwe1AAB2ng/wy9u0WoXOUZBmFQCjMJEYMZQQcr8w2fdPGemK9roAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKrXFxHawvNK21I13Mev4ADJJPQAckkAUAAEV3eW1hEZrmVIUHdj1OCdqjlmbAOFXLHHAr5g1jWpNanDSiTy0VykZ2oYxIwGFIUbl4Ubm/iB6DFAAB0ureK7jUd8cMn2O3BjbdFJibazFSJTkFW6Eon3c4YtXm7LCiSO0EinbtYkDYpZePkOwg55DcjvzigAAZ9nRZdmdqv1aUYXHHzKMK3fcp9DXe6FoE2sSxTtI/lpvSacMEZSqjZGgDlzJgq7ZRVHPJPFAABj6Vo13PcpBFG7hnYNLjaiwn5fOO7 Lk4HzegBIr6bsrGKxj2puZiF3yPy8m0YBY8e AMDk tAABS0zRrTS1JiXdM4AluHJaWU4GSzHONxAJA4zXQUAAEckiRI0jsERFLMzHAVVGSSewA615d4z1IRRJZK4zIPMmiBKvJHkhYwdp V3B3FeflAPDUAAEVz4rin0/8AdsouZpXTy0ch4Iw77Xc4IJ2qMgfKxJ5xzXkcEDJMVnZbd/uh1KtxJ8xXKqfl27sn5m60AAHuvhvM1vPN5hMr4G0qyGH5eBtZmXnhgVynpmui0WFYNPgCtG4dfM3RhhGfMO4FAxPy4Ix69cDOKAAD5WOYZMTrvRGJMZVljUhwGBTIddmCpDYZulfS teHLTWUbd 6lO396gUMwXdtRjg/Llsn8PQUAAHznqOoSazcLcO0aOFCJHEg RU 6u1iMJnoAzck9a3NTgu9AuWhYIQ8R3OsauFt5SYyrfuyB9z0Xk8UAAGv4Djf 0nkMe3NvcKWAGC4lgJHHTaCOPfitLwND5l5JciGWELa Xudi3nbpAfN YA/w4 XKjBoAAPW728u4JEjt7F7kMuTJ5iIi9RjnOW7ndsXH3STxW7QAAeYXdt4l1AbC0NqMDdsbEb8ZOCrPMPmOMHjAr0 gAA8fg8Ebzuu7hJCy4fEYdiVzgq7bdvU7vkz/tCvYKAADhbfwhotv/y7ebhtw812YDrxtyFK4OCGBz/Fmu6oAAIY4o4VCRokaqMBUUKoA6AAYwPSpqAADy7x9bmbRd4/5YXEUh jbov5uK6DxXbtc6HfouMiISc9MQusrevO1Dj3oAAPnLws7W s2LKUVjIq/vD8pSUFGxjB3lW QevWsXRmVdTsC5wourfcTxgCVec9sUAAH2xRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAABga3bSXmmXcMQDSNEfLB/vr8y7eRh9wG05 VsHtW/QAAfGckeUMqkESEMQynYrDJ8re2FZsHI29yRX2E9tBIwd4YmYFSGZFLAqcqQSCcqeR6UAAHjWj EWuYPNv4/JMzCQoskofYGBWN4yxTBGcbhvTPqK9voAAKltbQ2cMcEEaxRRjCovQD8ySSckk8kkk81boAACigAAKKAADxHxfpL3V6Jh826FFVRuDKYy5yuM7yx4xgsuc16zfWCXybWeSMjo0bFSPrjGfbvgnBGTQAAfLdhpF5cSpBsO24n2q2SVDRjc7bCwU7V67sNtHy5zX0hpmkfYJZJGkV8jam1SgVSctldxXLEDJxu4HJoAAOnUBQAOABjinUAABRQAAfPXjyR49TgZGMZW1Q7xkZ/fSEAnJB2kcAr3q942WM6hCWi3N9kyJPM27QkrMwZNpBGO7HvQAAVfA8rPqs6u8zSC1fduYbCokh27U4IxliP973qPwNzqskp3jzLWXaGLMWAmiOdx5xt2jn lAAB79K/lI0mGbYCSFVmYgDJCquWZvQDk9KnoAAI0dZEV1OVZQwOCMgjI4OCK4aO6fR9VFlMxa11Bme0dnH7mUAb7fDMMISR5YXoWCgHJIAADvaKAAAooAACigAAzNRga5sbuBfvS280Y rxkD dadAAB8LRNzvJX5MNtK8NtIwuB645qYxjcwTHGUxuOZCO68d woAAPuIHIzVCxma4tLaVihaSGJyUzsJZASVzzt54zQAAaFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAAHiXjWzluby2ZUyqQ/wCsZ8IrGQ4DLg9fXj69queNYHkltmTc58mYGIAglN8RZ1cY5Bx8vpnHegAAzPB0TrqkryMrOLaRHKfcy0kTqAoAVSoB3YwvTGas EIZPtXmD/VxQm3bD5O47JQT3cY 63bJwBQAAe10UAAHN65pSatYyQkfvVDPbtuK7JghCkkfw84YenuK6SgAA888L61JfJJY3g2XtkPLky24yhflL8ksXUgCTkjJDA84HL MtCnWRtaspHSSJU81U3CTC/L5qsnPyrjd0woJzQAAe115/wCHPE9vrUaxSMkV2vDRbuJNoyXi6ZHBJXquD2oAAPQKKAAAooAAPjDUo9moXqCMhVuZlBXttmYfLngdhx9at6qXTVdS4DKbu5 VhuTmZ vI2njjPWgAA p9Ez/ZWn54P2S3/wDRS/5NZ/hhmOi2O4EFYyuDn B2Xv8ATjt6UAAHW0UAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAef8Aie2lmW3eMA7fMH8RYZ2vmNRndIyoyKO 6r3iNphbRLAheWSZUTp8nBYyZPQqqnH1NAABj H4I4rgmGO4jTZIGErZwWMbAKNg X72N3zLjA4qTw25Lunms xX8xW3uysXyqmXeyNwSR/Fg4HAoAAPRqKAAAooAAIpI0mjeORQ6OpVlPRlYYIPsQealoAAPlTXfDVz4dk 0xF5IA4MNwjFZIWzld AMMp6MMA8dDxX01fWUOo2strOCY5Vw2DgjBBBB55VgCO3HegAA8U0n4hbVWPUoWc9PPhC5IwOXi4Gc5JKEf7teUazpk2lXk1s6sqrITFu/jjJOx1PRgVHJ7NkHBBoAAPrG31/SbpN8d/a4xk7pFjYDOMskm11/EV8XA4Oev1oAAOhub2K5vbqUq5SeeWQfPggPIzBWHCn7xz lc/jd6cD19/egAA v/Cg26JZDfvwsgzz2mf5QT1C/dB9BU/hmJ4dE09ZDljAH6/wyEuo7dFYCgAA6yigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAADmteIFg5JgBDIR58nlR8NkgtyeVB4A56Vf1OMS2kgIUgbWIYkAhWBI4yegOKAADA0OCONnkDDc442fdeP5WBdQoTcpYgOPvBq0tMt1gaUKE2g4VlGDn LjJx1VTt4JGcUAAHR0UAABRQAAFFAAAUUAAHPazo8Gt2htpiU5DLIoUsjDuNwPHr0yK6GgAA apPh7qauyxy2jpuOx2eRDjsWXymwSOwZvrX0rQAAfIsXhbWnuXgWxb5cqXdQsPoWWVsBvUbSTX11QAAVLW3W0t4bdCSsMSRqW6kIoUE8DnA5q3QAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAAFO6XdBKMbsqeCBz7cgjmrTDIP0oAAMyxiSOMGM4DZYqDkbmwd3OW6dPrTbGNo1w0bRYJ4LK2dwBJynDemWGeuOKAADXooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACqd1IYYXlAZvLG/aoyzBeSoUZyWGQKAAC5UcbrKodDlWGQR/n86AACSigAAKKAACrA 7fyTh2XnGRg9OMfh3p8cfl7sEkFieecZ6j88nn1oAAJ6KAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAAPM9D1Ge0v59HvkZG8yR7N9vyPDy zcv8As/MpP 0rEMMVt6zoMWpvHcq0sdzApEbRyGLd1Kq7LlgFYkjbt6mgAA7GuC0/VbqyjS31ZW85I8tOiExvtUHG7JLybDlyq7chqAADva5U61HNlLdW3/LzINgALMpPf7pXkHb95fWgAA6SNtwJxj5mH5MRn8cZrOsWmYN5nTqpAXBLEltpGcjJ4zzQAAa9FAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAARuiuMMoYe49Rg/oSDUlAABhy6Vay5wHiJYNuidkPUEjjjDYwfbpitygAAaAF6AD6U6gAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAD/2Q=='/>'''# 郵件主題body = { 'subject': "自動化測試報告添加圖片", # 郵件標(biāo)題 "content_html": html, # html格式}# 收件人receivers = '821006052@qq.com'# 發(fā)送郵件server.send_mail(receivers,body)

(左右滑動查看完整代碼)

通過代碼執(zhí)行后可以發(fā)現(xiàn),郵件成功的收到了并且圖片和文本都存在郵件中:

附件發(fā)送

通過上面的兩個例子這里應(yīng)該很清楚的就能知道了,我們只需要將附件信息直接寫在我們的body文本中就行了。

import zmail# 發(fā)件人username = 'xxxxx@163.com'# 授權(quán)碼密碼password = 'xxxxx'# 創(chuàng)建zmail服務(wù)server= zmail.server(username,password)html = '''<p> 這個郵件中攜帶附件,自動化測試結(jié)果 </p><img src='data:image/jpg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD//gAQTGF2YzU3LjI0LjEwMgD/2wBDAAgMDA4MDhAQEBAQEBMSExQUFBMTExMUFBQVFRUZGRkVFRUUFBUVGBgZGRscGxoaGRocHB4eHiQkIiIqKiszMz7/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsBAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKCxAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4 Tl5ufo6erx8vP09fb3 Pn6EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4 Tl5ufo6ery8/T19vf4 fr/wAARCAH0AfQDARIAAhIAAxIA/9oADAMBAAIRAxEAPwD3aigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACsV9Y0yJ2je/skdTgq1xCrA hBcEGgAA2qarBgCpDA9CDkUAADqKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAA898VWetX1v5OnPGkRRxOvmBJJckYRSU UYBz 8XduIbisPxzros7U6fCx8 5X95jPyQHIPOR80mNuOfl3ZxkUAAHzRSUAAGja313YsXtriWAnqY3Zcj0OCM/jWdQAAe1aJ49uYpVj1MiaFuPOWNRJGezFUwrKO4C7u4zjB8VoAAPuu1uoL2CO4t5BLFIMq69COnfBBBBBB5BGK VvDfim40NxE4M1ozZeP JM9XiPHPTIPyt7daAAD60pAQwBHfmgAAWigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAAPFn8AveXTXN/qck7SHdJshVHJxwFdndVC8ADy8bRgAV7TQAAcTZeEtFsowgtI5zxl7gCV2wT1z8g iqoPeu2oAAM3 z7LyPs32W38jj9yIkEfDbvuYC/e5rSoAAPM9Y8E6dqQVrcLYSL1MMa Ww/2ogUGR2KlevOeK9MoAAPAv FbNn/kJDH/AF7c/wDo/wCtdXrvjaz0wvDahbu4GVOD 5jbHG5h9/nGVT3G4EUAAHp6rtULknAAyepx3P8AWvlaXUfFHiD/AFYvGikZlC28bRwYY4KM6gKyjgfvXbA6nrQAAfVW4A4yMntmvkC48K67bRtLJYy7V67Hjlb8Fjd3I9SBigAA wa I4NW1G1P7m8uouckLNIATnPI3YPPXNAAB9uV8v6f491W2ZRc Vdx5G7cgSTbxna0e1c/7ytQAAfUFYOlaxZazCZbSTdtwHRhteNmGQGX q5U4OCcGgAA3qKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAK858Q LrTRt8EX7 728J/yzjJxgytx2OQq/NxzjINAAB2WoajaaXAZ7qVYkBwM8lmPRVUZZj9PcngGvjfUtUutWuHuLpg7tjHULGq5wka5wq8/nz1JoAAPRdR8Sap4nnNhp0LJFJuHlqcSSIP4pXyFRe5GQvOGLV5Qs0iAhHZNwKttONynqrYxkex4oAAPojRfAVtbrHNqJ8 bO7yVP7lfQNxukPr0XqMEc1x/gbV71dQh08yF7aRZf3bc WQjPuQ9Vyw5H3TuJxnmgAA kY444UWONFjRRhURQqqPQKMACpaAAAooAAOZuvDukXr ZNYwM WYsq WWLdS5j27z3 bPNZ/inWRo myOjhbibMcA77j95wP9hec9NxUHrQAAfKuppBHf3aW PJWeVYtrbh5YchcNk5GOhyc1lUAAHqPgEzDWv3eNhgl83/c XGPfzNldv8PdMkhhuL6RFAn2xwN/FsQt5h9lZtoHPJQ 1AAB7bRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAVXiuIZy4iljkMbFHCMrbHXqjYztYdwaAACxRQAAFFAAAUUAABWJqmrWmkQGa6kCjB2oMGSQj FF4yeRnsM8kUAAGvJIkSM8jKiICzMxAVQOpJOAB618ja94nvdcba37i3H3YEY7TzndIeN7dMcADsBk0AAHa IfHMsxa30xjHFyGueRI4Ix 7DAGMcn5vv9CNteZ6VpUmpPK24RQW8bS3E7KWSJFBPKjBZmxhVHzHn0NAABgkEYJB5GR78kZ9 a1dT1GTU7kzuiRDYkaRRjEUSIoASNf4V749SaAADGpaAAAr6O8EeHHs1/tK5xvmiAgT5W2xvhvMJwcMwxjBGFJz14AADX8HeHBpMAu5txuriIZU5UQxsQwjwcfPwC 7oRtHQk oUAABRQAAFeX MNYlghGm2SvJeXakFY0LssJBDEAZ Z8EDAOFDHjigAA8X8Wa2dY1BtjZt7ctHCOcHn5pOv8ZHHT5Qtel GPBSQL9p1SJXkP rtmwyxj 9JjKs57L91R1 boAAHE F/CU2rMtzdAxWisODkNcYPKr0ITsz/AILk5x9QIixqqqoVVACqoAAAGAABjA9KAABsUSQxpHGoREUKqrwFVRgAVLQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAAHyFr73Ol65qK29xNEWnMhaJ3iP73EuDtYZ278fhmuk IFgYNTS6CnbdRDLZGDLF8hAHUfJ5f50AAFvw/44uYZYrfUW8 FiqCf/lrFwAC2P8AWL/eJ fknJxivF6AAD72r5g8OeMTo9rNbXCSTqBm2C7cI5ySrkkEIxIORuI545oAAPdtb1200O3MkzB5CP3UAI3yN29dqf3m7e54r5I1HULnVLl7m5fe749goAwFUDoAP/r80AAEmp6ndavcvc3L7mboo 5GvZEHOFHbv1JySaxaAADf0fSp9Zu0toeM8u5BKxqBksxAOPQZ6kgV774C0prOwku5AQ92QVBHIiTO08gMN7En0K7TQAAYHi82uh6Tb6RZqE89vMlxglkTBLOTlsu 3B9EI6DFcb46uDPrcicYgiijHBB 7vOc98ucHpjFAAB5pRQAAeq DtEW9kkv7mLzba0DEIOTLMoDBNv8QVTkgkAkqORmvcvDtqul6LaJIwTEXmyF/k2mUmRg2Txs3bTn0oAAOsR1kVWUhlYAqwOQQRkEEZyPSuDvvGei2J2 eblh1W2XzPx35WM HoAAO/rwO7 I5 dbWxHX5JJpM5Hq0SKMfQSUAAHvlfKc/jrXJWyk0UA/uxwxkfnKJG/WgAA pliRCSAMk5LdyT79fYegAFfJDeL9eb/AJfn/wC/cI/lGMUAAH17XxgniLWY2yuo3h/3pncfkxIoAAPs vlODxzrkLhnminH9ySGML09YxG/H 9QAAfVleUaR47stQlENzEbJ2ICEv5kbEkAAvsTacnuu3g5IoAAPV6KAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAAOd1vR4Nbs2tpSU5DxyDrHIAQGxkbhyQVPUHjBwa6KgAA INS0250q5e2uU2OvQ87XXJAdCQNynHB/rX2Dq2j2esweTdJnGSjrw8ZI6q3P4g5U4HHAoAAPieu01zw3eaJJh/38RyVmjRtgXPAc4wj45K547E0AAHIMV2qApB53HP3ueMDHGPrzTkR5WVFV5HbCoqgsxJPCgDJPXgDvQAAd94O0c6pqSSSRLLbW53TbiMZKt5YKn7wLDkYxgHNTaZ4e8SxxtPZrPbZ4x5v2d3xnqrshwMfx46jHegAA quAMDgCvi291HV2DWt5c3vy/ehmeQHrkb1Y5POCN34UAAF/xW6Prl80cnmqZF bO7ny1yoPohyo9hXG0AABRQAAa15qV7qDbrq5mn9A7Eqv8Aur91f AgVLYaTf6m220tpZucFgMIDjPzSNhF/E0AAGJXtmn/AA8uZGRr2ZII rRxnzJvpu2iMfX5se9AAB4nWzqtrFZahdW0LM8cMzxqWILHacfMQAM568CgAAz4YZJ3EcUbSuSMIgJZuegA5P4V0Phy5NrrOnyDb/x8JGdw4Cyny2PUchXJB7GgAA2rXwTrlyRm3W3UjO aRAB7FULyA/8AAK sqAAD5yj HN8UYyXdqrgHaqiR1J7BmKoVB5yQrfQ19G0AAHyHqnhXVtIDSPEJYQDmaE71Ud9wIDrx1JXb719bTRJPG8UgDJIrIyn JWGCPxBoAAPg tTULKXTbua1mGHibBwcgjqrA jKQR35oAAO98OeMJdGjW1mi8 38zdu3HzIg2N2wHKkdWC/Lkk8815dQAAfdVrdQXsKT28iyxSDKuvf RBHQg8g8GvlHw34ln0GUqQZbaRgZIsnKnp5kfOA/r/eAAPYgAAPrqqdrdQ3sEdxA4kikXcrDv8A4EHII6ggigAAuUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAABmX94LKHft8x2YRwxAhTLK33Y1J6Z6k/wqCe1cJ4vvZNPfSbjEjQpeBpVQgBiBlQRkMWwGK87eu7qKAADT1DQH1BkgeUC2MbefLlvtk0jE8bhiHZ0YbkO0gBVAru6AADDsdIstOCeTCu5EEYkYBpNgJO3efmxljW5QAAFFAABk3 mWWqR Xd28cwHQsMMvIJ2uMOucDO0845rWoAAPnDxh4WttLt47uxjZYtwSZCzvsJ 64znAJyG3N94rt6173qNkmo2dxavjE0bJkru2sR8r44yUbDD6UAAHxdYywwXcEk8YmiSRGkjPR0B5HPt68U27tJbK4lt5l2yRMyt/wE9RnGQeo9RQAAfcEMUUMapEiRoB8qooVQPYDAFcR4Q1ZNU0uJc/vrVVglBxn5Vwj9ScOvc/xBvSgAA7eeZLeKSaQ4SJGdj6KoJJ/IVwPjTUEs9LaDzBG94fJUnPCYzIcBWJG35D/vigAA WLmdrmeWZ/vSyPI3 87Fj pqrQAAW7ZZHniWIFpC6BABkl8jaAO/Nd74J083uro 50W1XzyVxyQygISQRhs8/7IPTrQAAfV1FAAAUUAABRQAAeAfEHSZmli1GJC8YjEU21c7CrMVdsdm3bc9sAdxXv3WgAA Cq9d8X GDY3AuLCCZoJEeSVURnSApjJ3AfKhByN3TB7UAAHkVLQAAfYnhWD7Nodgm8PmLzMjoPNYybe/K7tp9wa8 HuqtIk2nSMx8oedD3CoWAdfb5mBH1PSgAA9yooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAADy3x5aNcaUsolKeRMjCPC4lZyIxzwwZQxIxxjOR0I7PW7WO80y8hkV3Uwu2EyX3IN67QMZO5Rgd lAABNpF39u0 0uC4dpIULsP egXDjHbDggj2rxnwHrdtbK2mTYieWXzIXJ V2YKpjP91/lG3 9yOuMgAB7/RQAAFFAAAUUAABRQAAeMeOtE8 D7fBCGdObhlGZCoXCv1 4nR9ozjB6LXpWqatY6VCZLuVV4O2PgySf7KJ1bqM/wjPzEUAAHyjoutS6PfQ3CD92uUkjH8UTkFlzkEnjcuTgMB24rI1GW1nu5pLSEwQM37uNmLlRgDknn5jlsZOM4ycUAAG34h1t9bv2uBvjiUBIYyRlEHUnaBy5yx69cZIArkKAABa918DeHY5lTVbj5trsII/lIyvBkbqchvuj5SCufSgAA7nwdobaRYmSYYnutjuuGBjQD5IyDjDDJLcA5OO1ej0AABRQAAFFAAAUUAABRQAAFFAAB5frfgmy1WY3EMn2OVvv7EDo7Z U3JhvXB569evqFAAB5roPg630S4 0m4luJgrKpx5UYDDBygZix/3m289MgGvSqAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAAPlbxposWkX6SW xIrkM6xDP7tkI3cc/IxIK/iMYFfRWraNZ61AIbpM7TlJFwJIycZ2MQcbsDI6HA9BQAAeBaf481O0EUVwkNyi4Bd9wmK44JdWKsR3JQs3c55rQvvh3dpIPsdxFLGf e26N168Harqw6cjHJ6UAAGm3xIALAaduGSA32ojI7HH2fI lcJ/wAIbraqd1i5Y42bZ7baPXf 8Pbp05oAAOwl JE5x5dhEnrvmZ/5InvXDr4P15uli/TPMkCjB so546dfzoAALF54w1y/DAXAt1xkrbqIyMHqHyZfTPz1px ANZcjcbSPKKxLSscE9UOyNvmXvjKejGgAA81mle4kMksryuwyzyFmYnHQscsfTNfQlj8O7OIhru5lucEHYgEKEdw3Luf AspoAAPAbOxudQmENtC80hx8qjOBkDcx6KvIyTgCvtKy0 006PyrWCOBf8AYHLY7s3LMfdiTQAAfNM3gTWobdZVSGVzjdCkg8xOM8ltqHHQ7Gb2zX1TQAAfKmiahfeGpFZoZMXG9WtpPl81o32fLwWjdG3D5gd3THNfQ p6FYathp4iJVGEnjYxzJ9GHXHYPuA545oAANGwv4dRgSaIkBhko BInJG11ydpyD VVtJ086XaR2xmafZu cqFJBckcAnnBwT/ABYzQAAblFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAV5nrniz yb5LWO2NztCtPhjlVcHAXAOGxhju6gj60AAHplVreeO6hiniO5JUWRD0yrAEHHbg0AAFmigAAKKAAAooAACigAAKKAAAooAACuL8QeJLXQYwG/e3EgzHApwcf33PO1M8Dux6dDgAAOuM0ayLEXUO4YqmRuYLjJC9SBkZ teA D7 51fX57q7kZ5BaPtwSqqvmRgIFXC7RuJx6/N15oAAPoSigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAzdQvY9OtJ7qTG2GNnwSF3ED5UB55dsKPcivLPH pCK3gsQf9afNlAbB8tDhAR3DPlv8AtnQAAeGzT3WpXbSuXmluZcKQT8zMQoVepA6Ko6AcYrv/AAbYC91JZWU7YEWbcP7yvhBn7vznkjG75KAAD3/SbI6dp9rasctDEisdzMN2MttLc7dxO30XAwOlbNAAAUUAABRQAAFFAAAUUAABXnHinxOmiRiKDZJdSdFJyIl/vuoOcnPyDjue2CAAE/iTxPDocfloBNdOpKJkbU6YaXkHHOQP4sdq UnkaZ2eRmd3bczMxLEsSSSTnJJPJPNAABfM1xqd1mXdcTTuFzn53ZjgAHn2AGMY4xXvng/wq nEX16MTkERQ8fulbgu5/56MOAv8IJz8xwAAA3vCfhz w7dpJsG5nA34wfKQciINzk/3yPlyBjOMn0SgAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKQkKCSQABkk9APU/1oAAFpoYMAQQQRkEdCPUH VAAA6igAAKzNRvEsLK4uXOBFEzc45bHyjnjLNgD3NAAB80 J7l9U1uYIquIm zRqxVSfJ3FmJJxt3lyOeRisC2sZL6SIQfvXmkwiv8APl8bju YcepZe2WwAaAAD3bwLYfZtNa5YfPdP68eXEWVdo7ZbcffIreutc0nQIEt5LgFoIljWGP95LiNVADAfdOMY8wrmgAA7SvnjUvHl5cjy9PhFuCf9a 2WTBPy/8ATOMnoQd/XqMUAAH0DJLHCpeR0jUdWZgoGBk8nHYV4X4b0u91eb7ZeNcJbjbhnkPmXL8blJOd0Lfxfd/ur0OAAA91jkSZEkjYOjqGRlOQysMgg9wR0pyIsaqqjAUAAew6etAAA uP8Ra9FoVrvwHnkysMeR97H33G4N5a8Zx3IHGc0AAGd4o8SR6HAEiKPdSfcQnOxe8jqO3ZQcbj64NfN6/atYvVMivd3Fy5HynDk9j93YqoO3CqB2AoAAMYma8n58yaWV/9p5Hdj LMzE/Uk19VeHfC1voo86TbNdMOZCOI8jlYunqQX4LDsASKAADnvC3g8WBW8v0BuAcxRZDLDjo7YyrPnlOoXg/e6ew0AABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAB5H8QHuRp1ukZxFJPiXBILFULIpHRl Uk57qvBr029s4dQt5badd8cq7WH8iOuCpwQfUUAAHyvoPiK50J22kSwM3z2xdhk4wHjYqwU8c4 90PQVa8R F7nRHWWItNbknEio2YgCoAmPKKWZsLjAbHQdKAAD3VPF htAkzXiJuGTGVcyqeMqyIrNkE/Q9iRzXySHKkEY46A4bGe/PegAA9r8WeLbTULT7HYlpFZkeWVlKqyqQRGqsoYndgtuCgbe a8WKldodGGRuGdwLKemPb0NAABbhleN22BVcHKyoxjMfXlXUjjn VMijEzJGqSsXO1Uiw7s3RRtwCcsf8KAACMKxbG3IJUFd3XgYy2f8A9Ve2eH/AzF0udSGF6i1OCx/umVlPy pUc9j3FAABkeH/AAvNq6R3MhS3szwoVmeWQI HA5AAbDDc dv8KV9HoiRoqIqoqgKqqAFVQMAKBgAAdBQAAJFGkMaRxqERFCqoGAqqMAD8OlS0AAGPql6unWU9ywc WhICKXOe3y8cdzyBjNeN L79jI6uzbM7YwNy UfL YMON5ZjyynbjA7UAAHASHUNcuk81jd3EyhY1BVSwAJB42xJsALFF24yS3PNbXhi1mnukeKRbUh8GViGeRTxIsXHyvg/MV65oAAPYfD gWvh2AyyvH9okA8yViAqDP8Aq42bGFzjP94gH0FdU m2cu0ywrKwz80uXb5hyMtnjjp0oAAMm48SabCrFJftJAB2wbXyPZiyx8d/m XjNaZ0jTSCDZWuDnI8mPnJyc/L3PWgAA8tuvHc2Qtrp 4vyhllJYDP8cUafLx0/eV6UdC0ouX xQAlSrBV2qwbGdyrhW6D7wNAAB4TceMtddx88FuMfMkMcbY52k/vTKcgnkZHT617sug6QuMadZDHP oi7nP938vSgAA eIPG2twy7nuYrlckbJIYlU 48pYmHt82K961m3sbXTLyT7PbpiGQKRCn sdSi4GByzMAPrQAAZfhvxOmtgwyoIbpV3FBnY6jbllzkrjcMqx9xkZx5N4Mgl/tmAqWIjjlZyDlSmwpnJx/GUB7gj0oAAPpuigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAAEIDAggEEEEHoR6H tLQAAec3vgrSbvlBJbHAH7sqV UHHEivj32la7W/vI9PtJ7mQgLFGz8kDcQOEGSOWOFA7kigAA Rl0/zrl7aF/Ok88wQE7lL4l2 YF 6FxliM/Lk mauG6ijMb2wNpKGdhPGHVvmQgbUXdn5SRlCNueaAAD3yx0/R/Cse R1NwwAkmZS8z5POyJAzIm49EX03E4zXzQZ2d2YysTjcZQzCSR3O47mySSecls9KAAD7Ds9TsdQLC2uIpin3lVhuX6rwwrw/wAGRu q7o1YpFFJ5ruqswLYUIz4G3eRuQddqn3oAAPoasm/1G30 MtK67sErHn5nwCcADJ7YBxjJA70AAHN IdXt7GIRNl2kJHlKTufaAxGQRtGOpPHNeG3ktzql/JdMjxNv3AHIXY21FjG8EK 373XnNAABnGSbVHed2ZFjK7cnKqrdIxnqRg/dHXPc10Qt94jSBHRUjXIRd5VgxBaPrlmyDJwwVgB3oAAL9vbywy262kbKP8Ali0ZMqvg7jkfKUfJw3zDeB1r1nw/potbUSSRCN5CZFQ78xK5D7GD4O4NljkZBPtQAAdbCnlxov8AdUD/AD/SlkkSFGeRlRFGWZiFVQOpJOAB60AAEteVap46srOQRWsf24gZd1k2RL7KwSQufXau0ZHPWgAA9Vr5hu/G2tSunlyJbB8EJFbqx2nphpt 4np8uOlAAB9PV8q/2/4mhnVRPeCSVQBG9srE7c8JE8OM9dxRfqTQAAeg M9Qlnkh063D8OHlcBsM5GEhXA dsNkqvzZK7eRXG G9ZOmalKdRhnL3D/M8hZPs3mNuaVo2AU Y23e3ysoX5c9KAAD1/wAL6D/Y9rvlUC6mA83B3CMdo1P5F8dW7kAV3YIYAggg8gjoR6j lAAAtFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAB8169c30l/NHcTBijyD7O26NEhJ QBm2IQw2MHxuZhzkCvbdW0O01cL5yAOv/LRVTftAbC5ZWyAzZH8 TQAAfKLtcYlU7UBUEhc/w9NnJ hx0yau3dpJZvNCyh3h3E7twGFyj7fm ZQc8NhqAADNZI4naE YRwVIjUMCQM9ycfQ9qJZkmji2o48tNrjORuHCkMAW bjhuM9KAAD1qz8WWel6PFb2sRS74D7wdrsR81xvI YsoGA33MheVWvGTsA3F95OPlAIBHcHpgj29QaAADuo2kvpJLuSWW4kdl3ldqSjI6ybQMqoC4VPu4xxVrwnp0t9qPD7VjVvOdWLMUdfl2sVZM7to7HGfSgAA2rPT7q4cxxoXnRFZs7osM2MO3mKfLbdz8u48EgV75bWyWsQjQuwH8Tuzux7lmYkmgAAxtO0W2sMPjfLsRdzYONuTkcD5ssct1bvXS0AAFO4n8heEeV2DbERWOWCk4ZgpWMHGAz4H41coAAPB7/TPEXiL55oTbpkbIZJBHGgz1CrvkY8At5qq2T8vHFe8UAAHzdq/hNdJ0x7m4ui8u6NY44kxFGzn5x8xaSQbQduNh9RivWfFse/R5WDiMxy27iQ/wAGJ0G/ofugmgAA5zwFd2dxaSQ VCl5Cx8xggEssZPyyMdoPyklCAflwOma4G81BYlttf065t4LyUeXfW25NzyAjdIsOSTHIV3P9VbqTQAAfToQA56n1PX8PQe1cZoPiey1uHIZYZ0C bC5AIJ6tGSfmTdwD1HG4DNAABzXj63jktLOTLrILkRoVyRh1LEMo5YZjXHoa0tVMWq61Y2Cuki2yvc3Kg52rwqAkHGWOAV67GPrQAAdZpeRYWgJckQRgl4zExIUA5jIGzkcDHFa1AAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFVbm5htInmmcRxoMsx/oBkk gXkngUAAFqvn3XfFU99cx2ti00cDoAQiDzp2LZ4YMfkK4wFZDhm3 lAAB6JrniSPTMwxIXlwD5hRmijBPOdpDOfZemRuPavCreOSWdncPHJvcLlVeIyoceRhm25I 8A3TgdKAACO686/uZJ5DGXc73kZPLRypIBwMHywpGSPm uK6aDSft0LSRW8cifdm3vJEgdRhjuwfK2MRiJemDng0AAHHpaedceUimSWTCouwBbhuzqAPlVsb8nbuGCtfRvhnRotNhlkXYzTMNpGSY0UAeVvYliA4Y/jQAAfOuuaLdaQ0RuTGTKm7g5K9Eyy4 U m0sDjt0rs/iBJGNWgDoW22qHG4jcDLJxx0YY6 maAACz8Pjuu7rb5e1bdc5UCUszjnPPy/Kc/VatfDwr5uobMhWS3I3csdplySRkcEkds8UAAHvFFAAAUUAAFS5uEtYmkfccDhVGXc44RRxlm7VUgXz5pZmbcFYxRp/CnlnDNj z5yfQCgAA5sjXtSRmWSLSozzEuzzrlhyP3pb5IweDhV3jpkY57qgAA8Su/BGo3anz9bluCASqypKy7sdOZzj0J2/hXttAAB8Qadp0 qXcdpbhTJJnG87VG1SzEnngAH3rY1BDpuuXDBCqwXzOoX5SFEu9QvoduMUAACav4d1HRFia6jXZIWCsjb13DnaeBgkcgd8HHQ1794wmtbzw55/Xzfs81ue4LFTu6jH7tmDHtmgAA abO utPlSe2kkhZcDcmBuGc7W42sDgZDBhVfZnvtHXH3sdhnH5CgAA qPCniCTXbaTzowk8GwOy/6uRX3bXUZJU/IQw6cZHXAg8G6Zc6dYSm4Tymnl3iMptkVVUIN CeuMhf4c980AAHo9FAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFeTeIPFhgQw6aVkkK5 0/K0Y bGIs5V24JLcoMDrngAAOu1jX7XR1w376dhlYEZd3ThnJ 4mcDOCf7oOK a57yN0iMbPNMrs4ciTzMO5d2lZi6t85Ow8nBJbrigAA1b/UL/AFaVJrqWNOdirHIfLt8sUIaLlsSjncMsQc7scVXt7E305toLUmRQw8uUGO4jQAN945BxjbHlUx NAABW wXNssnmxS8Mgkkjk2iHJO1Nq5Jbk4znqOK gNB8PrpyJLNuMwHyjO3YrAZWURt5csgPVsEcDHTNAABymh Gmn z3NyoiRCCsXlhHkMW5FMse3ZyuCHHzMD2yMeykgDJ4xQAAYtyFjEECbo0b5Mr0VSpXHOevY46j3otpDPcSlxIhQ7VVihQr/ejwofngtu9RQAAcnqWoano5 aaF0kl2xAwbURdp2qdpBwoXnndk56VxfifXjfTx21k0bwow/fK/DSkspQchDgfd5HcjgigAA4rxNqM19drNNGkWbaNAFZXWUozMGxyyLlj8pOfc1zU8TpIWnVssisC6bMqRgMBgKwYD5JB8pxQAAelfDtXF9ctjCG35 bHPmJt TcMjG75tpxjqM8s8Ahk1Ns7CGspCGGc/wCuh Vv93t9aAAD6OooAACigAApW8BgM3zllklaRVI/1e4DcuedwL7nGem7HQCqd7q1hpoBurmKHJwAzfMeR0QZY9Rk4470AAGzXmt54zs7fzljjd3jGYy5VIZwDyY5F80kY5BKDPHSgAA9Kr5Zv9f13WyYYiy5Gfs1osgdgQcqwGZHXacnPyGgAAg8bJGNcuWV1k3xxNiMg WyqEKyehwmce4rmL7RdR02KOe6t3hSU4UsUyWxkgqGLL/wIDNAABnzXlxcpAk0zyLAvlwoc4ROuFxgenvwPSvRfAMME2qyCVEkKW5lj3AHbIskeHUEH5lzwe1AAB2ng/wy9u0WoXOUZBmFQCjMJEYMZQQcr8w2fdPGemK9roAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKrXFxHawvNK21I13Mev4ADJJPQAckkAUAAEV3eW1hEZrmVIUHdj1OCdqjlmbAOFXLHHAr5g1jWpNanDSiTy0VykZ2oYxIwGFIUbl4Ubm/iB6DFAAB0ureK7jUd8cMn2O3BjbdFJibazFSJTkFW6Eon3c4YtXm7LCiSO0EinbtYkDYpZePkOwg55DcjvzigAAZ9nRZdmdqv1aUYXHHzKMK3fcp9DXe6FoE2sSxTtI/lpvSacMEZSqjZGgDlzJgq7ZRVHPJPFAABj6Vo13PcpBFG7hnYNLjaiwn5fOO7 Lk4HzegBIr6bsrGKxj2puZiF3yPy8m0YBY8e AMDk tAABS0zRrTS1JiXdM4AluHJaWU4GSzHONxAJA4zXQUAAEckiRI0jsERFLMzHAVVGSSewA615d4z1IRRJZK4zIPMmiBKvJHkhYwdp V3B3FeflAPDUAAEVz4rin0/8AdsouZpXTy0ch4Iw77Xc4IJ2qMgfKxJ5xzXkcEDJMVnZbd/uh1KtxJ8xXKqfl27sn5m60AAHuvhvM1vPN5hMr4G0qyGH5eBtZmXnhgVynpmui0WFYNPgCtG4dfM3RhhGfMO4FAxPy4Ix69cDOKAAD5WOYZMTrvRGJMZVljUhwGBTIddmCpDYZulfS teHLTWUbd 6lO396gUMwXdtRjg/Llsn8PQUAAHznqOoSazcLcO0aOFCJHEg RU 6u1iMJnoAzck9a3NTgu9AuWhYIQ8R3OsauFt5SYyrfuyB9z0Xk8UAAGv4Djf 0nkMe3NvcKWAGC4lgJHHTaCOPfitLwND5l5JciGWELa Xudi3nbpAfN YA/w4 XKjBoAAPW728u4JEjt7F7kMuTJ5iIi9RjnOW7ndsXH3STxW7QAAeYXdt4l1AbC0NqMDdsbEb8ZOCrPMPmOMHjAr0 gAA8fg8Ebzuu7hJCy4fEYdiVzgq7bdvU7vkz/tCvYKAADhbfwhotv/y7ebhtw812YDrxtyFK4OCGBz/Fmu6oAAIY4o4VCRokaqMBUUKoA6AAYwPSpqAADy7x9bmbRd4/5YXEUh jbov5uK6DxXbtc6HfouMiISc9MQusrevO1Dj3oAAPnLws7W s2LKUVjIq/vD8pSUFGxjB3lW QevWsXRmVdTsC5wourfcTxgCVec9sUAAH2xRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAABga3bSXmmXcMQDSNEfLB/vr8y7eRh9wG05 VsHtW/QAAfGckeUMqkESEMQynYrDJ8re2FZsHI29yRX2E9tBIwd4YmYFSGZFLAqcqQSCcqeR6UAAHjWj EWuYPNv4/JMzCQoskofYGBWN4yxTBGcbhvTPqK9voAAKltbQ2cMcEEaxRRjCovQD8ySSckk8kkk81boAACigAAKKAADxHxfpL3V6Jh826FFVRuDKYy5yuM7yx4xgsuc16zfWCXybWeSMjo0bFSPrjGfbvgnBGTQAAfLdhpF5cSpBsO24n2q2SVDRjc7bCwU7V67sNtHy5zX0hpmkfYJZJGkV8jam1SgVSctldxXLEDJxu4HJoAAOnUBQAOABjinUAABRQAAfPXjyR49TgZGMZW1Q7xkZ/fSEAnJB2kcAr3q942WM6hCWi3N9kyJPM27QkrMwZNpBGO7HvQAAVfA8rPqs6u8zSC1fduYbCokh27U4IxliP973qPwNzqskp3jzLWXaGLMWAmiOdx5xt2jn lAAB79K/lI0mGbYCSFVmYgDJCquWZvQDk9KnoAAI0dZEV1OVZQwOCMgjI4OCK4aO6fR9VFlMxa11Bme0dnH7mUAb7fDMMISR5YXoWCgHJIAADvaKAAAooAACigAAzNRga5sbuBfvS280Y rxkD dadAAB8LRNzvJX5MNtK8NtIwuB645qYxjcwTHGUxuOZCO68d woAAPuIHIzVCxma4tLaVihaSGJyUzsJZASVzzt54zQAAaFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAAHiXjWzluby2ZUyqQ/wCsZ8IrGQ4DLg9fXj69queNYHkltmTc58mYGIAglN8RZ1cY5Bx8vpnHegAAzPB0TrqkryMrOLaRHKfcy0kTqAoAVSoB3YwvTGas EIZPtXmD/VxQm3bD5O47JQT3cY 63bJwBQAAe10UAAHN65pSatYyQkfvVDPbtuK7JghCkkfw84YenuK6SgAA888L61JfJJY3g2XtkPLky24yhflL8ksXUgCTkjJDA84HL MtCnWRtaspHSSJU81U3CTC/L5qsnPyrjd0woJzQAAe115/wCHPE9vrUaxSMkV2vDRbuJNoyXi6ZHBJXquD2oAAPQKKAAAooAAPjDUo9moXqCMhVuZlBXttmYfLngdhx9at6qXTVdS4DKbu5 VhuTmZ vI2njjPWgAA p9Ez/ZWn54P2S3/wDRS/5NZ/hhmOi2O4EFYyuDn B2Xv8ATjt6UAAHW0UAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAef8Aie2lmW3eMA7fMH8RYZ2vmNRndIyoyKO 6r3iNphbRLAheWSZUTp8nBYyZPQqqnH1NAABj H4I4rgmGO4jTZIGErZwWMbAKNg X72N3zLjA4qTw25Lunms xX8xW3uysXyqmXeyNwSR/Fg4HAoAAPRqKAAAooAAIpI0mjeORQ6OpVlPRlYYIPsQealoAAPlTXfDVz4dk 0xF5IA4MNwjFZIWzld AMMp6MMA8dDxX01fWUOo2strOCY5Vw2DgjBBBB55VgCO3HegAA8U0n4hbVWPUoWc9PPhC5IwOXi4Gc5JKEf7teUazpk2lXk1s6sqrITFu/jjJOx1PRgVHJ7NkHBBoAAPrG31/SbpN8d/a4xk7pFjYDOMskm11/EV8XA4Oev1oAAOhub2K5vbqUq5SeeWQfPggPIzBWHCn7xz lc/jd6cD19/egAA v/Cg26JZDfvwsgzz2mf5QT1C/dB9BU/hmJ4dE09ZDljAH6/wyEuo7dFYCgAA6yigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAADmteIFg5JgBDIR58nlR8NkgtyeVB4A56Vf1OMS2kgIUgbWIYkAhWBI4yegOKAADA0OCONnkDDc442fdeP5WBdQoTcpYgOPvBq0tMt1gaUKE2g4VlGDn LjJx1VTt4JGcUAAHR0UAABRQAAFFAAAUUAAHPazo8Gt2htpiU5DLIoUsjDuNwPHr0yK6GgAA apPh7qauyxy2jpuOx2eRDjsWXymwSOwZvrX0rQAAfIsXhbWnuXgWxb5cqXdQsPoWWVsBvUbSTX11QAAVLW3W0t4bdCSsMSRqW6kIoUE8DnA5q3QAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAAFO6XdBKMbsqeCBz7cgjmrTDIP0oAAMyxiSOMGM4DZYqDkbmwd3OW6dPrTbGNo1w0bRYJ4LK2dwBJynDemWGeuOKAADXooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACqd1IYYXlAZvLG/aoyzBeSoUZyWGQKAAC5UcbrKodDlWGQR/n86AACSigAAKKAACrA 7fyTh2XnGRg9OMfh3p8cfl7sEkFieecZ6j88nn1oAAJ6KAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAAPM9D1Ge0v59HvkZG8yR7N9vyPDy zcv8As/MpP 0rEMMVt6zoMWpvHcq0sdzApEbRyGLd1Kq7LlgFYkjbt6mgAA7GuC0/VbqyjS31ZW85I8tOiExvtUHG7JLybDlyq7chqAADva5U61HNlLdW3/LzINgALMpPf7pXkHb95fWgAA6SNtwJxj5mH5MRn8cZrOsWmYN5nTqpAXBLEltpGcjJ4zzQAAa9FAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAAFFAAAUUAABRQAARuiuMMoYe49Rg/oSDUlAABhy6Vay5wHiJYNuidkPUEjjjDYwfbpitygAAaAF6AD6U6gAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAAooAACigAAKKAAD/2Q=='/>'''# 郵件主題body = { 'subject': "自動化測試報告添加附件", # 郵件標(biāo)題 "content_html": html, # html格式 "attachments": "123.jpg" # 附件}# 收件人receivers = '821006052@qq.com'# 發(fā)送郵件server.send_mail(receivers,body)

(左右滑動查看完整代碼)

通過制定代碼后發(fā)現(xiàn),郵件已經(jīng)成功發(fā)送且攜帶了附件內(nèi)容。

?

yagmail

yagmail也是屬于Python發(fā)送郵件的一個庫,這種庫相比前面兩種依舊做了很大的簡介,使用更加方便,因為屬于Python的第三方庫,我們安裝。

安裝:

pip install yagmail

(左右滑動查看完整代碼)

發(fā)送文本

這里一樣先將yagmail創(chuàng)建一個服務(wù)對象,通過將發(fā)件人的賬號,授權(quán)碼進(jìn)行連接登錄。

import yagmail# 發(fā)件人username = 'xxxxxx@163.com'# 授權(quán)碼密碼password = 'xxxxxx'# 創(chuàng)建yagmail服務(wù),需要加上服務(wù)器地址server = yagmail.SMTP(username,password, host='smtp.163.com')# 收件人receivers = '821006052@qq.com'text = '這是測試報告內(nèi)容' # 報告內(nèi)容title = '自動化測試報告' # 郵件標(biāo)題server.send(contents=text,to=receivers,subject=title)

(左右滑動查看完整代碼)

通過發(fā)現(xiàn)yagmail的代碼比zmail的代碼更加簡潔了一些,但是整體內(nèi)容是差不多的。執(zhí)行代碼,發(fā)現(xiàn)我們已經(jīng)將其報告發(fā)送成功了。

?

圖片發(fā)送

yagmail中攜帶了發(fā)送圖片的方法,直接將圖片路徑方進(jìn)入就可以了,其中這里需要使用yagmai.inline的方法將圖片添加到正文中:

import yagmail# 發(fā)件人username = 'xxxx@163.com'# 授權(quán)碼密碼password = 'xxxxx'# 創(chuàng)建yagmail服務(wù),需要加上服務(wù)器地址server = yagmail.SMTP(username,password, host='smtp.163.com')# 收件人receivers = '821006052@qq.com'text = '這是測試報告內(nèi)容加上圖片顯示內(nèi)容' # 報告內(nèi)容title = '自動化測試報告攜帶圖片' # 郵件標(biāo)題img = yagmail.inline('123.jpg') # 圖片地址server.send(contents=text,to=receivers,subject=title,attachments=img)

(左右滑動查看完整代碼)

執(zhí)行代碼發(fā)現(xiàn),我們已經(jīng)成功的將圖片添加到了郵件中:

?

附件發(fā)送

附件形式y(tǒng)agmail中也提到了單獨的方法,通過attachments的方法來添加附件文件。

import yagmail# 發(fā)件人username = 'xxxxxx@163.com'# 授權(quán)碼密碼password = 'xxxxx'# 創(chuàng)建yagmail服務(wù),需要加上服務(wù)器地址server = yagmail.SMTP(username,password, host='smtp.163.com')# 收件人receivers = '821006052@qq.com'text = '這是測試報告內(nèi)容加上附件內(nèi)容' # 報告內(nèi)容title = '自動化測試報告攜帶附件' # 郵件標(biāo)題fujian = '123.jpg' # 附件server.send(contents=text,to=receivers,subject=title, attachments=fujian)

(左右滑動查看完整代碼)

通過執(zhí)行代碼發(fā)現(xiàn),我們已經(jīng)成功的將郵件攜帶附件發(fā)送成功了。

?

實戰(zhàn)演示

前面已經(jīng)將Python幾種發(fā)送報告的庫都做了一個簡單的介紹,安靜在這里在給大家通過UnitTest生成一份測試報告,然后在通過郵件的形式發(fā)送出去來進(jìn)行演示,方便大家記憶。

古話說,好記性不如爛筆頭,腦子笨,咱多寫幾遍,就記住了。

UnitTest生成報告并發(fā)送報告

安靜隨便寫幾個測試用例,然后通過HTMLTestRunner的方式生成測試報告。

import unittestimport HTMLTestRunnerclass Test(unittest.TestCase): def test_01(self): print('測試用例1') def test_02(self): print('測試用例2') def test_03(self): print('測試用例3')if __name__ == '__main__': # 測試報告地址 fp = open('result.html', "wb") # 報告詳情 runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title=u'自動化測試報告,測試結(jié)果如下:', description=u'用例執(zhí)行情況:') # 實例化 testunit = unittest.TestSuite() # 加載用例 testunit.addTests(unittest.TestLoader().loadTestsFromTestCase(Test)) # 執(zhí)行用例 runner.run(testunit) # 關(guān)閉報告 fp.close()

(左右滑動查看完整代碼)

通過執(zhí)行代碼發(fā)現(xiàn)測試報告已經(jīng)生成了,接下來我們需要通過將其測試報告內(nèi)容添加到郵件中然后在進(jìn)行發(fā)送。

郵件加入測試報告結(jié)果

上面已經(jīng)通過UnitTest單元測試框架生成了測試報告,接下來就是需要我們通過郵件庫來進(jìn)行發(fā)送了,安靜這里選擇了yagmail,別問為什么,想用哪個就用了。

import yagmail# 發(fā)件人username = 'xxxxxx@163.com'# 授權(quán)碼密碼password = 'xxxxxx'# 創(chuàng)建yagmail服務(wù),需要加上服務(wù)器地址server = yagmail.SMTP(username,password, host='smtp.163.com')# 收件人receivers = '821006052@qq.com'with open('result.html', 'rb')as f: text = f.read()title = '自動化測試結(jié)果' # 郵件標(biāo)題fujian = r'E:webresult.html' # 附件server.send(contents=text.decode('utf-8'), to=receivers, subject=title,attachments=fujian)

(左右滑動查看完整代碼)

通過執(zhí)行代碼后發(fā)現(xiàn)測試報告內(nèi)容已經(jīng)成功發(fā)送了(這里有個問題就是排版可能發(fā)生了一些改變),但是整體的報告內(nèi)容以及附件全部都發(fā)送了。

?

總結(jié)

安靜分別簡單的介紹了Python發(fā)送郵件的方法,其中有簡單的,也有復(fù)雜操作的,但是據(jù)圖使用哪種就要看個人的喜好了。

spark與spring集成做web接口

需要實現(xiàn)的功能:

寫訪問spark的接口,也就是從web上輸入網(wǎng)址就能把我們需要的信息通過提交一個job然后返回給我們json數(shù)據(jù)。

成果展示:

通過url請求,然后的到一個wordcount的json結(jié)果(借助的是谷歌瀏覽器postman插件顯示的,直接在瀏覽器上輸入網(wǎng)址是一樣的效果)

使用的關(guān)鍵技術(shù):

java語言編程,springmvc框架,tomcat容器,spark框架,scala相關(guān)依賴

成體架構(gòu):

我使用的是maven構(gòu)建的一個web工程,pom文件如下:

<dependencies>

<!-- https://mvnrepository.com/artifact/junit/junit -->

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.12</version>

<scope>test</scope>

</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-core_2.11 -->

<dependency>

<groupId>org.apache.spark</groupId>

<artifactId>spark-core_2.11</artifactId>

<version>1.6.3</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-sql_2.11 -->

<dependency>

<groupId>org.apache.spark</groupId>

<artifactId>spark-sql_2.11</artifactId>

<version>1.6.3</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.scala-lang/scala-library -->

<dependency>

<groupId>org.scala-lang</groupId>

<artifactId>scala-library</artifactId>

<version>2.11.11</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.scala-lang/scala-reflect -->

<dependency>

<groupId>org.scala-lang</groupId>

<artifactId>scala-reflect</artifactId>

<version>2.11.11</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.scala-lang/scala-compiler -->

<dependency>

<groupId>org.scala-lang</groupId>

<artifactId>scala-compiler</artifactId>

<version>2.11.11</version>

</dependency>

<!-- spring框架的相關(guān)jar包 -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context</artifactId>

<version>4.3.4.RELEASE</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jdbc</artifactId>

<version>4.3.4.RELEASE</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-web</artifactId>

<version>4.3.4.RELEASE</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

<version>4.3.4.RELEASE</version>

</dependency>

<!--添加持久層框架(mybatise)-->

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->

<dependency>

<groupId>org.mybatis</groupId>

<artifactId>mybatis</artifactId>

<version>3.4.1</version>

</dependency>

<!--mybatise和spring整合包-->

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->

<dependency>

<groupId>org.mybatis</groupId>

<artifactId>mybatis-spring</artifactId>

<version>1.3.0</version>

</dependency>

<!-- -->

<dependency>

<groupId>commons-DBCP</groupId>

<artifactId>commons-DBCP</artifactId>

<version>1.4</version>

</dependency>

<dependency>

<groupId>org.aspectj</groupId>

<artifactId>aspectjweaver</artifactId>

<version>1.8.9</version>

</dependency>

<!--添加連接池的jar包-->

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid</artifactId>

<version>1.0.18</version>

</dependency>

<!--添加數(shù)據(jù)庫驅(qū)動-->

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>5.1.39</version>

</dependency>

<!-- 日志處理 -->

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-api</artifactId>

<version>1.7.21</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-log4j12</artifactId>

<version>1.7.21</version>

</dependency>

<!-- https://mvnrepository.com/artifact/log4j/log4j -->

<dependency>

<groupId>log4j</groupId>

<artifactId>log4j</artifactId>

<version>1.2.17</version>

</dependency>

<!--json相關(guān)的依賴,不要使用jackson的依賴-->

<dependency>

<groupId>net.sf.json-lib</groupId>

<artifactId>json-lib</artifactId>

<version>2.4</version>

<classifier>jdk15</classifier>

</dependency>

</dependencies>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

web.xml的配置(這里只配置了springmvc容器)

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

<display-name>Archetype Created Web Application</display-name>

<!-- springmvc的前端控制器 -->

<servlet>

<servlet-name>manager</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<!-- contextConfigLocation不是必須的, 如果不配置contextConfigLocation, springmvc的配置文件默認(rèn)在:WEB-INF/servlet的name "-servlet.xml" -->

<init-param>

<param-name>contextConfigLocation</param-name>

<param-value>classpath:springmvc.xml</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>manager</servlet-name>

<url-pattern>/</url-pattern>

</servlet-mapping>

<!-- 解決post亂碼 -->

<filter>

<filter-name>CharacterEncodingFilter</filter-name>

<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>utf-8</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>CharacterEncodingFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<!-- 日志配置 -->

<context-param>

<param-name>log4jConfigLocation</param-name>

<param-value>classpath:log4j.properties</param-value>

</context-param>

<listener>

<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>

</listener>

</web-app>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

然后就是springMVC的配置文件

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd

http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<!-- 配置包掃描器 -->

<context:component-scan base-package="com.zzrenfeng.zhsx.controller" />

<!-- 配置注解驅(qū)動 -->

<mvc:annotation-driven />

<context:component-scan base-package="com.zzrenfeng.zhsx.service"></context:component-scan>

<context:component-scan base-package="com.zzrenfeng.zhsx.spark.service"></context:component-scan>

<context:component-scan base-package="com.zzrenfeng.zhsx.spark.conf"></context:component-scan>

</beans>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

配置文件就就沒有了,如果有需要可以再去集成其他的,下面進(jìn)入編碼的介紹

對象和json相互轉(zhuǎn)換的工具類:

(為什么使用手動的去轉(zhuǎn)換,而沒有使用jackson的相關(guān)依賴進(jìn)行自動轉(zhuǎn)換,是我在使用的時候發(fā)現(xiàn)使用jackson會對咱們的spark作業(yè)有影響,spark作業(yè)會異常終止掉)

package com.zzrenfeng.zhsx.util;

import java.lang.reflect.Field;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Set;

import net.sf.json.JSONArray;

import net.sf.json.JSONObject;

import net.sf.json.JsonConfig;

/**

* Json與javaBean之間的轉(zhuǎn)換工具類

*

* @author

* @version

*

* {@code 現(xiàn)使用json-lib組件實現(xiàn)

* 需要

* json-lib-2.4-jdk15.jar

* ezmorph-1.0.6.jar

* commons-collections-3.1.jar

* commons-lang-2.0.jar

* 支持

* }

*/

public class JsonUtil {

/**

* 從一個JSON 對象字符格式中得到一個java對象

*

* @param jsonString

* @param beanCalss

* @return

*/

@SuppressWarnings("unchecked")

public static <T> T jsonToBean(String jsonString, Class<T> beanCalss) {

JSONObject jsonObject = JSONObject.fromObject(jsonString);

T bean = (T) JSONObject.toBean(jsonObject, beanCalss);

return bean;

}

/**

* 將java對象轉(zhuǎn)換成json字符串

*

* @param bean

* @return

*/

public static String beanToJson(Object bean) {

JSONObject json = JSONObject.fromObject(bean);

return json.toString();

}

/**

* 將java對象轉(zhuǎn)換成json字符串

*

* @param bean

* @return

*/

public static String beanToJson(Object bean, String[] _nory_changes, boolean nory) {

JSONObject json = null;

if(nory){//轉(zhuǎn)換_nory_changes里的屬性

Field[] fields = bean.getClass().getDeclaredFields();

String str = "";

for(Field field : fields){

// System.out.println(field.getName());

str =(":" field.getName());

}

fields = bean.getClass().getSuperclass().getDeclaredFields();

for(Field field : fields){

// System.out.println(field.getName());

str =(":" field.getName());

}

str =":";

for(String s : _nory_changes){

str = str.replace(":" s ":", ":");

}

json = JSONObject.fromObject(bean,configJson(str.split(":")));

}else{//轉(zhuǎn)換除了_nory_changes里的屬性

json = JSONObject.fromObject(bean,configJson(_nory_changes));

}

return json.toString();

}

private static JsonConfig configJson(String[] excludes) {

JsonConfig jsonConfig = new JsonConfig();

jsonConfig.setExcludes(excludes);

//

jsonConfig.setIgnoreDefaultExcludes(false);

//

// jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);

// jsonConfig.registerJsonValueProcessor(Date.class,

//

// new DateJsonValueProcessor(datePattern));

return jsonConfig;

}

/**

* 將java對象List集合轉(zhuǎn)換成json字符串

* @param beans

* @return

*/

@SuppressWarnings("unchecked")

public static String beanListToJson(List beans) {

StringBuffer rest = new StringBuffer();

rest.append("[");

int size = beans.size();

for (int i = 0; i < size; i ) {

rest.append(beanToJson(beans.get(i)) ((i<size-1)?",":""));

}

rest.append("]");

return rest.toString();

}

/**

*

* @param beans

* @param _no_changes

* @return

*/

@SuppressWarnings("unchecked")

public static String beanListToJson(List beans, String[] _nory_changes, boolean nory) {

StringBuffer rest = new StringBuffer();

rest.append("[");

int size = beans.size();

for (int i = 0; i < size; i ) {

try{

rest.append(beanToJson(beans.get(i),_nory_changes,nory));

if(i<size-1){

rest.append(",");

}

}catch(Exception e){

e.printStackTrace();

}

}

rest.append("]");

return rest.toString();

}

/**

* 從json HASH表達(dá)式中獲取一個map,改map支持嵌套功能

*

* @param jsonString

* @return

*/

@SuppressWarnings({ "unchecked" })

public static Map jsonToMap(String jsonString) {

JSONObject jsonObject = JSONObject.fromObject(jsonString);

Iterator keyIter = jsonObject.keys();

String key;

Object value;

Map valueMap = new HashMap();

while (keyIter.hasNext()) {

key = (String) keyIter.next();

value = jsonObject.get(key).toString();

valueMap.put(key, value);

}

return valueMap;

}

/**

* map集合轉(zhuǎn)換成json格式數(shù)據(jù)

* @param map

* @return

*/

public static String mapToJson(Map<String, ?> map, String[] _nory_changes, boolean nory){

String s_json = "{";

Set<String> key = map.keySet();

for (Iterator<?> it = key.iterator(); it.hasNext();) {

String s = (String) it.next();

if(map.get(s) == null){

}else if(map.get(s) instanceof List<?>){

s_json =(s ":" JsonUtil.beanListToJson((List<?>)map.get(s), _nory_changes, nory));

}else{

JSONObject json = JSONObject.fromObject(map);

s_json = (s ":" json.toString());;

}

if(it.hasNext()){

s_json =",";

}

}

s_json ="}";

return s_json;

}

/**

* 從json數(shù)組中得到相應(yīng)java數(shù)組

*

* @param jsonString

* @return

*/

public static Object[] jsonToObjectArray(String jsonString) {

JSONArray jsonArray = JSONArray.fromObject(jsonString);

return jsonArray.toArray();

}

public static String listToJson(List<?> list) {

JSONArray jsonArray = JSONArray.fromObject(list);

return jsonArray.toString();

}

/**

* 從json對象集合表達(dá)式中得到一個java對象列表

*

* @param jsonString

* @param beanClass

* @return

*/

@SuppressWarnings("unchecked")

public static <T> List<T> jsonToBeanList(String jsonString, Class<T> beanClass) {

JSONArray jsonArray = JSONArray.fromObject(jsonString);

JSONObject jsonObject;

T bean;

int size = jsonArray.size();

List<T> list = new ArrayList<T>(size);

for (int i = 0; i < size; i ) {

jsonObject = jsonArray.getJSONObject(i);

bean = (T) JSONObject.toBean(jsonObject, beanClass);

list.add(bean);

}

return list;

}

/**

* 從json數(shù)組中解析出java字符串?dāng)?shù)組

*

* @param jsonString

* @return

*/

public static String[] jsonToStringArray(String jsonString) {

JSONArray jsonArray = JSONArray.fromObject(jsonString);

String[] stringArray = new String[jsonArray.size()];

int size = jsonArray.size();

for (int i = 0; i < size; i ) {

stringArray[i] = jsonArray.getString(i);

}

return stringArray;

}

/**

* 從json數(shù)組中解析出javaLong型對象數(shù)組

*

* @param jsonString

* @return

*/

public static Long[] jsonToLongArray(String jsonString) {

JSONArray jsonArray = JSONArray.fromObject(jsonString);

int size = jsonArray.size();

Long[] longArray = new Long[size];

for (int i = 0; i < size; i ) {

longArray[i] = jsonArray.getLong(i);

}

return longArray;

}

/**

* 從json數(shù)組中解析出java Integer型對象數(shù)組

*

* @param jsonString

* @return

*/

public static Integer[] jsonToIntegerArray(String jsonString) {

JSONArray jsonArray = JSONArray.fromObject(jsonString);

int size = jsonArray.size();

Integer[] integerArray = new Integer[size];

for (int i = 0; i < size; i ) {

integerArray[i] = jsonArray.getInt(i);

}

return integerArray;

}

/**

* 從json數(shù)組中解析出java Double型對象數(shù)組

*

* @param jsonString

* @return

*/

public static Double[] jsonToDoubleArray(String jsonString) {

JSONArray jsonArray = JSONArray.fromObject(jsonString);

int size = jsonArray.size();

Double[] doubleArray = new Double[size];

for (int i = 0; i < size; i ) {

doubleArray[i] = jsonArray.getDouble(i);

}

return doubleArray;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

spark的工具類:(主要負(fù)責(zé)sparkcontext的初始化工作)

package com.zzrenfeng.zhsx.spark.conf;

import java.io.Serializable;

import org.apache.spark.SparkConf;

import org.apache.spark.api.java.JavaSparkContext;

import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

import org.springframework.stereotype.Component;

@Component

public class ApplicationConfiguration implements Serializable{

private static final long serialVersionUID = 1L;

public SparkConf sparkconf(){

SparkConf conf = new SparkConf()

.setMaster("local[*]")

.setAppName("wc");

return conf;

}

public JavaSparkContext javaSparkContext(){

return new JavaSparkContext(sparkconf());

}

public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {

return new PropertySourcesPlaceholderConfigurer();

}

public String filePath(){

return "E:測試文件nlog.txt";

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

wordcount model類(對wordcount進(jìn)行封裝)

package com.zzrenfeng.zhsx.spark.domain;

import scala.Serializable;

public class WordCount implements Serializable{

/**

*

*/

private static final long serialVersionUID = 1L;

private String word;

private Integer count;

public WordCount(){}

public WordCount(String v1, int l) {

word = v1;

count = l;

}

public String getWord() {

return word;

}

public void setWord(String word) {

this.word = word;

}

public int getCount() {

return count;

}

public void setCount(int count) {

this.count = count;

}

@Override

public String toString() {

return "WordCount [word=" word ", count=" count "]";

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

spark service類,主要是負(fù)責(zé)spark word count的job任務(wù)邏輯

package com.zzrenfeng.zhsx.spark.service;

import java.util.Arrays;

import java.util.List;

import org.apache.spark.api.java.JavaPairRDD;

import org.apache.spark.api.java.JavaRDD;

import org.apache.spark.api.java.JavaSparkContext;

import org.apache.spark.api.java.function.FlatMapFunction;

import org.apache.spark.api.java.function.Function;

import org.apache.spark.api.java.function.Function2;

import org.apache.spark.api.java.function.PairFunction;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import scala.Tuple2;

import com.zzrenfeng.zhsx.spark.conf.ApplicationConfiguration;

import com.zzrenfeng.zhsx.spark.domain.WordCount;

@Component

public class SparkServiceTest implements java.io.Serializable{

@Autowired

ApplicationConfiguration applicationConfiguration;

public List<WordCount> doWordCount(){

JavaSparkContext javaSparkContext = applicationConfiguration.javaSparkContext();

System.out.println(javaSparkContext);

JavaRDD<String> file = javaSparkContext.textFile(applicationConfiguration.filePath());

JavaRDD<String> worlds = file.flatMap(new FlatMapFunction<String, String>() {

@Override

public Iterable<String> call(String t) throws Exception {

// TODO Auto-generated method stub

List<String> list = Arrays.asList(t.split(" "));

return list;

}

});

JavaRDD<WordCount> wordcount = worlds.map(new Function<String, WordCount>() {

@Override

public WordCount call(String v1) throws Exception {

return new WordCount(v1,1);

}

});

JavaPairRDD<String, Integer> pairwordCount = wordcount.mapToPair(new PairFunction<WordCount, String, Integer>() {

@Override

public Tuple2<String, Integer> call(WordCount t) throws Exception {

// TODO Auto-generated method stub

return new Tuple2<>(t.getWord() , new Integer(t.getCount()));

}

});

JavaPairRDD<String, Integer> worldCounts = pairwordCount.reduceByKey(new Function2<Integer, Integer, Integer>() {

@Override

public Integer call(Integer v1, Integer v2) throws Exception {

// TODO Auto-generated method stub

return v1 v2;

}

});

JavaRDD result = worldCounts.map(new Function<Tuple2<String,Integer>, WordCount>() {

@Override

public WordCount call(Tuple2<String, Integer> v1) throws Exception {

// TODO Auto-generated method stub

return new WordCount(v1._1,v1._2);

}

});

List<WordCount> list = result.collect();

javaSparkContext.close();

System.out.println(list.toString());

return list;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

controller層,主要負(fù)責(zé)請求的攔截

package com.zzrenfeng.zhsx.controller;

import java.util.ArrayList;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.ResponseBody;

import com.zzrenfeng.zhsx.spark.domain.WordCount;

import com.zzrenfeng.zhsx.spark.service.SparkServiceTest;

import com.zzrenfeng.zhsx.util.JsonUtil;

@Controller

@RequestMapping("hello")

public class ControllerTest {

@Autowired

private SparkServiceTest sparkServiceTest;

@RequestMapping("wc")

@ResponseBody

public String wordCount(){

List<WordCount> list = sparkServiceTest.doWordCount();

return JsonUtil.listToJson(list);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

進(jìn)行啟動,然后在瀏覽器上輸入上面的攔截的url就可以看到開始出現(xiàn)的結(jié)果了。

應(yīng)為這是個web接口,所以可以從各個端去調(diào)用,甚至可以用其他語言去調(diào)用。

現(xiàn)在可以愉快的去擼spark代碼了,也許有人會問spark不應(yīng)該用scala開發(fā)更好嗎?

個人認(rèn)為如果是純粹的數(shù)據(jù)處理可以使用scala,編寫起來太爽了,但是跟其他的集成的時候最好還是用java,畢竟有問題了還可以跟java大牛去討論討論。

歡迎有興趣的一起來探討

免責(zé)聲明:本文由用戶上傳,如有侵權(quán)請聯(lián)系刪除!