From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8594CC282CB for ; Tue, 5 Feb 2019 12:30:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3199C2083B for ; Tue, 5 Feb 2019 12:30:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="idEj978L" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727221AbfBEMao (ORCPT ); Tue, 5 Feb 2019 07:30:44 -0500 Received: from mail-lj1-f196.google.com ([209.85.208.196]:37106 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725947AbfBEMao (ORCPT ); Tue, 5 Feb 2019 07:30:44 -0500 Received: by mail-lj1-f196.google.com with SMTP id t18-v6so2727959ljd.4 for ; Tue, 05 Feb 2019 04:30:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding:content-language; bh=oCA+jJUgCsPMslv6Uos0OmNuevTfTV8l3yM/Xu4D5+g=; b=idEj978LSvZZN3Km5nZmFiPhOSOmcEZysO6XcX9rylkeQrEIUPU+4gt23UA2d0hGnI BStrWMTIhxV7xASAUkt2sTTUkQcRVzKaSMFkbVpcgnNARiuFb1a7pa7pOPJsUlgJJoa7 MyJfWDpQQVO512vOWNOHDfykLW57eZ27D7x4N08hmlHoCnJ55qGUj1mLSLK+H0j6MBjx XIfbFsWnbq8K5UswNUqVNzRA2cAYUvMKmjqaQCKptoZaumLLwS2ymfa89Kq1nFk8VqVi lX4ef3HyBqD6i4U4iC5NSyA63A+zCGzhDFiFRjGwqxEHQarrfDXrL6VF8iwaDdt4pO7O J13w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=oCA+jJUgCsPMslv6Uos0OmNuevTfTV8l3yM/Xu4D5+g=; b=cc7xPnJvaEL2LwQAFbdpwiVRNZgaZo+oEH/13OkPa0J5UZtGlZBYnh8PGlGCXpC51K VZvWGL6CrHlWVXkUqhx9guxyh5COKlsZOyz3VfTEk9WN2Kyf5u7tb1H/5TukzRf6Rdp4 AmlMuapf+OyOsG8hHMK9m0jz/PnAGYir9TPYvUtb/uHKy+IXU9LUXHHng3bZLlhzS6yT dadYiOQ2YpRv+zT1v1DcpX8UgZ3Te42isPy7Y8khp4R4EZ3j3c3AMyzP7m6Eu5wpHium K1/QyRyLuxQ048TsEgdzPdlWj6uxx9y/+U2RiUgH2QM+5LKXxGOg970xzAcjZV0R66Ke JU8A== X-Gm-Message-State: AHQUAuYbV8AJQnCXCkNuEqpCddKBMCF6xLHdZIXaa6DhOPIqphMYnrRd mx4WJgsU0V5ryETTfC6rpN4= X-Google-Smtp-Source: AHgI3IavuARJ2HCf83+tXElXB4atEje5JU2+EbWNRl+IewR9wlbYHNzRzAswuZPbvwMpP4PZGAVAZg== X-Received: by 2002:a2e:8596:: with SMTP id b22-v6mr2835199lji.122.1549369841174; Tue, 05 Feb 2019 04:30:41 -0800 (PST) Received: from [10.17.182.20] (ll-22.209.223.85.sovam.net.ua. [85.223.209.22]) by smtp.gmail.com with ESMTPSA id q23sm3713530lfm.82.2019.02.05.04.30.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 05 Feb 2019 04:30:40 -0800 (PST) Subject: Re: [Xen-devel][PATCH v4 1/1] cameraif: add ABI for para-virtual camera To: Hans Verkuil , "Oleksandr_Andrushchenko@epam.com" , "xen-devel@lists.xenproject.org" , "konrad.wilk@oracle.com" , "jgross@suse.com" , "boris.ostrovsky@oracle.com" , "mchehab@kernel.org" , "linux-media@vger.kernel.org" , "sakari.ailus@linux.intel.com" , "koji.matsuoka.xm@renesas.com" References: <20190115093853.15495-1-andr2000@gmail.com> <20190115093853.15495-2-andr2000@gmail.com> <393f824d-e543-476c-777f-402bcc1c0bcb@xs4all.nl> <1152536e-9238-4192-653e-b784b34b8a0d@epam.com> <3ea2c5a1-b5a1-ba70-ade5-d14cc3aace66@xs4all.nl> <08d6da1b-f061-010c-abf8-865564c26d49@gmail.com> From: Oleksandr Andrushchenko Message-ID: <474636e0-8059-7b75-8b48-a216c6defaf4@gmail.com> Date: Tue, 5 Feb 2019 14:30:39 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org On 2/5/19 2:14 PM, Hans Verkuil wrote: > On 2/5/19 12:44 PM, Oleksandr Andrushchenko wrote: >> On 2/5/19 12:53 PM, Hans Verkuil wrote: >>> On 2/5/19 11:44 AM, Oleksandr Andrushchenko wrote: >>>> On 2/5/19 11:34 AM, Hans Verkuil wrote: >>>>> On 2/5/19 9:48 AM, Oleksandr Andrushchenko wrote: >>>>>> On 1/23/19 10:14 AM, Oleksandr Andrushchenko wrote: >>>>>>> Any comments from Xen community? >>>>>>> Konrad? >>>>>> While I am still looking forward to any comments from Xen community... >>>>>>> On 1/15/19 4:44 PM, Hans Verkuil wrote: >>>>>>>> Hi Oleksandr, >>>>>>>> >>>>>>>> Just two remaining comments: >>>>>>>> >>>>>>>> On 1/15/19 10:38 AM, Oleksandr Andrushchenko wrote: >>>>>>>>> From: Oleksandr Andrushchenko >>>>>>>>> >>>>>>>>> This is the ABI for the two halves of a para-virtualized >>>>>>>>> camera driver which extends Xen's reach multimedia capabilities even >>>>>>>>> farther enabling it for video conferencing, In-Vehicle Infotainment, >>>>>>>>> high definition maps etc. >>>>>>>>> >>>>>>>>> The initial goal is to support most needed functionality with the >>>>>>>>> final idea to make it possible to extend the protocol if need be: >>>>>>>>> >>>>>>>>> 1. Provide means for base virtual device configuration: >>>>>>>>>      - pixel formats >>>>>>>>>      - resolutions >>>>>>>>>      - frame rates >>>>>>>>> 2. Support basic camera controls: >>>>>>>>>      - contrast >>>>>>>>>      - brightness >>>>>>>>>      - hue >>>>>>>>>      - saturation >>>>>>>>> 3. Support streaming control >>>>>>>>> >>>>>>>>> Signed-off-by: Oleksandr Andrushchenko >>>>>>>>> --- >>>>>>>>>      xen/include/public/io/cameraif.h | 1364 ++++++++++++++++++++++++++++++ >>>>>>>>>      1 file changed, 1364 insertions(+) >>>>>>>>>      create mode 100644 xen/include/public/io/cameraif.h >>>>>>>>> >>>>>>>>> diff --git a/xen/include/public/io/cameraif.h b/xen/include/public/io/cameraif.h >>>>>>>>> new file mode 100644 >>>>>>>>> index 000000000000..246eb2457f40 >>>>>>>>> --- /dev/null >>>>>>>>> +++ b/xen/include/public/io/cameraif.h >>>>>>>>> @@ -0,0 +1,1364 @@ >>>>>>>> >>>>>>>> >>>>>>>>> +/* >>>>>>>>> + ****************************************************************************** >>>>>>>>> + *                                 EVENT CODES >>>>>>>>> + ****************************************************************************** >>>>>>>>> + */ >>>>>>>>> +#define XENCAMERA_EVT_FRAME_AVAIL      0x00 >>>>>>>>> +#define XENCAMERA_EVT_CTRL_CHANGE      0x01 >>>>>>>>> + >>>>>>>>> +/* Resolution has changed. */ >>>>>>>>> +#define XENCAMERA_EVT_CFG_FLG_RESOL    (1 << 0) >>>>>>>> I think this flag is a left-over from v2 and should be removed. >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>>> + * Request number of buffers to be used: >>>>>>>>> + *         0                1                 2               3        octet >>>>>>>>> + * +----------------+----------------+----------------+----------------+ >>>>>>>>> + * |               id                | _OP_BUF_REQUEST|   reserved     | 4 >>>>>>>>> + * +----------------+----------------+----------------+----------------+ >>>>>>>>> + * |                             reserved                              | 8 >>>>>>>>> + * +----------------+----------------+----------------+----------------+ >>>>>>>>> + * |    num_bufs    |                     reserved                     | 12 >>>>>>>>> + * +----------------+----------------+----------------+----------------+ >>>>>>>>> + * |                             reserved                              | 16 >>>>>>>>> + * +----------------+----------------+----------------+----------------+ >>>>>>>>> + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| >>>>>>>>> + * +----------------+----------------+----------------+----------------+ >>>>>>>>> + * |                             reserved                              | 64 >>>>>>>>> + * +----------------+----------------+----------------+----------------+ >>>>>>>>> + * >>>>>>>>> + * num_bufs - uint8_t, desired number of buffers to be used. This is >>>>>>>>> + *   limited to the value configured in XenStore.max-buffers. >>>>>>>>> + *   Passing zero num_bufs in this request (after streaming has stopped >>>>>>>>> + *   and all buffers destroyed) unblocks camera configuration changes. >>>>>>>> I think the phrase 'unblocks camera configuration changes' is confusing. >>>>>>>> >>>>>>>> In v3 this sentence came after the third note below, and so it made sense >>>>>>>> in that context, but now the order has been reversed and it became hard to >>>>>>>> understand. >>>>>>>> >>>>>>>> I'm not sure what the best approach is to fix this. One option is to remove >>>>>>>> the third note and integrate it somehow in the sentence above. Or perhaps >>>>>>>> do away with the 'notes' at all and just write a more extensive documentation >>>>>>>> for this op. I leave that up to you. >>>>>> Hans, how about: >>>>>> >>>>>>    * num_bufs - uint8_t, desired number of buffers to be used. >>>>>>    * >>>>>>    * The number of buffers in this request must not exceed the value configured >>>>>>    * in XenStore.max-buffers. If the number of buffers is not zero then after this >>>>>>    * request the camera configuration cannot be changed. In order to allow camera >>>>>>    * (re)configuration this request must be sent with num_bufs set to zero and >>>>>>    * the streaming must be stopped and buffers destroyed. >>>>>>    * It is allowed for the frontend to send multiple XENCAMERA_OP_BUF_REQUEST >>>>>>    * requests before sending XENCAMERA_OP_STREAM_START request to update or >>>>>>    * tune the final configuration. >>>>>>    * Frontend is responsible for checking the corresponding response in order to >>>>>>    * see if the values reported back by the backend do match the desired ones >>>>>>    * and can be accepted. >>>>>>    * >>>>>>    * See response format for this request. >>>>>>    */ >>>>> Hmm, it still is awkward. Part of the reason for that is that VIDIOC_REQBUFS >>>>> is just weird in that a value of 0 has a special meaning. >>>>> >>>>> Perhaps it would be much cleaner for the Xen implementation to just add a new >>>>> OP: _OP_FREE_ALL_BUFS (or perhaps _RELEASE_ALL_BUFS) that effectively does >>>>> VIDIOC_REQBUFS with a 0 count value. And this OP_BUF_REQUEST (wouldn't >>>>> OP_REQUEST_BUFS be a better name?) >>>> I have all operation categorized, e.g. there are commands >>>> for configuration (XENCAMERA_OP_CONFIG_XXX), >>>> buffer handling (XENCAMERA_OP_BUF_XXX) etc., so I prefer to >>>> keep the name as is. >>>>>    would then do nothing or return an error >>>>> if num_bufs == 0. >>>>> >>>>> If you don't want to create a new Xen op, then I would change the text some >>>>> more since you do not actually explain what the op does if num_bufs is 0. >>>> Well, I tend to keep this as is with no additional op. >>>>> I would write something like this: >>>>> >>>>> If num_bufs is greater than 0, then . >>>>> >>>>> If num_bufs is equal to 0, then . >>>>> >>>>> If num_bufs is not zero then after this request the camera configuration >>>>> cannot be changed. In order to allow camera (re)configuration this request >>>>> must be sent with num_bufs set to zero and the streaming must be stopped >>>>> and buffers destroyed. >>>> Next try: >>>> >>>>   * num_bufs - uint8_t, desired number of buffers to be used. >>>>   * >>>>   * If num_bufs is not zero then the backend validates the requested number of >>>>   * buffers and responds with the number of buffers allowed for this frontend. >>>>   * Frontend is responsible for checking the corresponding response in order to >>>>   * see if the values reported back by the backend do match the desired ones >>>>   * and can be accepted. >>>>   * Frontend is allowed to send multiple XENCAMERA_OP_BUF_REQUEST requests >>>>   * before sending XENCAMERA_OP_STREAM_START request to update or tune the >>>>   * final configuration. >>>>   * Frontend is not allowed to change the number of buffers and/or camera >>>>   * configuration after the streaming has started. >>> This all looks good. >> Great >>>>   * >>>>   * In order to allow camera (re)configuration this request must be sent with >>>>   * num_bufs set to zero and the streaming must be stopped and buffers destroyed. >>> You just say that if you want to reconfigure (and this only applies to reconfigure, >>> not to the initial configure step since then there are no buffers allocated yet), >>> then you need to call this with num_bufs == 0. But you don't explain what this op >>> does if num_bufs == 0! >>> >>> So before this sentence you need to add a description of what this op does if num_bufs >>> is 0, and change '(re)configuration' to 'reconfiguration'. >> Well, it is a good question. I already describe what happens if >> streaming has stopped and buffers destroyed and num_bufs == 0: >> this is a reconfiguration. >> >> I also have a note that "Frontend is not allowed to change the >> number of buffers and/or camera configuration after the streaming >> has started.": this is the case that we cannot change the number of >> buffers during the streaming, e.g. one cannot send num_bufs == 0 >> at this time. >> >> So, what is not covered is that the streaming has never started, >> num_bufs has or has not been set to some value and now frontend >> requests num_bufs == 0? >> It seems that we can state that in this case backend does >> nothing or it may free any buffers if it has allocated any, so the >> tail reads as: >> >>  * If num_bufs is 0 and streaming has not started yet, then the backend may >>  * free all previously allocated buffers (if any) or do nothing. > Much better. Now you actually explain what this op does if num_bufs == 0. > >>  * >>  * If camera reconfiguration is required then this request must be sent with >>  * num_bufs set to zero and streaming must be stopped and buffers destroyed. > Shouldn't the order be to first stop streaming, then call this request with > num_bufs set to 0 and finally destroy the buffers? Yes, I meant that, but this does need to be more clear:  * If camera reconfiguration is required then the streaming must be stopped  * and this request must be sent with num_bufs set to zero and finally  * buffers destroyed. > > Trying to call this if streaming is in progress will result in an error. > I think that should be documented as well. Sure > > Sorry for paying so much attention to this, but I think it is important that > this is documented precisely. Thank you for helping with this - your comments are really important and make the description precise. Ok, so finally:  * num_bufs - uint8_t, desired number of buffers to be used.  *  * If num_bufs is not zero then the backend validates the requested number of  * buffers and responds with the number of buffers allowed for this frontend.  * Frontend is responsible for checking the corresponding response in order to  * see if the values reported back by the backend do match the desired ones  * and can be accepted.  * Frontend is allowed to send multiple XENCAMERA_OP_BUF_REQUEST requests  * before sending XENCAMERA_OP_STREAM_START request to update or tune the  * final configuration.  * Frontend is not allowed to change the number of buffers and/or camera  * configuration after the streaming has started.  *  * If num_bufs is 0 and streaming has not started yet, then the backend may  * free all previously allocated buffers (if any) or do nothing.  * Trying to call this if streaming is in progress will result in an error.  *  * If camera reconfiguration is required then the streaming must be stopped  * and this request must be sent with num_bufs set to zero and finally  * buffers destroyed.  *  * Please note, that the number of buffers in this request must not exceed  * the value configured in XenStore.max-buffers.  *  * See response format for this request. > Regards, > > Hans Thank you, Oleksandr >>  * >>  * Please note, that the number of buffers in this request must not exceed >>  * the value configured in XenStore.max-buffers. >>  * >>  * See response format for this request. >> >>> Regards, >>> >>>     Hans >>> >>>>   * >>>>   * Please note, that the number of buffers in this request must not exceed >>>>   * the value configured in XenStore.max-buffers. >>>>   * >>>>   * See response format for this request. >>>> >>>>> Regards, >>>>> >>>>>      Hans >>>>> >>>>>>>>> + * >>>>>>>>> + * See response format for this request. >>>>>>>>> + * >>>>>>>>> + * Notes: >>>>>>>>> + *  - frontend must check the corresponding response in order to see >>>>>>>>> + *    if the values reported back by the backend do match the desired ones >>>>>>>>> + *    and can be accepted. >>>>>>>>> + *  - frontend may send multiple XENCAMERA_OP_BUF_REQUEST requests before >>>>>>>>> + *    sending XENCAMERA_OP_STREAM_START request to update or tune the >>>>>>>>> + *    configuration. >>>>>>>>> + *  - after this request camera configuration cannot be changed, unless >>>>>>>> camera configuration -> the camera configuration >>>>>>>> >>>>>>>>> + *    streaming is stopped and buffers destroyed >>>>>>>>> + */ >>>>>>>> Regards, >>>>>>>> >>>>>>>>       Hans From mboxrd@z Thu Jan 1 00:00:00 1970 From: Oleksandr Andrushchenko Subject: Re: [PATCH v4 1/1] cameraif: add ABI for para-virtual camera Date: Tue, 5 Feb 2019 14:30:39 +0200 Message-ID: <474636e0-8059-7b75-8b48-a216c6defaf4@gmail.com> References: <20190115093853.15495-1-andr2000@gmail.com> <20190115093853.15495-2-andr2000@gmail.com> <393f824d-e543-476c-777f-402bcc1c0bcb@xs4all.nl> <1152536e-9238-4192-653e-b784b34b8a0d@epam.com> <3ea2c5a1-b5a1-ba70-ade5-d14cc3aace66@xs4all.nl> <08d6da1b-f061-010c-abf8-865564c26d49@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1gqzsD-0003BF-Et for xen-devel@lists.xenproject.org; Tue, 05 Feb 2019 12:30:45 +0000 Received: by mail-lj1-x242.google.com with SMTP id g11-v6so2744726ljk.3 for ; Tue, 05 Feb 2019 04:30:42 -0800 (PST) In-Reply-To: Content-Language: en-US List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" To: Hans Verkuil , "Oleksandr_Andrushchenko@epam.com" , "xen-devel@lists.xenproject.org" , "konrad.wilk@oracle.com" , "jgross@suse.com" , "boris.ostrovsky@oracle.com" , "mchehab@kernel.org" , "linux-media@vger.kernel.org" , "sakari.ailus@linux.intel.com" , "koji.matsuoka.xm@renesas.com" List-Id: xen-devel@lists.xenproject.org T24gMi81LzE5IDI6MTQgUE0sIEhhbnMgVmVya3VpbCB3cm90ZToKPiBPbiAyLzUvMTkgMTI6NDQg UE0sIE9sZWtzYW5kciBBbmRydXNoY2hlbmtvIHdyb3RlOgo+PiBPbiAyLzUvMTkgMTI6NTMgUE0s IEhhbnMgVmVya3VpbCB3cm90ZToKPj4+IE9uIDIvNS8xOSAxMTo0NCBBTSwgT2xla3NhbmRyIEFu ZHJ1c2hjaGVua28gd3JvdGU6Cj4+Pj4gT24gMi81LzE5IDExOjM0IEFNLCBIYW5zIFZlcmt1aWwg d3JvdGU6Cj4+Pj4+IE9uIDIvNS8xOSA5OjQ4IEFNLCBPbGVrc2FuZHIgQW5kcnVzaGNoZW5rbyB3 cm90ZToKPj4+Pj4+IE9uIDEvMjMvMTkgMTA6MTQgQU0sIE9sZWtzYW5kciBBbmRydXNoY2hlbmtv IHdyb3RlOgo+Pj4+Pj4+IEFueSBjb21tZW50cyBmcm9tIFhlbiBjb21tdW5pdHk/Cj4+Pj4+Pj4g S29ucmFkPwo+Pj4+Pj4gV2hpbGUgSSBhbSBzdGlsbCBsb29raW5nIGZvcndhcmQgdG8gYW55IGNv bW1lbnRzIGZyb20gWGVuIGNvbW11bml0eS4uLgo+Pj4+Pj4+IE9uIDEvMTUvMTkgNDo0NCBQTSwg SGFucyBWZXJrdWlsIHdyb3RlOgo+Pj4+Pj4+PiBIaSBPbGVrc2FuZHIsCj4+Pj4+Pj4+Cj4+Pj4+ Pj4+IEp1c3QgdHdvIHJlbWFpbmluZyBjb21tZW50czoKPj4+Pj4+Pj4KPj4+Pj4+Pj4gT24gMS8x NS8xOSAxMDozOCBBTSwgT2xla3NhbmRyIEFuZHJ1c2hjaGVua28gd3JvdGU6Cj4+Pj4+Pj4+PiBG cm9tOiBPbGVrc2FuZHIgQW5kcnVzaGNoZW5rbyA8b2xla3NhbmRyX2FuZHJ1c2hjaGVua29AZXBh bS5jb20+Cj4+Pj4+Pj4+Pgo+Pj4+Pj4+Pj4gVGhpcyBpcyB0aGUgQUJJIGZvciB0aGUgdHdvIGhh bHZlcyBvZiBhIHBhcmEtdmlydHVhbGl6ZWQKPj4+Pj4+Pj4+IGNhbWVyYSBkcml2ZXIgd2hpY2gg ZXh0ZW5kcyBYZW4ncyByZWFjaCBtdWx0aW1lZGlhIGNhcGFiaWxpdGllcyBldmVuCj4+Pj4+Pj4+ PiBmYXJ0aGVyIGVuYWJsaW5nIGl0IGZvciB2aWRlbyBjb25mZXJlbmNpbmcsIEluLVZlaGljbGUg SW5mb3RhaW5tZW50LAo+Pj4+Pj4+Pj4gaGlnaCBkZWZpbml0aW9uIG1hcHMgZXRjLgo+Pj4+Pj4+ Pj4KPj4+Pj4+Pj4+IFRoZSBpbml0aWFsIGdvYWwgaXMgdG8gc3VwcG9ydCBtb3N0IG5lZWRlZCBm dW5jdGlvbmFsaXR5IHdpdGggdGhlCj4+Pj4+Pj4+PiBmaW5hbCBpZGVhIHRvIG1ha2UgaXQgcG9z c2libGUgdG8gZXh0ZW5kIHRoZSBwcm90b2NvbCBpZiBuZWVkIGJlOgo+Pj4+Pj4+Pj4KPj4+Pj4+ Pj4+IDEuIFByb3ZpZGUgbWVhbnMgZm9yIGJhc2UgdmlydHVhbCBkZXZpY2UgY29uZmlndXJhdGlv bjoKPj4+Pj4+Pj4+ICDCoMKgwqDCoCAtIHBpeGVsIGZvcm1hdHMKPj4+Pj4+Pj4+ICDCoMKgwqDC oCAtIHJlc29sdXRpb25zCj4+Pj4+Pj4+PiAgwqDCoMKgwqAgLSBmcmFtZSByYXRlcwo+Pj4+Pj4+ Pj4gMi4gU3VwcG9ydCBiYXNpYyBjYW1lcmEgY29udHJvbHM6Cj4+Pj4+Pj4+PiAgwqDCoMKgwqAg LSBjb250cmFzdAo+Pj4+Pj4+Pj4gIMKgwqDCoMKgIC0gYnJpZ2h0bmVzcwo+Pj4+Pj4+Pj4gIMKg wqDCoMKgIC0gaHVlCj4+Pj4+Pj4+PiAgwqDCoMKgwqAgLSBzYXR1cmF0aW9uCj4+Pj4+Pj4+PiAz LiBTdXBwb3J0IHN0cmVhbWluZyBjb250cm9sCj4+Pj4+Pj4+Pgo+Pj4+Pj4+Pj4gU2lnbmVkLW9m Zi1ieTogT2xla3NhbmRyIEFuZHJ1c2hjaGVua28gPG9sZWtzYW5kcl9hbmRydXNoY2hlbmtvQGVw YW0uY29tPgo+Pj4+Pj4+Pj4gLS0tCj4+Pj4+Pj4+PiAgwqDCoMKgwqAgeGVuL2luY2x1ZGUvcHVi bGljL2lvL2NhbWVyYWlmLmggfCAxMzY0ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwo+ Pj4+Pj4+Pj4gIMKgwqDCoMKgIDEgZmlsZSBjaGFuZ2VkLCAxMzY0IGluc2VydGlvbnMoKykKPj4+ Pj4+Pj4+ICDCoMKgwqDCoCBjcmVhdGUgbW9kZSAxMDA2NDQgeGVuL2luY2x1ZGUvcHVibGljL2lv L2NhbWVyYWlmLmgKPj4+Pj4+Pj4+Cj4+Pj4+Pj4+PiBkaWZmIC0tZ2l0IGEveGVuL2luY2x1ZGUv cHVibGljL2lvL2NhbWVyYWlmLmggYi94ZW4vaW5jbHVkZS9wdWJsaWMvaW8vY2FtZXJhaWYuaAo+ Pj4+Pj4+Pj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPj4+Pj4+Pj4+IGluZGV4IDAwMDAwMDAwMDAw MC4uMjQ2ZWIyNDU3ZjQwCj4+Pj4+Pj4+PiAtLS0gL2Rldi9udWxsCj4+Pj4+Pj4+PiArKysgYi94 ZW4vaW5jbHVkZS9wdWJsaWMvaW8vY2FtZXJhaWYuaAo+Pj4+Pj4+Pj4gQEAgLTAsMCArMSwxMzY0 IEBACj4+Pj4+Pj4+IDxzbmlwPgo+Pj4+Pj4+Pgo+Pj4+Pj4+Pj4gKy8qCj4+Pj4+Pj4+PiArICoq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKgo+Pj4+Pj4+Pj4gKyAqwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBFVkVOVCBDT0RFUwo+Pj4+ Pj4+Pj4gKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioKPj4+Pj4+Pj4+ICsgKi8KPj4+Pj4+Pj4+ICsj ZGVmaW5lIFhFTkNBTUVSQV9FVlRfRlJBTUVfQVZBSUzCoMKgwqDCoMKgIDB4MDAKPj4+Pj4+Pj4+ ICsjZGVmaW5lIFhFTkNBTUVSQV9FVlRfQ1RSTF9DSEFOR0XCoMKgwqDCoMKgIDB4MDEKPj4+Pj4+ Pj4+ICsKPj4+Pj4+Pj4+ICsvKiBSZXNvbHV0aW9uIGhhcyBjaGFuZ2VkLiAqLwo+Pj4+Pj4+Pj4g KyNkZWZpbmUgWEVOQ0FNRVJBX0VWVF9DRkdfRkxHX1JFU09MwqDCoMKgICgxIDw8IDApCj4+Pj4+ Pj4+IEkgdGhpbmsgdGhpcyBmbGFnIGlzIGEgbGVmdC1vdmVyIGZyb20gdjIgYW5kIHNob3VsZCBi ZSByZW1vdmVkLgo+Pj4+Pj4+Pgo+Pj4+Pj4+PiA8c25pcD4KPj4+Pj4+Pj4KPj4+Pj4+Pj4+ICsg KiBSZXF1ZXN0IG51bWJlciBvZiBidWZmZXJzIHRvIGJlIHVzZWQ6Cj4+Pj4+Pj4+PiArICrCoMKg wqDCoMKgwqDCoMKgIDDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgMcKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIDLCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDPCoMKg wqDCoMKgwqDCoCBvY3RldAo+Pj4+Pj4+Pj4gKyAqICstLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0t LS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKwo+Pj4+Pj4+Pj4gKyAq IHzCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGlkwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIHwgX09QX0JVRl9SRVFVRVNUfMKgwqAgcmVzZXJ2ZWTCoMKgwqDCoCB8IDQKPj4+Pj4+ Pj4+ICsgKiArLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0t LS0rLS0tLS0tLS0tLS0tLS0tLSsKPj4+Pj4+Pj4+ICsgKiB8wqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcmVzZXJ2ZWTCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHwgOAo+Pj4+Pj4+ Pj4gKyAqICstLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0t LSstLS0tLS0tLS0tLS0tLS0tKwo+Pj4+Pj4+Pj4gKyAqIHzCoMKgwqAgbnVtX2J1ZnPCoMKgwqAg fMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcmVzZXJ2ZWTCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHwgMTIKPj4+Pj4+Pj4+ICsgKiArLS0t LS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0t LS0tLS0tLSsKPj4+Pj4+Pj4+ICsgKiB8wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcmVzZXJ2ZWTCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHwgMTYKPj4+Pj4+Pj4+ICsgKiArLS0t LS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0t LS0tLS0tLSsKPj4+Pj4+Pj4+ICsgKiB8L1wvXC9cL1wvXC9cL1wvXC9cL1wvXC9cL1wvXC9cL1wv XC9cL1wvXC9cL1wvXC9cL1wvXC9cL1wvXC9cL1wvXC9cL3wKPj4+Pj4+Pj4+ICsgKiArLS0tLS0t LS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0t LS0tLSsKPj4+Pj4+Pj4+ICsgKiB8wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgcmVzZXJ2ZWTCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHwgNjQKPj4+Pj4+Pj4+ICsgKiArLS0tLS0t LS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0t LS0tLSsKPj4+Pj4+Pj4+ICsgKgo+Pj4+Pj4+Pj4gKyAqIG51bV9idWZzIC0gdWludDhfdCwgZGVz aXJlZCBudW1iZXIgb2YgYnVmZmVycyB0byBiZSB1c2VkLiBUaGlzIGlzCj4+Pj4+Pj4+PiArICrC oMKgIGxpbWl0ZWQgdG8gdGhlIHZhbHVlIGNvbmZpZ3VyZWQgaW4gWGVuU3RvcmUubWF4LWJ1ZmZl cnMuCj4+Pj4+Pj4+PiArICrCoMKgIFBhc3NpbmcgemVybyBudW1fYnVmcyBpbiB0aGlzIHJlcXVl c3QgKGFmdGVyIHN0cmVhbWluZyBoYXMgc3RvcHBlZAo+Pj4+Pj4+Pj4gKyAqwqDCoCBhbmQgYWxs IGJ1ZmZlcnMgZGVzdHJveWVkKSB1bmJsb2NrcyBjYW1lcmEgY29uZmlndXJhdGlvbiBjaGFuZ2Vz Lgo+Pj4+Pj4+PiBJIHRoaW5rIHRoZSBwaHJhc2UgJ3VuYmxvY2tzIGNhbWVyYSBjb25maWd1cmF0 aW9uIGNoYW5nZXMnIGlzIGNvbmZ1c2luZy4KPj4+Pj4+Pj4KPj4+Pj4+Pj4gSW4gdjMgdGhpcyBz ZW50ZW5jZSBjYW1lIGFmdGVyIHRoZSB0aGlyZCBub3RlIGJlbG93LCBhbmQgc28gaXQgbWFkZSBz ZW5zZQo+Pj4+Pj4+PiBpbiB0aGF0IGNvbnRleHQsIGJ1dCBub3cgdGhlIG9yZGVyIGhhcyBiZWVu IHJldmVyc2VkIGFuZCBpdCBiZWNhbWUgaGFyZCB0bwo+Pj4+Pj4+PiB1bmRlcnN0YW5kLgo+Pj4+ Pj4+Pgo+Pj4+Pj4+PiBJJ20gbm90IHN1cmUgd2hhdCB0aGUgYmVzdCBhcHByb2FjaCBpcyB0byBm aXggdGhpcy4gT25lIG9wdGlvbiBpcyB0byByZW1vdmUKPj4+Pj4+Pj4gdGhlIHRoaXJkIG5vdGUg YW5kIGludGVncmF0ZSBpdCBzb21laG93IGluIHRoZSBzZW50ZW5jZSBhYm92ZS4gT3IgcGVyaGFw cwo+Pj4+Pj4+PiBkbyBhd2F5IHdpdGggdGhlICdub3RlcycgYXQgYWxsIGFuZCBqdXN0IHdyaXRl IGEgbW9yZSBleHRlbnNpdmUgZG9jdW1lbnRhdGlvbgo+Pj4+Pj4+PiBmb3IgdGhpcyBvcC4gSSBs ZWF2ZSB0aGF0IHVwIHRvIHlvdS4KPj4+Pj4+IEhhbnMsIGhvdyBhYm91dDoKPj4+Pj4+Cj4+Pj4+ PiAgwqDCoMKgKiBudW1fYnVmcyAtIHVpbnQ4X3QsIGRlc2lyZWQgbnVtYmVyIG9mIGJ1ZmZlcnMg dG8gYmUgdXNlZC4KPj4+Pj4+ICDCoMKgwqAqCj4+Pj4+PiAgwqDCoMKgKiBUaGUgbnVtYmVyIG9m IGJ1ZmZlcnMgaW4gdGhpcyByZXF1ZXN0IG11c3Qgbm90IGV4Y2VlZCB0aGUgdmFsdWUgY29uZmln dXJlZAo+Pj4+Pj4gIMKgwqDCoCogaW4gWGVuU3RvcmUubWF4LWJ1ZmZlcnMuIElmIHRoZSBudW1i ZXIgb2YgYnVmZmVycyBpcyBub3QgemVybyB0aGVuIGFmdGVyIHRoaXMKPj4+Pj4+ICDCoMKgwqAq IHJlcXVlc3QgdGhlIGNhbWVyYSBjb25maWd1cmF0aW9uIGNhbm5vdCBiZSBjaGFuZ2VkLiBJbiBv cmRlciB0byBhbGxvdyBjYW1lcmEKPj4+Pj4+ICDCoMKgwqAqIChyZSljb25maWd1cmF0aW9uIHRo aXMgcmVxdWVzdCBtdXN0IGJlIHNlbnQgd2l0aCBudW1fYnVmcyBzZXQgdG8gemVybyBhbmQKPj4+ Pj4+ICDCoMKgwqAqIHRoZSBzdHJlYW1pbmcgbXVzdCBiZSBzdG9wcGVkIGFuZCBidWZmZXJzIGRl c3Ryb3llZC4KPj4+Pj4+ICDCoMKgwqAqIEl0IGlzIGFsbG93ZWQgZm9yIHRoZSBmcm9udGVuZCB0 byBzZW5kIG11bHRpcGxlIFhFTkNBTUVSQV9PUF9CVUZfUkVRVUVTVAo+Pj4+Pj4gIMKgwqDCoCog cmVxdWVzdHMgYmVmb3JlIHNlbmRpbmcgWEVOQ0FNRVJBX09QX1NUUkVBTV9TVEFSVCByZXF1ZXN0 IHRvIHVwZGF0ZSBvcgo+Pj4+Pj4gIMKgwqDCoCogdHVuZSB0aGUgZmluYWwgY29uZmlndXJhdGlv bi4KPj4+Pj4+ICDCoMKgwqAqIEZyb250ZW5kIGlzIHJlc3BvbnNpYmxlIGZvciBjaGVja2luZyB0 aGUgY29ycmVzcG9uZGluZyByZXNwb25zZSBpbiBvcmRlciB0bwo+Pj4+Pj4gIMKgwqDCoCogc2Vl IGlmIHRoZSB2YWx1ZXMgcmVwb3J0ZWQgYmFjayBieSB0aGUgYmFja2VuZCBkbyBtYXRjaCB0aGUg ZGVzaXJlZCBvbmVzCj4+Pj4+PiAgwqDCoMKgKiBhbmQgY2FuIGJlIGFjY2VwdGVkLgo+Pj4+Pj4g IMKgwqDCoCoKPj4+Pj4+ICDCoMKgwqAqIFNlZSByZXNwb25zZSBmb3JtYXQgZm9yIHRoaXMgcmVx dWVzdC4KPj4+Pj4+ICDCoMKgwqAqLwo+Pj4+PiBIbW0sIGl0IHN0aWxsIGlzIGF3a3dhcmQuIFBh cnQgb2YgdGhlIHJlYXNvbiBmb3IgdGhhdCBpcyB0aGF0IFZJRElPQ19SRVFCVUZTCj4+Pj4+IGlz IGp1c3Qgd2VpcmQgaW4gdGhhdCBhIHZhbHVlIG9mIDAgaGFzIGEgc3BlY2lhbCBtZWFuaW5nLgo+ Pj4+Pgo+Pj4+PiBQZXJoYXBzIGl0IHdvdWxkIGJlIG11Y2ggY2xlYW5lciBmb3IgdGhlIFhlbiBp bXBsZW1lbnRhdGlvbiB0byBqdXN0IGFkZCBhIG5ldwo+Pj4+PiBPUDogX09QX0ZSRUVfQUxMX0JV RlMgKG9yIHBlcmhhcHMgX1JFTEVBU0VfQUxMX0JVRlMpIHRoYXQgZWZmZWN0aXZlbHkgZG9lcwo+ Pj4+PiBWSURJT0NfUkVRQlVGUyB3aXRoIGEgMCBjb3VudCB2YWx1ZS4gQW5kIHRoaXMgT1BfQlVG X1JFUVVFU1QgKHdvdWxkbid0Cj4+Pj4+IE9QX1JFUVVFU1RfQlVGUyBiZSBhIGJldHRlciBuYW1l PykKPj4+PiBJIGhhdmUgYWxsIG9wZXJhdGlvbiBjYXRlZ29yaXplZCwgZS5nLiB0aGVyZSBhcmUg Y29tbWFuZHMKPj4+PiBmb3IgY29uZmlndXJhdGlvbiAoWEVOQ0FNRVJBX09QX0NPTkZJR19YWFgp LAo+Pj4+IGJ1ZmZlciBoYW5kbGluZyAoWEVOQ0FNRVJBX09QX0JVRl9YWFgpIGV0Yy4sIHNvIEkg cHJlZmVyIHRvCj4+Pj4ga2VlcCB0aGUgbmFtZSBhcyBpcy4KPj4+Pj4gIMKgwqAgd291bGQgdGhl biBkbyBub3RoaW5nIG9yIHJldHVybiBhbiBlcnJvcgo+Pj4+PiBpZiBudW1fYnVmcyA9PSAwLgo+ Pj4+Pgo+Pj4+PiBJZiB5b3UgZG9uJ3Qgd2FudCB0byBjcmVhdGUgYSBuZXcgWGVuIG9wLCB0aGVu IEkgd291bGQgY2hhbmdlIHRoZSB0ZXh0IHNvbWUKPj4+Pj4gbW9yZSBzaW5jZSB5b3UgZG8gbm90 IGFjdHVhbGx5IGV4cGxhaW4gd2hhdCB0aGUgb3AgZG9lcyBpZiBudW1fYnVmcyBpcyAwLgo+Pj4+ IFdlbGwsIEkgdGVuZCB0byBrZWVwIHRoaXMgYXMgaXMgd2l0aCBubyBhZGRpdGlvbmFsIG9wLgo+ Pj4+PiBJIHdvdWxkIHdyaXRlIHNvbWV0aGluZyBsaWtlIHRoaXM6Cj4+Pj4+Cj4+Pj4+IElmIG51 bV9idWZzIGlzIGdyZWF0ZXIgdGhhbiAwLCB0aGVuIDxkZXNjcmliZSB3aGF0IGhhcHBlbnM+Lgo+ Pj4+Pgo+Pj4+PiBJZiBudW1fYnVmcyBpcyBlcXVhbCB0byAwLCB0aGVuIDxkZXNjcmliZSB3aGF0 IGhhcHBlbnM+Lgo+Pj4+Pgo+Pj4+PiBJZiBudW1fYnVmcyBpcyBub3QgemVybyB0aGVuIGFmdGVy IHRoaXMgcmVxdWVzdCB0aGUgY2FtZXJhIGNvbmZpZ3VyYXRpb24KPj4+Pj4gY2Fubm90IGJlIGNo YW5nZWQuIEluIG9yZGVyIHRvIGFsbG93IGNhbWVyYSAocmUpY29uZmlndXJhdGlvbiB0aGlzIHJl cXVlc3QKPj4+Pj4gbXVzdCBiZSBzZW50IHdpdGggbnVtX2J1ZnMgc2V0IHRvIHplcm8gYW5kIHRo ZSBzdHJlYW1pbmcgbXVzdCBiZSBzdG9wcGVkCj4+Pj4+IGFuZCBidWZmZXJzIGRlc3Ryb3llZC4K Pj4+PiBOZXh0IHRyeToKPj4+Pgo+Pj4+ICDCoMKgKiBudW1fYnVmcyAtIHVpbnQ4X3QsIGRlc2ly ZWQgbnVtYmVyIG9mIGJ1ZmZlcnMgdG8gYmUgdXNlZC4KPj4+PiAgwqDCoCoKPj4+PiAgwqDCoCog SWYgbnVtX2J1ZnMgaXMgbm90IHplcm8gdGhlbiB0aGUgYmFja2VuZCB2YWxpZGF0ZXMgdGhlIHJl cXVlc3RlZCBudW1iZXIgb2YKPj4+PiAgwqDCoCogYnVmZmVycyBhbmQgcmVzcG9uZHMgd2l0aCB0 aGUgbnVtYmVyIG9mIGJ1ZmZlcnMgYWxsb3dlZCBmb3IgdGhpcyBmcm9udGVuZC4KPj4+PiAgwqDC oCogRnJvbnRlbmQgaXMgcmVzcG9uc2libGUgZm9yIGNoZWNraW5nIHRoZSBjb3JyZXNwb25kaW5n IHJlc3BvbnNlIGluIG9yZGVyIHRvCj4+Pj4gIMKgwqAqIHNlZSBpZiB0aGUgdmFsdWVzIHJlcG9y dGVkIGJhY2sgYnkgdGhlIGJhY2tlbmQgZG8gbWF0Y2ggdGhlIGRlc2lyZWQgb25lcwo+Pj4+ICDC oMKgKiBhbmQgY2FuIGJlIGFjY2VwdGVkLgo+Pj4+ICDCoMKgKiBGcm9udGVuZCBpcyBhbGxvd2Vk IHRvIHNlbmQgbXVsdGlwbGUgWEVOQ0FNRVJBX09QX0JVRl9SRVFVRVNUIHJlcXVlc3RzCj4+Pj4g IMKgwqAqIGJlZm9yZSBzZW5kaW5nIFhFTkNBTUVSQV9PUF9TVFJFQU1fU1RBUlQgcmVxdWVzdCB0 byB1cGRhdGUgb3IgdHVuZSB0aGUKPj4+PiAgwqDCoCogZmluYWwgY29uZmlndXJhdGlvbi4KPj4+ PiAgwqDCoCogRnJvbnRlbmQgaXMgbm90IGFsbG93ZWQgdG8gY2hhbmdlIHRoZSBudW1iZXIgb2Yg YnVmZmVycyBhbmQvb3IgY2FtZXJhCj4+Pj4gIMKgwqAqIGNvbmZpZ3VyYXRpb24gYWZ0ZXIgdGhl IHN0cmVhbWluZyBoYXMgc3RhcnRlZC4KPj4+IFRoaXMgYWxsIGxvb2tzIGdvb2QuCj4+IEdyZWF0 Cj4+Pj4gIMKgwqAqCj4+Pj4gIMKgwqAqIEluIG9yZGVyIHRvIGFsbG93IGNhbWVyYSAocmUpY29u ZmlndXJhdGlvbiB0aGlzIHJlcXVlc3QgbXVzdCBiZSBzZW50IHdpdGgKPj4+PiAgwqDCoCogbnVt X2J1ZnMgc2V0IHRvIHplcm8gYW5kIHRoZSBzdHJlYW1pbmcgbXVzdCBiZSBzdG9wcGVkIGFuZCBi dWZmZXJzIGRlc3Ryb3llZC4KPj4+IFlvdSBqdXN0IHNheSB0aGF0IGlmIHlvdSB3YW50IHRvIHJl Y29uZmlndXJlIChhbmQgdGhpcyBvbmx5IGFwcGxpZXMgdG8gcmVjb25maWd1cmUsCj4+PiBub3Qg dG8gdGhlIGluaXRpYWwgY29uZmlndXJlIHN0ZXAgc2luY2UgdGhlbiB0aGVyZSBhcmUgbm8gYnVm ZmVycyBhbGxvY2F0ZWQgeWV0KSwKPj4+IHRoZW4geW91IG5lZWQgdG8gY2FsbCB0aGlzIHdpdGgg bnVtX2J1ZnMgPT0gMC4gQnV0IHlvdSBkb24ndCBleHBsYWluIHdoYXQgdGhpcyBvcAo+Pj4gZG9l cyBpZiBudW1fYnVmcyA9PSAwIQo+Pj4KPj4+IFNvIGJlZm9yZSB0aGlzIHNlbnRlbmNlIHlvdSBu ZWVkIHRvIGFkZCBhIGRlc2NyaXB0aW9uIG9mIHdoYXQgdGhpcyBvcCBkb2VzIGlmIG51bV9idWZz Cj4+PiBpcyAwLCBhbmQgY2hhbmdlICcocmUpY29uZmlndXJhdGlvbicgdG8gJ3JlY29uZmlndXJh dGlvbicuCj4+IFdlbGwsIGl0IGlzIGEgZ29vZCBxdWVzdGlvbi4gSSBhbHJlYWR5IGRlc2NyaWJl IHdoYXQgaGFwcGVucyBpZgo+PiBzdHJlYW1pbmcgaGFzIHN0b3BwZWQgYW5kIGJ1ZmZlcnMgZGVz dHJveWVkIGFuZCBudW1fYnVmcyA9PSAwOgo+PiB0aGlzIGlzIGEgcmVjb25maWd1cmF0aW9uLgo+ Pgo+PiBJIGFsc28gaGF2ZSBhIG5vdGUgdGhhdCAiRnJvbnRlbmQgaXMgbm90IGFsbG93ZWQgdG8g Y2hhbmdlIHRoZQo+PiBudW1iZXIgb2YgYnVmZmVycyBhbmQvb3IgY2FtZXJhIGNvbmZpZ3VyYXRp b24gYWZ0ZXIgdGhlIHN0cmVhbWluZwo+PiBoYXMgc3RhcnRlZC4iOiB0aGlzIGlzIHRoZSBjYXNl IHRoYXQgd2UgY2Fubm90IGNoYW5nZSB0aGUgbnVtYmVyIG9mCj4+IGJ1ZmZlcnMgZHVyaW5nIHRo ZSBzdHJlYW1pbmcsIGUuZy4gb25lIGNhbm5vdCBzZW5kIG51bV9idWZzID09IDAKPj4gYXQgdGhp cyB0aW1lLgo+Pgo+PiBTbywgd2hhdCBpcyBub3QgY292ZXJlZCBpcyB0aGF0IHRoZSBzdHJlYW1p bmcgaGFzIG5ldmVyIHN0YXJ0ZWQsCj4+IG51bV9idWZzIGhhcyBvciBoYXMgbm90IGJlZW4gc2V0 IHRvIHNvbWUgdmFsdWUgYW5kIG5vdyBmcm9udGVuZAo+PiByZXF1ZXN0cyBudW1fYnVmcyA9PSAw Pwo+PiBJdCBzZWVtcyB0aGF0IHdlIGNhbiBzdGF0ZSB0aGF0IGluIHRoaXMgY2FzZSBiYWNrZW5k IGRvZXMKPj4gbm90aGluZyBvciBpdCBtYXkgZnJlZSBhbnkgYnVmZmVycyBpZiBpdCBoYXMgYWxs b2NhdGVkIGFueSwgc28gdGhlCj4+IHRhaWwgcmVhZHMgYXM6Cj4+Cj4+ICDCoCogSWYgbnVtX2J1 ZnMgaXMgMCBhbmQgc3RyZWFtaW5nIGhhcyBub3Qgc3RhcnRlZCB5ZXQsIHRoZW4gdGhlIGJhY2tl bmQgbWF5Cj4+ICDCoCogZnJlZSBhbGwgcHJldmlvdXNseSBhbGxvY2F0ZWQgYnVmZmVycyAoaWYg YW55KSBvciBkbyBub3RoaW5nLgo+IE11Y2ggYmV0dGVyLiBOb3cgeW91IGFjdHVhbGx5IGV4cGxh aW4gd2hhdCB0aGlzIG9wIGRvZXMgaWYgbnVtX2J1ZnMgPT0gMC4KPgo+PiAgwqAqCj4+ICDCoCog SWYgY2FtZXJhIHJlY29uZmlndXJhdGlvbiBpcyByZXF1aXJlZCB0aGVuIHRoaXMgcmVxdWVzdCBt dXN0IGJlIHNlbnQgd2l0aAo+PiAgwqAqIG51bV9idWZzIHNldCB0byB6ZXJvIGFuZCBzdHJlYW1p bmcgbXVzdCBiZSBzdG9wcGVkIGFuZCBidWZmZXJzIGRlc3Ryb3llZC4KPiBTaG91bGRuJ3QgdGhl IG9yZGVyIGJlIHRvIGZpcnN0IHN0b3Agc3RyZWFtaW5nLCB0aGVuIGNhbGwgdGhpcyByZXF1ZXN0 IHdpdGgKPiBudW1fYnVmcyBzZXQgdG8gMCBhbmQgZmluYWxseSBkZXN0cm95IHRoZSBidWZmZXJz PwpZZXMsIEkgbWVhbnQgdGhhdCwgYnV0IHRoaXMgZG9lcyBuZWVkIHRvIGJlIG1vcmUgY2xlYXI6 CiDCoCogSWYgY2FtZXJhIHJlY29uZmlndXJhdGlvbiBpcyByZXF1aXJlZCB0aGVuIHRoZSBzdHJl YW1pbmcgbXVzdCBiZSBzdG9wcGVkCiDCoCogYW5kIHRoaXMgcmVxdWVzdCBtdXN0IGJlIHNlbnQg d2l0aCBudW1fYnVmcyBzZXQgdG8gemVybyBhbmQgZmluYWxseQogwqAqIGJ1ZmZlcnMgZGVzdHJv eWVkLgoKPgo+IFRyeWluZyB0byBjYWxsIHRoaXMgaWYgc3RyZWFtaW5nIGlzIGluIHByb2dyZXNz IHdpbGwgcmVzdWx0IGluIGFuIGVycm9yLgo+IEkgdGhpbmsgdGhhdCBzaG91bGQgYmUgZG9jdW1l bnRlZCBhcyB3ZWxsLgpTdXJlCj4KPiBTb3JyeSBmb3IgcGF5aW5nIHNvIG11Y2ggYXR0ZW50aW9u IHRvIHRoaXMsIGJ1dCBJIHRoaW5rIGl0IGlzIGltcG9ydGFudCB0aGF0Cj4gdGhpcyBpcyBkb2N1 bWVudGVkIHByZWNpc2VseS4KVGhhbmsgeW91IGZvciBoZWxwaW5nIHdpdGggdGhpcyAtIHlvdXIg Y29tbWVudHMgYXJlIHJlYWxseQppbXBvcnRhbnQgYW5kIG1ha2UgdGhlIGRlc2NyaXB0aW9uIHBy ZWNpc2UuIE9rLCBzbyBmaW5hbGx5OgoKIMKgKiBudW1fYnVmcyAtIHVpbnQ4X3QsIGRlc2lyZWQg bnVtYmVyIG9mIGJ1ZmZlcnMgdG8gYmUgdXNlZC4KIMKgKgogwqAqIElmIG51bV9idWZzIGlzIG5v dCB6ZXJvIHRoZW4gdGhlIGJhY2tlbmQgdmFsaWRhdGVzIHRoZSByZXF1ZXN0ZWQgCm51bWJlciBv ZgogwqAqIGJ1ZmZlcnMgYW5kIHJlc3BvbmRzIHdpdGggdGhlIG51bWJlciBvZiBidWZmZXJzIGFs bG93ZWQgZm9yIHRoaXMgCmZyb250ZW5kLgogwqAqIEZyb250ZW5kIGlzIHJlc3BvbnNpYmxlIGZv ciBjaGVja2luZyB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZSBpbiAKb3JkZXIgdG8KIMKgKiBz ZWUgaWYgdGhlIHZhbHVlcyByZXBvcnRlZCBiYWNrIGJ5IHRoZSBiYWNrZW5kIGRvIG1hdGNoIHRo ZSBkZXNpcmVkIG9uZXMKIMKgKiBhbmQgY2FuIGJlIGFjY2VwdGVkLgogwqAqIEZyb250ZW5kIGlz IGFsbG93ZWQgdG8gc2VuZCBtdWx0aXBsZSBYRU5DQU1FUkFfT1BfQlVGX1JFUVVFU1QgcmVxdWVz dHMKIMKgKiBiZWZvcmUgc2VuZGluZyBYRU5DQU1FUkFfT1BfU1RSRUFNX1NUQVJUIHJlcXVlc3Qg dG8gdXBkYXRlIG9yIHR1bmUgdGhlCiDCoCogZmluYWwgY29uZmlndXJhdGlvbi4KIMKgKiBGcm9u dGVuZCBpcyBub3QgYWxsb3dlZCB0byBjaGFuZ2UgdGhlIG51bWJlciBvZiBidWZmZXJzIGFuZC9v ciBjYW1lcmEKIMKgKiBjb25maWd1cmF0aW9uIGFmdGVyIHRoZSBzdHJlYW1pbmcgaGFzIHN0YXJ0 ZWQuCiDCoCoKIMKgKiBJZiBudW1fYnVmcyBpcyAwIGFuZCBzdHJlYW1pbmcgaGFzIG5vdCBzdGFy dGVkIHlldCwgdGhlbiB0aGUgYmFja2VuZCBtYXkKIMKgKiBmcmVlIGFsbCBwcmV2aW91c2x5IGFs bG9jYXRlZCBidWZmZXJzIChpZiBhbnkpIG9yIGRvIG5vdGhpbmcuCiDCoCogVHJ5aW5nIHRvIGNh bGwgdGhpcyBpZiBzdHJlYW1pbmcgaXMgaW4gcHJvZ3Jlc3Mgd2lsbCByZXN1bHQgaW4gYW4gZXJy b3IuCiDCoCoKIMKgKiBJZiBjYW1lcmEgcmVjb25maWd1cmF0aW9uIGlzIHJlcXVpcmVkIHRoZW4g dGhlIHN0cmVhbWluZyBtdXN0IGJlIHN0b3BwZWQKIMKgKiBhbmQgdGhpcyByZXF1ZXN0IG11c3Qg YmUgc2VudCB3aXRoIG51bV9idWZzIHNldCB0byB6ZXJvIGFuZCBmaW5hbGx5CiDCoCogYnVmZmVy cyBkZXN0cm95ZWQuCiDCoCoKIMKgKiBQbGVhc2Ugbm90ZSwgdGhhdCB0aGUgbnVtYmVyIG9mIGJ1 ZmZlcnMgaW4gdGhpcyByZXF1ZXN0IG11c3Qgbm90IGV4Y2VlZAogwqAqIHRoZSB2YWx1ZSBjb25m aWd1cmVkIGluIFhlblN0b3JlLm1heC1idWZmZXJzLgogwqAqCiDCoCogU2VlIHJlc3BvbnNlIGZv cm1hdCBmb3IgdGhpcyByZXF1ZXN0LgoKPiBSZWdhcmRzLAo+Cj4gCUhhbnMKVGhhbmsgeW91LApP bGVrc2FuZHIKPj4gIMKgKgo+PiAgwqAqIFBsZWFzZSBub3RlLCB0aGF0IHRoZSBudW1iZXIgb2Yg YnVmZmVycyBpbiB0aGlzIHJlcXVlc3QgbXVzdCBub3QgZXhjZWVkCj4+ICDCoCogdGhlIHZhbHVl IGNvbmZpZ3VyZWQgaW4gWGVuU3RvcmUubWF4LWJ1ZmZlcnMuCj4+ICDCoCoKPj4gIMKgKiBTZWUg cmVzcG9uc2UgZm9ybWF0IGZvciB0aGlzIHJlcXVlc3QuCj4+Cj4+PiBSZWdhcmRzLAo+Pj4KPj4+ ICDCoMKgwqDCoEhhbnMKPj4+Cj4+Pj4gIMKgwqAqCj4+Pj4gIMKgwqAqIFBsZWFzZSBub3RlLCB0 aGF0IHRoZSBudW1iZXIgb2YgYnVmZmVycyBpbiB0aGlzIHJlcXVlc3QgbXVzdCBub3QgZXhjZWVk Cj4+Pj4gIMKgwqAqIHRoZSB2YWx1ZSBjb25maWd1cmVkIGluIFhlblN0b3JlLm1heC1idWZmZXJz Lgo+Pj4+ICDCoMKgKgo+Pj4+ICDCoMKgKiBTZWUgcmVzcG9uc2UgZm9ybWF0IGZvciB0aGlzIHJl cXVlc3QuCj4+Pj4KPj4+Pj4gUmVnYXJkcywKPj4+Pj4KPj4+Pj4gIMKgwqDCoMKgwqBIYW5zCj4+ Pj4+Cj4+Pj4+Pj4+PiArICoKPj4+Pj4+Pj4+ICsgKiBTZWUgcmVzcG9uc2UgZm9ybWF0IGZvciB0 aGlzIHJlcXVlc3QuCj4+Pj4+Pj4+PiArICoKPj4+Pj4+Pj4+ICsgKiBOb3RlczoKPj4+Pj4+Pj4+ ICsgKsKgIC0gZnJvbnRlbmQgbXVzdCBjaGVjayB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZSBp biBvcmRlciB0byBzZWUKPj4+Pj4+Pj4+ICsgKsKgwqDCoCBpZiB0aGUgdmFsdWVzIHJlcG9ydGVk IGJhY2sgYnkgdGhlIGJhY2tlbmQgZG8gbWF0Y2ggdGhlIGRlc2lyZWQgb25lcwo+Pj4+Pj4+Pj4g KyAqwqDCoMKgIGFuZCBjYW4gYmUgYWNjZXB0ZWQuCj4+Pj4+Pj4+PiArICrCoCAtIGZyb250ZW5k IG1heSBzZW5kIG11bHRpcGxlIFhFTkNBTUVSQV9PUF9CVUZfUkVRVUVTVCByZXF1ZXN0cyBiZWZv cmUKPj4+Pj4+Pj4+ICsgKsKgwqDCoCBzZW5kaW5nIFhFTkNBTUVSQV9PUF9TVFJFQU1fU1RBUlQg cmVxdWVzdCB0byB1cGRhdGUgb3IgdHVuZSB0aGUKPj4+Pj4+Pj4+ICsgKsKgwqDCoCBjb25maWd1 cmF0aW9uLgo+Pj4+Pj4+Pj4gKyAqwqAgLSBhZnRlciB0aGlzIHJlcXVlc3QgY2FtZXJhIGNvbmZp Z3VyYXRpb24gY2Fubm90IGJlIGNoYW5nZWQsIHVubGVzcwo+Pj4+Pj4+PiBjYW1lcmEgY29uZmln dXJhdGlvbiAtPiB0aGUgY2FtZXJhIGNvbmZpZ3VyYXRpb24KPj4+Pj4+Pj4KPj4+Pj4+Pj4+ICsg KsKgwqDCoCBzdHJlYW1pbmcgaXMgc3RvcHBlZCBhbmQgYnVmZmVycyBkZXN0cm95ZWQKPj4+Pj4+ Pj4+ICsgKi8KPj4+Pj4+Pj4gUmVnYXJkcywKPj4+Pj4+Pj4KPj4+Pj4+Pj4gIMKgwqDCoMKgwqDC oEhhbnMKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpY ZW4tZGV2ZWwgbWFpbGluZyBsaXN0Clhlbi1kZXZlbEBsaXN0cy54ZW5wcm9qZWN0Lm9yZwpodHRw czovL2xpc3RzLnhlbnByb2plY3Qub3JnL21haWxtYW4vbGlzdGluZm8veGVuLWRldmVs