From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: multipart/mixed; boundary="===============3360458458674382862==" MIME-Version: 1.0 From: Sreeni (Sreenivasa) Busam (Stellus) Subject: Re: [SPDK] Request for more details on SPDK driver API. Date: Mon, 13 Nov 2017 19:47:55 +0000 Message-ID: <83a4340c4f944611b899b961e2f0ef88@stellus.com> In-Reply-To: 0fa061d0031f4705b96e62d928e27988@stellus.com List-ID: To: spdk@lists.01.org --===============3360458458674382862== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Hi guys, A simple follow-up question to Paul's answer. Let us assume that I/O to NVMe device has been issued and submit has comple= ted and is successful. Is it a safe assumption that the callback function p= rovided in the spdk_nvme_ns_cmd_read() gets called when the read or write I= /O has completed successfully without errors? If the I/O has failed for any= reason, the callback is not called correct? I am using the case when the request is issued without the bdev layer. Thanks, Sreeni From: SPDK [mailto:spdk-bounces(a)lists.01.org] On Behalf Of Sreeni (Sreeni= vasa) Busam (Stellus) Sent: Sunday, November 12, 2017 10:37 PM To: Storage Performance Development Kit Subject: Re: [SPDK] Request for more details on SPDK driver API. Hi Paul, Thank you very much for taking the time to write a clear and lengthy reply = addressing my questions. I have got a fair understanding about the bdev lay= er and the use of it. I looked at the hello_world and fio example code already and tested the cod= e, and they were working well with a local NVMe SSD device connected. I nee= d to check out the blob hello_world example though. I will take a look at the presentations and follow-up if I have any other q= uestions. I have to join the #spdk channel, and will contact you if I need = any help there. I have a few questions regarding how the failures of read and write request= s are handled in the lower layer and controller level, if they are handled = and other questions. Sreeni From: SPDK [mailto:spdk-bounces(a)lists.01.org] On Behalf Of Luse, Paul E Sent: Saturday, November 11, 2017 6:41 AM To: Storage Performance Development Kit > Subject: Re: [SPDK] Request for more details on SPDK driver API. Hi Sreeni, Welcome! Before I give you the start of an answer (others will chime in as= well I'm sure) I should mention that we're also on IRC at freenode in the = #spdk channel. You can generally find an expert there that can help via re= al-time or slightly delayed discussions :) Also, if you haven't checked out the presentations from our summit earlier = this year they are at http://www.spdk.io/news/2017/05/03/summit_presentatio= ns/ and there's some good ones in there that might help you. In most of those decks you'll find an architecture diagram that might help = pull all of this together for you. The key point for understanding your que= stions is to realize that SPDK is a collection of layered modules, some opt= ional, that all work together to form a storage stack in user space. So if= you think of the top of the stack being front end protocol modules like iS= CSI and NVMeoF and then the next big layer down being a generic block layer= followed by a lower device driver layer it should start to make more sense= . The generic block layer is a lightweight block abstraction at the top an= d then device specific modules at the bottom to interface with device drive= rs. So, anywhere you see an API with "bdev" in it, like the 2 you mention, = you're in the generic block layer. If the application you've constructed i= s based on NVMe then the next layer down will be the NVMe driver where you'= ll find the API that you listed in (1) below. As I mentioned though, a lot= of the layers are optional including the bdev layer. If you wanted to wri= te an application that didn't use bdevs (you knew it was only ever going to= be NVMe and didn't want the minimal overhead of bdev) you could use those = NVMe driver APIs directly in your application. Hope that makes sense, again I'm sure others will add more clarifying bits = of information as well. Here are some examples: https://github.com/spdk/spdk/tree/master/examples/nvme/hello_world is an ap= plication that doesn't use bdev, talks directly to NVMe https://github.com/spdk/spdk/tree/master/examples/blob/hello_world is a sim= ple blobstore example (I didn't mention blobstore above but its another opt= ional layer) that does use a bdev. In this example it uses a ram disk (mall= oc) back end but could also easily use an NVMe back end directly and there'= s an open patch that shows how that works at https://review.gerrithub.io/#/= c/375460/ - both of these might not be the best example for your question b= ecause blobstore is thrown in the mix but you can see the bdev portion in t= here as part of blobstore in a subdir called bdev under /lib/blob Anyway, hope that helps more than it confuses :) Feel free to keep asking q= uestions until it makes sense... Thx Paul PS: there's also a bunch of existing bdev back end modules here https://git= hub.com/spdk/spdk/tree/master/lib/bdev that may help clarify the concepts. = Note that you can also stack bdevs in order to intercept IO coming and goin= g so you can do value added things easily, we call those "virtual bdevs" an= d you'll see some examples in the dir I just mentioned (ie split, lvol) From: SPDK [mailto:spdk-bounces(a)lists.01.org] On Behalf Of Sreeni (Sreeni= vasa) Busam (Stellus) Sent: Friday, November 10, 2017 6:25 PM To: spdk(a)lists.01.org Subject: [SPDK] Request for more details on SPDK driver API. I am new to SPDK driver and trying to understand the various API's availabl= e to do I/O on NVMe local device and using NVMeoF protocol on a target devi= ce. I see different interfaces for the read and write I/O operations. It seems there are two types of interfaces available. 1. spdk_nvme_ns_cmd_read() and spdk_nvme_ns_cmd_write() and related functio= n. This is used for PCIe devices. It seems to apply to devices attached loc= ally. 2. spdk_bdev_read_blocks() and spdk_bdev_write_blocks() and related API's i= n lib/bdev. I have been looking at the code and trying to understand how this API and r= elated APIs for the module has been used, the API's in 2. are used for blob= fs I/O operation spdk/lib/blob/bdev/*, when there is a blob filesystem and = for I/O operation on NVMe devices using NVMeoF protocol spdk/lib/nvmf/*. Is this a correct assumption? Is the lib/bdev layer developed to address on= ly these cases? Can the lib/bdev API be used on a local NVMe device? If so, is there a test= program to understand how to create a bdev device and do the I/O on NVMe S= SD block device? Please let me know if there is an example to understand how to use the lib/= nvmf interfaces. I want to test a device on remote target using NVMeoF prot= ocol. Thanks very much for any help in the lib/bdev API. --===============3360458458674382862== Content-Type: text/html MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="attachment.html" PGh0bWwgeG1sbnM6dj0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp2bWwiIHhtbG5zOm89InVy bjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSIgeG1sbnM6dz0idXJuOnNjaGVt YXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6d29yZCIgeG1sbnM6bT0iaHR0cDovL3NjaGVtYXMubWlj cm9zb2Z0LmNvbS9vZmZpY2UvMjAwNC8xMi9vbW1sIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv VFIvUkVDLWh0bWw0MCI+CjxoZWFkPgo8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNv bnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11cy1hc2NpaSI+CjxtZXRhIG5hbWU9IkdlbmVyYXRv ciIgY29udGVudD0iTWljcm9zb2Z0IFdvcmQgMTUgKGZpbHRlcmVkIG1lZGl1bSkiPgo8c3R5bGU+ PCEtLQovKiBGb250IERlZmluaXRpb25zICovCkBmb250LWZhY2UKCXtmb250LWZhbWlseTpXaW5n ZGluZ3M7CglwYW5vc2UtMTo1IDAgMCAwIDAgMCAwIDAgMCAwO30KQGZvbnQtZmFjZQoJe2ZvbnQt ZmFtaWx5OiJDYW1icmlhIE1hdGgiOwoJcGFub3NlLTE6MiA0IDUgMyA1IDQgNiAzIDIgNDt9CkBm b250LWZhY2UKCXtmb250LWZhbWlseToiTWFsZ3VuIEdvdGhpYyI7CglwYW5vc2UtMToyIDExIDUg MyAyIDAgMCAyIDAgNDt9CkBmb250LWZhY2UKCXtmb250LWZhbWlseTpDYWxpYnJpOwoJcGFub3Nl LTE6MiAxNSA1IDIgMiAyIDQgMyAyIDQ7fQpAZm9udC1mYWNlCgl7Zm9udC1mYW1pbHk6IlxATWFs Z3VuIEdvdGhpYyI7CglwYW5vc2UtMToyIDExIDUgMyAyIDAgMCAyIDAgNDt9Ci8qIFN0eWxlIERl ZmluaXRpb25zICovCnAuTXNvTm9ybWFsLCBsaS5Nc29Ob3JtYWwsIGRpdi5Nc29Ob3JtYWwKCXtt YXJnaW46MGluOwoJbWFyZ2luLWJvdHRvbTouMDAwMXB0OwoJZm9udC1zaXplOjExLjBwdDsKCWZv bnQtZmFtaWx5OiJDYWxpYnJpIixzYW5zLXNlcmlmO30KYTpsaW5rLCBzcGFuLk1zb0h5cGVybGlu awoJe21zby1zdHlsZS1wcmlvcml0eTo5OTsKCWNvbG9yOiMwNTYzQzE7Cgl0ZXh0LWRlY29yYXRp b246dW5kZXJsaW5lO30KYTp2aXNpdGVkLCBzcGFuLk1zb0h5cGVybGlua0ZvbGxvd2VkCgl7bXNv LXN0eWxlLXByaW9yaXR5Ojk5OwoJY29sb3I6Izk1NEY3MjsKCXRleHQtZGVjb3JhdGlvbjp1bmRl cmxpbmU7fQpwLk1zb0xpc3RQYXJhZ3JhcGgsIGxpLk1zb0xpc3RQYXJhZ3JhcGgsIGRpdi5Nc29M aXN0UGFyYWdyYXBoCgl7bXNvLXN0eWxlLXByaW9yaXR5OjM0OwoJbWFyZ2luLXRvcDowaW47Cglt YXJnaW4tcmlnaHQ6MGluOwoJbWFyZ2luLWJvdHRvbTowaW47CgltYXJnaW4tbGVmdDouNWluOwoJ bWFyZ2luLWJvdHRvbTouMDAwMXB0OwoJZm9udC1zaXplOjExLjBwdDsKCWZvbnQtZmFtaWx5OiJD YWxpYnJpIixzYW5zLXNlcmlmO30Kc3Bhbi5FbWFpbFN0eWxlMTgKCXttc28tc3R5bGUtdHlwZTpw ZXJzb25hbDsKCWZvbnQtZmFtaWx5OiJDYWxpYnJpIixzYW5zLXNlcmlmOwoJY29sb3I6d2luZG93 dGV4dDt9CnNwYW4uRW1haWxTdHlsZTE5Cgl7bXNvLXN0eWxlLXR5cGU6cGVyc29uYWw7Cglmb250 LWZhbWlseToiQ2FsaWJyaSIsc2Fucy1zZXJpZjsKCWNvbG9yOiMxRjQ5N0Q7fQpzcGFuLkVtYWls U3R5bGUyMAoJe21zby1zdHlsZS10eXBlOnBlcnNvbmFsOwoJZm9udC1mYW1pbHk6IkNhbGlicmki LHNhbnMtc2VyaWY7Cgljb2xvcjojMUY0OTdEO30Kc3Bhbi5FbWFpbFN0eWxlMjEKCXttc28tc3R5 bGUtdHlwZTpwZXJzb25hbC1yZXBseTsKCWZvbnQtZmFtaWx5OiJDYWxpYnJpIixzYW5zLXNlcmlm OwoJY29sb3I6IzFGNDk3RDt9Ci5Nc29DaHBEZWZhdWx0Cgl7bXNvLXN0eWxlLXR5cGU6ZXhwb3J0 LW9ubHk7Cglmb250LXNpemU6MTAuMHB0O30KQHBhZ2UgV29yZFNlY3Rpb24xCgl7c2l6ZTo4LjVp biAxMS4waW47CgltYXJnaW46MS4waW4gMS4waW4gMS4waW4gMS4waW47fQpkaXYuV29yZFNlY3Rp b24xCgl7cGFnZTpXb3JkU2VjdGlvbjE7fQotLT48L3N0eWxlPjwhLS1baWYgZ3RlIG1zbyA5XT48 eG1sPgo8bzpzaGFwZWRlZmF1bHRzIHY6ZXh0PSJlZGl0IiBzcGlkbWF4PSIxMDI2IiAvPgo8L3ht bD48IVtlbmRpZl0tLT48IS0tW2lmIGd0ZSBtc28gOV0+PHhtbD4KPG86c2hhcGVsYXlvdXQgdjpl eHQ9ImVkaXQiPgo8bzppZG1hcCB2OmV4dD0iZWRpdCIgZGF0YT0iMSIgLz4KPC9vOnNoYXBlbGF5 b3V0PjwveG1sPjwhW2VuZGlmXS0tPgo8L2hlYWQ+Cjxib2R5IGxhbmc9IkVOLVVTIiBsaW5rPSIj MDU2M0MxIiB2bGluaz0iIzk1NEY3MiI+CjxkaXYgY2xhc3M9IldvcmRTZWN0aW9uMSI+CjxwIGNs YXNzPSJNc29Ob3JtYWwiPjxzcGFuIHN0eWxlPSJjb2xvcjojMUY0OTdEIj5IaSBndXlzLDxvOnA+ PC9vOnA+PC9zcGFuPjwvcD4KPHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9ImNvbG9y OiMxRjQ5N0QiPjxvOnA+Jm5ic3A7PC9vOnA+PC9zcGFuPjwvcD4KPHAgY2xhc3M9Ik1zb05vcm1h bCI+PHNwYW4gc3R5bGU9ImNvbG9yOiMxRjQ5N0QiPkEgc2ltcGxlIGZvbGxvdy11cCBxdWVzdGlv biB0byBQYXVsJiM4MjE3O3MgYW5zd2VyLjxvOnA+PC9vOnA+PC9zcGFuPjwvcD4KPHAgY2xhc3M9 Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9ImNvbG9yOiMxRjQ5N0QiPkxldCB1cyBhc3N1bWUgdGhh dCBJL08gdG8gTlZNZSBkZXZpY2UgaGFzIGJlZW4gaXNzdWVkIGFuZCBzdWJtaXQgaGFzIGNvbXBs ZXRlZCBhbmQgaXMgc3VjY2Vzc2Z1bC4gSXMgaXQgYSBzYWZlIGFzc3VtcHRpb24gdGhhdCB0aGUg Y2FsbGJhY2sgZnVuY3Rpb24gcHJvdmlkZWQgaW4gdGhlIHNwZGtfbnZtZV9uc19jbWRfcmVhZCgp IGdldHMgY2FsbGVkIHdoZW4gdGhlCiByZWFkIG9yIHdyaXRlIEkvTyBoYXMgY29tcGxldGVkIHN1 Y2Nlc3NmdWxseSB3aXRob3V0IGVycm9ycz8gSWYgdGhlIEkvTyBoYXMgZmFpbGVkIGZvciBhbnkg cmVhc29uLCB0aGUgY2FsbGJhY2sgaXMgbm90IGNhbGxlZCBjb3JyZWN0PzxvOnA+PC9vOnA+PC9z cGFuPjwvcD4KPHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9ImNvbG9yOiMxRjQ5N0Qi PkkgYW0gdXNpbmcgdGhlIGNhc2Ugd2hlbiB0aGUgcmVxdWVzdCBpcyBpc3N1ZWQgd2l0aG91dCB0 aGUgYmRldiBsYXllci48bzpwPjwvbzpwPjwvc3Bhbj48L3A+CjxwIGNsYXNzPSJNc29Ob3JtYWwi PjxzcGFuIHN0eWxlPSJjb2xvcjojMUY0OTdEIj48bzpwPiZuYnNwOzwvbzpwPjwvc3Bhbj48L3A+ CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxzcGFuIHN0eWxlPSJjb2xvcjojMUY0OTdEIj5UaGFua3Ms PG86cD48L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0i Y29sb3I6IzFGNDk3RCI+U3JlZW5pPG86cD48L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNv Tm9ybWFsIj48YSBuYW1lPSJfTWFpbEVuZENvbXBvc2UiPjxzcGFuIHN0eWxlPSJjb2xvcjojMUY0 OTdEIj48bzpwPiZuYnNwOzwvbzpwPjwvc3Bhbj48L2E+PC9wPgo8ZGl2Pgo8ZGl2IHN0eWxlPSJi b3JkZXI6bm9uZTtib3JkZXItdG9wOnNvbGlkICNFMUUxRTEgMS4wcHQ7cGFkZGluZzozLjBwdCAw aW4gMGluIDBpbiI+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxiPkZyb206PC9iPiBTUERLIFttYWls dG86c3Bkay1ib3VuY2VzQGxpc3RzLjAxLm9yZ10gPGI+T24gQmVoYWxmIE9mCjwvYj5TcmVlbmkg KFNyZWVuaXZhc2EpIEJ1c2FtIChTdGVsbHVzKTxicj4KPGI+U2VudDo8L2I+IFN1bmRheSwgTm92 ZW1iZXIgMTIsIDIwMTcgMTA6MzcgUE08YnI+CjxiPlRvOjwvYj4gU3RvcmFnZSBQZXJmb3JtYW5j ZSBEZXZlbG9wbWVudCBLaXQgJmx0O3NwZGtAbGlzdHMuMDEub3JnJmd0Ozxicj4KPGI+U3ViamVj dDo8L2I+IFJlOiBbU1BES10gUmVxdWVzdCBmb3IgbW9yZSBkZXRhaWxzIG9uIFNQREsgZHJpdmVy IEFQSS48bzpwPjwvbzpwPjwvcD4KPC9kaXY+CjwvZGl2Pgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48 bzpwPiZuYnNwOzwvbzpwPjwvcD4KPHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9ImNv bG9yOiMxRjQ5N0QiPkhpIFBhdWwsPG86cD48L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNv Tm9ybWFsIj48c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3RCI+PG86cD4mbmJzcDs8L286cD48L3Nw YW4+PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3RCI+ VGhhbmsgeW91IHZlcnkgbXVjaCBmb3IgdGFraW5nIHRoZSB0aW1lIHRvIHdyaXRlIGEgY2xlYXIg YW5kIGxlbmd0aHkgcmVwbHkgYWRkcmVzc2luZyBteSBxdWVzdGlvbnMuIEkgaGF2ZSBnb3QgYSBm YWlyIHVuZGVyc3RhbmRpbmcgYWJvdXQgdGhlIGJkZXYgbGF5ZXIgYW5kIHRoZSB1c2Ugb2YgaXQu PG86cD48L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0i Y29sb3I6IzFGNDk3RCI+SSBsb29rZWQgYXQgdGhlIGhlbGxvX3dvcmxkIGFuZCBmaW8gZXhhbXBs ZSBjb2RlIGFscmVhZHkgYW5kIHRlc3RlZCB0aGUgY29kZSwgYW5kIHRoZXkgd2VyZSB3b3JraW5n IHdlbGwgd2l0aCBhIGxvY2FsIE5WTWUgU1NEIGRldmljZSBjb25uZWN0ZWQuIEkgbmVlZCB0byBj aGVjayBvdXQgdGhlIGJsb2IgaGVsbG9fd29ybGQgZXhhbXBsZSB0aG91Z2guPG86cD48L286cD48 L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3 RCI+SSB3aWxsIHRha2UgYSBsb29rIGF0IHRoZSBwcmVzZW50YXRpb25zIGFuZCBmb2xsb3ctdXAg aWYgSSBoYXZlIGFueSBvdGhlciBxdWVzdGlvbnMuIEkgaGF2ZSB0byBqb2luIHRoZSAjc3BkayBj aGFubmVsLCBhbmQgd2lsbCBjb250YWN0IHlvdSBpZiBJIG5lZWQgYW55IGhlbHAgdGhlcmUuCjxv OnA+PC9vOnA+PC9zcGFuPjwvcD4KPHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9ImNv bG9yOiMxRjQ5N0QiPkkgaGF2ZSBhIGZldyBxdWVzdGlvbnMgcmVnYXJkaW5nIGhvdyB0aGUgZmFp bHVyZXMgb2YgcmVhZCBhbmQgd3JpdGUgcmVxdWVzdHMgYXJlIGhhbmRsZWQgaW4gdGhlIGxvd2Vy IGxheWVyIGFuZCBjb250cm9sbGVyIGxldmVsLCBpZiB0aGV5IGFyZSBoYW5kbGVkIGFuZCBvdGhl ciBxdWVzdGlvbnMuPG86cD48L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48 c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3RCI+PG86cD4mbmJzcDs8L286cD48L3NwYW4+PC9wPgo8 cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3RCI+U3JlZW5pPG86 cD48L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0iY29s b3I6IzFGNDk3RCI+PG86cD4mbmJzcDs8L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNvTm9y bWFsIj48c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3RCI+PG86cD4mbmJzcDs8L286cD48L3NwYW4+ PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3RCI+PG86 cD4mbmJzcDs8L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHls ZT0iY29sb3I6IzFGNDk3RCI+PG86cD4mbmJzcDs8L286cD48L3NwYW4+PC9wPgo8ZGl2Pgo8ZGl2 IHN0eWxlPSJib3JkZXI6bm9uZTtib3JkZXItdG9wOnNvbGlkICNFMUUxRTEgMS4wcHQ7cGFkZGlu ZzozLjBwdCAwaW4gMGluIDBpbiI+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxiPkZyb206PC9iPiBT UERLIFs8YSBocmVmPSJtYWlsdG86c3Bkay1ib3VuY2VzQGxpc3RzLjAxLm9yZyI+bWFpbHRvOnNw ZGstYm91bmNlc0BsaXN0cy4wMS5vcmc8L2E+XQo8Yj5PbiBCZWhhbGYgT2YgPC9iPkx1c2UsIFBh dWwgRTxicj4KPGI+U2VudDo8L2I+IFNhdHVyZGF5LCBOb3ZlbWJlciAxMSwgMjAxNyA2OjQxIEFN PGJyPgo8Yj5Ubzo8L2I+IFN0b3JhZ2UgUGVyZm9ybWFuY2UgRGV2ZWxvcG1lbnQgS2l0ICZsdDs8 YSBocmVmPSJtYWlsdG86c3Bka0BsaXN0cy4wMS5vcmciPnNwZGtAbGlzdHMuMDEub3JnPC9hPiZn dDs8YnI+CjxiPlN1YmplY3Q6PC9iPiBSZTogW1NQREtdIFJlcXVlc3QgZm9yIG1vcmUgZGV0YWls cyBvbiBTUERLIGRyaXZlciBBUEkuPG86cD48L286cD48L3A+CjwvZGl2Pgo8L2Rpdj4KPHAgY2xh c3M9Ik1zb05vcm1hbCI+PG86cD4mbmJzcDs8L286cD48L3A+CjxwIGNsYXNzPSJNc29Ob3JtYWwi PjxzcGFuIHN0eWxlPSJjb2xvcjojMUY0OTdEIj5IaSBTcmVlbmksPG86cD48L286cD48L3NwYW4+ PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3RCI+PG86 cD4mbmJzcDs8L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHls ZT0iY29sb3I6IzFGNDk3RCI+V2VsY29tZSEmbmJzcDsgQmVmb3JlIEkgZ2l2ZSB5b3UgdGhlIHN0 YXJ0IG9mIGFuIGFuc3dlciAob3RoZXJzIHdpbGwgY2hpbWUgaW4gYXMgd2VsbCBJJiM4MjE3O20g c3VyZSkgSSBzaG91bGQgbWVudGlvbiB0aGF0IHdlJiM4MjE3O3JlIGFsc28gb24gSVJDIGF0IGZy ZWVub2RlIGluIHRoZSAjc3BkayBjaGFubmVsLiZuYnNwOyBZb3UgY2FuIGdlbmVyYWxseSBmaW5k IGFuIGV4cGVydCB0aGVyZSB0aGF0CiBjYW4gaGVscCB2aWEgcmVhbC10aW1lIG9yIHNsaWdodGx5 IGRlbGF5ZWQgZGlzY3Vzc2lvbnMgPC9zcGFuPjxzcGFuIHN0eWxlPSJmb250LWZhbWlseTpXaW5n ZGluZ3M7Y29sb3I6IzFGNDk3RCI+Sjwvc3Bhbj48c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3RCI+ PG86cD48L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0i Y29sb3I6IzFGNDk3RCI+PG86cD4mbmJzcDs8L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNv Tm9ybWFsIj48c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3RCI+QWxzbywgaWYgeW91IGhhdmVuJiM4 MjE3O3QgY2hlY2tlZCBvdXQgdGhlIHByZXNlbnRhdGlvbnMgZnJvbSBvdXIgc3VtbWl0IGVhcmxp ZXIgdGhpcyB5ZWFyIHRoZXkgYXJlIGF0CjxhIGhyZWY9Imh0dHA6Ly93d3cuc3Bkay5pby9uZXdz LzIwMTcvMDUvMDMvc3VtbWl0X3ByZXNlbnRhdGlvbnMvIj5odHRwOi8vd3d3LnNwZGsuaW8vbmV3 cy8yMDE3LzA1LzAzL3N1bW1pdF9wcmVzZW50YXRpb25zLzwvYT4gYW5kIHRoZXJlJiM4MjE3O3Mg c29tZSBnb29kIG9uZXMgaW4gdGhlcmUgdGhhdCBtaWdodCBoZWxwIHlvdS48bzpwPjwvbzpwPjwv c3Bhbj48L3A+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxzcGFuIHN0eWxlPSJjb2xvcjojMUY0OTdE Ij48bzpwPiZuYnNwOzwvbzpwPjwvc3Bhbj48L3A+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxzcGFu IHN0eWxlPSJjb2xvcjojMUY0OTdEIj5JbiBtb3N0IG9mIHRob3NlIGRlY2tzIHlvdSYjODIxNzts bCBmaW5kIGFuIGFyY2hpdGVjdHVyZSBkaWFncmFtIHRoYXQgbWlnaHQgaGVscCBwdWxsIGFsbCBv ZiB0aGlzIHRvZ2V0aGVyIGZvciB5b3UuIFRoZSBrZXkgcG9pbnQgZm9yIHVuZGVyc3RhbmRpbmcg eW91ciBxdWVzdGlvbnMgaXMgdG8gcmVhbGl6ZSB0aGF0IFNQREsgaXMgYSBjb2xsZWN0aW9uIG9m IGxheWVyZWQKIG1vZHVsZXMsIHNvbWUgb3B0aW9uYWwsIHRoYXQgYWxsIHdvcmsgdG9nZXRoZXIg dG8gZm9ybSBhIHN0b3JhZ2Ugc3RhY2sgaW4gdXNlciBzcGFjZS4mbmJzcDsgU28gaWYgeW91IHRo aW5rIG9mIHRoZSB0b3Agb2YgdGhlIHN0YWNrIGJlaW5nIGZyb250IGVuZCBwcm90b2NvbCBtb2R1 bGVzIGxpa2UgaVNDU0kgYW5kIE5WTWVvRiBhbmQgdGhlbiB0aGUgbmV4dCBiaWcgbGF5ZXIgZG93 biBiZWluZyBhIGdlbmVyaWMgYmxvY2sgbGF5ZXIgZm9sbG93ZWQgYnkgYQogbG93ZXIgZGV2aWNl IGRyaXZlciBsYXllciBpdCBzaG91bGQgc3RhcnQgdG8gbWFrZSBtb3JlIHNlbnNlLiZuYnNwOyBU aGUgZ2VuZXJpYyBibG9jayBsYXllciBpcyBhIGxpZ2h0d2VpZ2h0IGJsb2NrIGFic3RyYWN0aW9u IGF0IHRoZSB0b3AgYW5kIHRoZW4gZGV2aWNlIHNwZWNpZmljIG1vZHVsZXMgYXQgdGhlIGJvdHRv bSB0byBpbnRlcmZhY2Ugd2l0aCBkZXZpY2UgZHJpdmVycy4gU28sIGFueXdoZXJlIHlvdSBzZWUg YW4gQVBJIHdpdGggJiM4MjIwO2JkZXYmIzgyMjE7IGluCiBpdCwgbGlrZSB0aGUgMiB5b3UgbWVu dGlvbiwgeW91JiM4MjE3O3JlIGluIHRoZSBnZW5lcmljIGJsb2NrIGxheWVyLiZuYnNwOyBJZiB0 aGUgYXBwbGljYXRpb24geW91JiM4MjE3O3ZlIGNvbnN0cnVjdGVkIGlzIGJhc2VkIG9uIE5WTWUg dGhlbiB0aGUgbmV4dCBsYXllciBkb3duIHdpbGwgYmUgdGhlIE5WTWUgZHJpdmVyIHdoZXJlIHlv dSYjODIxNztsbCBmaW5kIHRoZSBBUEkgdGhhdCB5b3UgbGlzdGVkIGluICgxKSBiZWxvdy4mbmJz cDsgQXMgSSBtZW50aW9uZWQgdGhvdWdoLCBhIGxvdCBvZgogdGhlIGxheWVycyBhcmUgb3B0aW9u YWwgaW5jbHVkaW5nIHRoZSBiZGV2IGxheWVyLiZuYnNwOyBJZiB5b3Ugd2FudGVkIHRvIHdyaXRl IGFuIGFwcGxpY2F0aW9uIHRoYXQgZGlkbiYjODIxNzt0IHVzZSBiZGV2cyAoeW91IGtuZXcgaXQg d2FzIG9ubHkgZXZlciBnb2luZyB0byBiZSBOVk1lIGFuZCBkaWRuJiM4MjE3O3Qgd2FudCB0aGUg bWluaW1hbCBvdmVyaGVhZCBvZiBiZGV2KSB5b3UgY291bGQgdXNlIHRob3NlIE5WTWUgZHJpdmVy IEFQSXMgZGlyZWN0bHkgaW4geW91ciBhcHBsaWNhdGlvbi48bzpwPjwvbzpwPjwvc3Bhbj48L3A+ CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxzcGFuIHN0eWxlPSJjb2xvcjojMUY0OTdEIj48bzpwPiZu YnNwOzwvbzpwPjwvc3Bhbj48L3A+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxzcGFuIHN0eWxlPSJj b2xvcjojMUY0OTdEIj5Ib3BlIHRoYXQgbWFrZXMgc2Vuc2UsIGFnYWluIEkmIzgyMTc7bSBzdXJl IG90aGVycyB3aWxsIGFkZCBtb3JlIGNsYXJpZnlpbmcgYml0cyBvZiBpbmZvcm1hdGlvbiBhcyB3 ZWxsLiZuYnNwOyBIZXJlIGFyZSBzb21lIGV4YW1wbGVzOjxvOnA+PC9vOnA+PC9zcGFuPjwvcD4K PHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9ImNvbG9yOiMxRjQ5N0QiPjxvOnA+Jm5i c3A7PC9vOnA+PC9zcGFuPjwvcD4KPHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9ImNv bG9yOiMxRjQ5N0QiPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zcGRrL3NwZGsvdHJlZS9t YXN0ZXIvZXhhbXBsZXMvbnZtZS9oZWxsb193b3JsZCI+aHR0cHM6Ly9naXRodWIuY29tL3NwZGsv c3Bkay90cmVlL21hc3Rlci9leGFtcGxlcy9udm1lL2hlbGxvX3dvcmxkPC9hPiBpcyBhbiBhcHBs aWNhdGlvbiB0aGF0IGRvZXNuJiM4MjE3O3QgdXNlIGJkZXYsIHRhbGtzIGRpcmVjdGx5IHRvIE5W TWU8bzpwPjwvbzpwPjwvc3Bhbj48L3A+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxzcGFuIHN0eWxl PSJjb2xvcjojMUY0OTdEIj48YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc3Bkay9zcGRrL3Ry ZWUvbWFzdGVyL2V4YW1wbGVzL2Jsb2IvaGVsbG9fd29ybGQiPmh0dHBzOi8vZ2l0aHViLmNvbS9z cGRrL3NwZGsvdHJlZS9tYXN0ZXIvZXhhbXBsZXMvYmxvYi9oZWxsb193b3JsZDwvYT4gaXMgYSBz aW1wbGUgYmxvYnN0b3JlIGV4YW1wbGUgKEkgZGlkbiYjODIxNzt0IG1lbnRpb24gYmxvYnN0b3Jl IGFib3ZlCiBidXQgaXRzIGFub3RoZXIgb3B0aW9uYWwgbGF5ZXIpIHRoYXQgZG9lcyB1c2UgYSBi ZGV2LiBJbiB0aGlzIGV4YW1wbGUgaXQgdXNlcyBhIHJhbSBkaXNrIChtYWxsb2MpIGJhY2sgZW5k IGJ1dCBjb3VsZCBhbHNvIGVhc2lseSB1c2UgYW4gTlZNZSBiYWNrIGVuZCBkaXJlY3RseSBhbmQg dGhlcmUmIzgyMTc7cyBhbiBvcGVuIHBhdGNoIHRoYXQgc2hvd3MgaG93IHRoYXQgd29ya3MgYXQK PGEgaHJlZj0iaHR0cHM6Ly9yZXZpZXcuZ2Vycml0aHViLmlvLyMvYy8zNzU0NjAvIj5odHRwczov L3Jldmlldy5nZXJyaXRodWIuaW8vIy9jLzM3NTQ2MC88L2E+IC0gYm90aCBvZiB0aGVzZSBtaWdo dCBub3QgYmUgdGhlIGJlc3QgZXhhbXBsZSBmb3IgeW91ciBxdWVzdGlvbiBiZWNhdXNlIGJsb2Jz dG9yZSBpcyB0aHJvd24gaW4gdGhlIG1peCBidXQgeW91IGNhbiBzZWUgdGhlIGJkZXYgcG9ydGlv biBpbiB0aGVyZSBhcyBwYXJ0IG9mIGJsb2JzdG9yZQogaW4gYSBzdWJkaXIgY2FsbGVkIGJkZXYg dW5kZXIgL2xpYi9ibG9iPG86cD48L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFs Ij48c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3RCI+PG86cD4mbmJzcDs8L286cD48L3NwYW4+PC9w Pgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3RCI+QW55d2F5 LCBob3BlIHRoYXQgaGVscHMgbW9yZSB0aGFuIGl0IGNvbmZ1c2VzCjwvc3Bhbj48c3BhbiBzdHls ZT0iZm9udC1mYW1pbHk6V2luZ2RpbmdzO2NvbG9yOiMxRjQ5N0QiPko8L3NwYW4+PHNwYW4gc3R5 bGU9ImNvbG9yOiMxRjQ5N0QiPiBGZWVsIGZyZWUgdG8ga2VlcCBhc2tpbmcgcXVlc3Rpb25zIHVu dGlsIGl0IG1ha2VzIHNlbnNlJiM4MjMwOzxvOnA+PC9vOnA+PC9zcGFuPjwvcD4KPHAgY2xhc3M9 Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9ImNvbG9yOiMxRjQ5N0QiPjxvOnA+Jm5ic3A7PC9vOnA+ PC9zcGFuPjwvcD4KPHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9ImNvbG9yOiMxRjQ5 N0QiPlRoeDxvOnA+PC9vOnA+PC9zcGFuPjwvcD4KPHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4g c3R5bGU9ImNvbG9yOiMxRjQ5N0QiPlBhdWw8bzpwPjwvbzpwPjwvc3Bhbj48L3A+CjxwIGNsYXNz PSJNc29Ob3JtYWwiPjxzcGFuIHN0eWxlPSJjb2xvcjojMUY0OTdEIj48bzpwPiZuYnNwOzwvbzpw Pjwvc3Bhbj48L3A+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxzcGFuIHN0eWxlPSJjb2xvcjojMUY0 OTdEIj5QUzogdGhlcmUmIzgyMTc7cyBhbHNvIGEgYnVuY2ggb2YgZXhpc3RpbmcgYmRldiBiYWNr IGVuZCBtb2R1bGVzIGhlcmUKPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NwZGsvc3Bkay90 cmVlL21hc3Rlci9saWIvYmRldiI+aHR0cHM6Ly9naXRodWIuY29tL3NwZGsvc3Bkay90cmVlL21h c3Rlci9saWIvYmRldjwvYT4gdGhhdCBtYXkgaGVscCBjbGFyaWZ5IHRoZSBjb25jZXB0cy4gTm90 ZSB0aGF0IHlvdSBjYW4gYWxzbyBzdGFjayBiZGV2cyBpbiBvcmRlciB0byBpbnRlcmNlcHQgSU8g Y29taW5nIGFuZCBnb2luZyBzbyB5b3UgY2FuIGRvIHZhbHVlIGFkZGVkIHRoaW5ncwogZWFzaWx5 LCB3ZSBjYWxsIHRob3NlICYjODIyMDt2aXJ0dWFsIGJkZXZzJiM4MjIxOyBhbmQgeW91JiM4MjE3 O2xsIHNlZSBzb21lIGV4YW1wbGVzIGluIHRoZSBkaXIgSSBqdXN0IG1lbnRpb25lZCAoaWUgc3Bs aXQsIGx2b2wpPG86cD48L286cD48L3NwYW4+PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3Bh biBzdHlsZT0iY29sb3I6IzFGNDk3RCI+PG86cD4mbmJzcDs8L286cD48L3NwYW4+PC9wPgo8cCBj bGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0iY29sb3I6IzFGNDk3RCI+PG86cD4mbmJzcDs8 L286cD48L3NwYW4+PC9wPgo8ZGl2Pgo8ZGl2IHN0eWxlPSJib3JkZXI6bm9uZTtib3JkZXItdG9w OnNvbGlkICNFMUUxRTEgMS4wcHQ7cGFkZGluZzozLjBwdCAwaW4gMGluIDBpbiI+CjxwIGNsYXNz PSJNc29Ob3JtYWwiPjxhIG5hbWU9Il9fX19fcmVwbHlzZXBhcmF0b3IiPjwvYT48Yj5Gcm9tOjwv Yj4gU1BESyBbPGEgaHJlZj0ibWFpbHRvOnNwZGstYm91bmNlc0BsaXN0cy4wMS5vcmciPm1haWx0 bzpzcGRrLWJvdW5jZXNAbGlzdHMuMDEub3JnPC9hPl0KPGI+T24gQmVoYWxmIE9mIDwvYj5TcmVl bmkgKFNyZWVuaXZhc2EpIEJ1c2FtIChTdGVsbHVzKTxicj4KPGI+U2VudDo8L2I+IEZyaWRheSwg Tm92ZW1iZXIgMTAsIDIwMTcgNjoyNSBQTTxicj4KPGI+VG86PC9iPiA8YSBocmVmPSJtYWlsdG86 c3Bka0BsaXN0cy4wMS5vcmciPnNwZGtAbGlzdHMuMDEub3JnPC9hPjxicj4KPGI+U3ViamVjdDo8 L2I+IFtTUERLXSBSZXF1ZXN0IGZvciBtb3JlIGRldGFpbHMgb24gU1BESyBkcml2ZXIgQVBJLjxv OnA+PC9vOnA+PC9wPgo8L2Rpdj4KPC9kaXY+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxvOnA+Jm5i c3A7PC9vOnA+PC9wPgo8cCBjbGFzcz0iTXNvTm9ybWFsIj5JIGFtIG5ldyB0byBTUERLIGRyaXZl ciBhbmQgdHJ5aW5nIHRvIHVuZGVyc3RhbmQgdGhlIHZhcmlvdXMgQVBJJiM4MjE3O3MgYXZhaWxh YmxlIHRvIGRvIEkvTyBvbiBOVk1lIGxvY2FsIGRldmljZSBhbmQgdXNpbmcgTlZNZW9GIHByb3Rv Y29sIG9uIGEgdGFyZ2V0IGRldmljZS4KPG86cD48L286cD48L3A+CjxwIGNsYXNzPSJNc29Ob3Jt YWwiPkkgc2VlIGRpZmZlcmVudCBpbnRlcmZhY2VzIGZvciB0aGUgcmVhZCBhbmQgd3JpdGUgSS9P IG9wZXJhdGlvbnMuPG86cD48L286cD48L3A+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPkl0IHNlZW1z IHRoZXJlIGFyZSB0d28gdHlwZXMgb2YgaW50ZXJmYWNlcyBhdmFpbGFibGUuPG86cD48L286cD48 L3A+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjEuIHNwZGtfbnZtZV9uc19jbWRfcmVhZCgpIGFuZCBz cGRrX252bWVfbnNfY21kX3dyaXRlKCkgYW5kIHJlbGF0ZWQgZnVuY3Rpb24uIFRoaXMgaXMgdXNl ZCBmb3IgUENJZSBkZXZpY2VzLiBJdCBzZWVtcyB0byBhcHBseSB0byBkZXZpY2VzIGF0dGFjaGVk IGxvY2FsbHkuPG86cD48L286cD48L3A+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjIuIHNwZGtfYmRl dl9yZWFkX2Jsb2NrcygpIGFuZCBzcGRrX2JkZXZfd3JpdGVfYmxvY2tzKCkgYW5kIHJlbGF0ZWQg QVBJJiM4MjE3O3MgaW4gbGliL2JkZXYuPG86cD48L286cD48L3A+CjxwIGNsYXNzPSJNc29Ob3Jt YWwiPkkgaGF2ZSBiZWVuIGxvb2tpbmcgYXQgdGhlIGNvZGUgYW5kIHRyeWluZyB0byB1bmRlcnN0 YW5kIGhvdyB0aGlzIEFQSSBhbmQgcmVsYXRlZCBBUElzIGZvciB0aGUgbW9kdWxlIGhhcyBiZWVu IHVzZWQsIHRoZSBBUEkmIzgyMTc7cyBpbiAyLiBhcmUgdXNlZCBmb3IgYmxvYmZzIEkvTyBvcGVy YXRpb24gc3Bkay9saWIvYmxvYi9iZGV2LyosIHdoZW4gdGhlcmUgaXMgYSBibG9iIGZpbGVzeXN0 ZW0gYW5kIGZvciBJL08gb3BlcmF0aW9uCiBvbiBOVk1lIGRldmljZXMgdXNpbmcgTlZNZW9GIHBy b3RvY29sIHNwZGsvbGliL252bWYvKi48bzpwPjwvbzpwPjwvcD4KPHAgY2xhc3M9Ik1zb05vcm1h bCI+SXMgdGhpcyBhIGNvcnJlY3QgYXNzdW1wdGlvbj8gSXMgdGhlIGxpYi9iZGV2IGxheWVyIGRl dmVsb3BlZCB0byBhZGRyZXNzIG9ubHkgdGhlc2UgY2FzZXM/PG86cD48L286cD48L3A+CjxwIGNs YXNzPSJNc29Ob3JtYWwiPkNhbiB0aGUgbGliL2JkZXYgQVBJIGJlIHVzZWQgb24gYSBsb2NhbCBO Vk1lIGRldmljZT8gSWYgc28sIGlzIHRoZXJlIGEgdGVzdCBwcm9ncmFtIHRvIHVuZGVyc3RhbmQg aG93IHRvIGNyZWF0ZSBhIGJkZXYgZGV2aWNlIGFuZCBkbyB0aGUgSS9PIG9uIE5WTWUgU1NEIGJs b2NrIGRldmljZT88bzpwPjwvbzpwPjwvcD4KPHAgY2xhc3M9Ik1zb05vcm1hbCI+UGxlYXNlIGxl dCBtZSBrbm93IGlmIHRoZXJlIGlzIGFuIGV4YW1wbGUgdG8gdW5kZXJzdGFuZCBob3cgdG8gdXNl IHRoZSBsaWIvbnZtZiBpbnRlcmZhY2VzLiBJIHdhbnQgdG8gdGVzdCBhIGRldmljZSBvbiByZW1v dGUgdGFyZ2V0IHVzaW5nIE5WTWVvRiBwcm90b2NvbC48bzpwPjwvbzpwPjwvcD4KPHAgY2xhc3M9 Ik1zb05vcm1hbCI+PG86cD4mbmJzcDs8L286cD48L3A+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPlRo YW5rcyB2ZXJ5IG11Y2ggZm9yIGFueSBoZWxwIGluIHRoZSBsaWIvYmRldiBBUEkuPG86cD48L286 cD48L3A+CjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxvOnA+Jm5ic3A7PC9vOnA+PC9wPgo8cCBjbGFz cz0iTXNvTm9ybWFsIj48bzpwPiZuYnNwOzwvbzpwPjwvcD4KPC9kaXY+CjwvYm9keT4KPC9odG1s Pgo= --===============3360458458674382862==--