From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from sender4-op-o11.zoho.com (sender4-op-o11.zoho.com [136.143.188.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7AE104949ED; Mon, 31 Aug 2026 13:38:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.11 ARC-Seal:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788183529; cv=pass; b=oFv6iSnnXJoF3195MUGgqzOdS0pNVA6jpxBdLYmFYmiXByWtE/ldtYliyyU3SPUat+rCPTfLmEG4svac0ABmZu7PR2KC1EeRnBzJR2p2ruMvAFEvB/rhSeSuVv3sSp6B/twI1cnG48nperEgHbiR376nDosqBgwuC4DsegvduFw= ARC-Message-Signature:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788183529; c=relaxed/simple; bh=KVqHzJZmVYUEThyE61NoC//YMjx+hO2G1ZcSMuXk8R4=; h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: In-Reply-To:Content-Type; b=oY1SRl7RGhalq6M731d4KI6WSJnvCfDDhzVoQDoVeZ3jreYCn/d1SZQv+HMCOS7flPkXx+u2bWZ6KgYu6BQOaLUPcwM+K17T0/7+B/bqqeJmwR7kGI54fx6Xe5f9WX6Z0yINxE3XUPZn8gRIPEYJUugiuLuVBUr14hN86LAGnoI= ARC-Authentication-Results:i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=benjamin.gaignard@collabora.com header.b=BteJHwZl; arc=pass smtp.client-ip=136.143.188.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=benjamin.gaignard@collabora.com header.b="BteJHwZl" ARC-Seal: i=1; a=rsa-sha256; t=1788183489; cv=none; d=zohomail.com; s=zohoarc; b=DgPQUzBqluTpdRfkXsbxDkjE98EhJakSW24tVlr/j6QcFklt/wgmkxPJQ5yi+39opgMrUbOzlbnQyl2UMBvoz1K0tGX8uZi6u2uOCZbWi3W6oO8TVtmM9EjmVv1MJfZRY5kvacsUs4/BRnwUUgpiNyOcrVuOoW4QXmHENW1Og40= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788183489; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:Subject:Subject:To:To:Message-Id:Reply-To; bh=zdEqHU01IjF92t+B1+W0pEI1Sf51+S0bk3C3C5oJ47w=; b=Iy4EdWY+TrJJl2TyLmq2wnNNSvZCT+gIseLbKyl3ivPfHaw8QI8Diy9n41mwRUAwYUGUBUk6qIRRkU6pAI2FDjUmFPyxWJY5veL6yU2uY77DPis0DkXEo4cBxG5zxl1OHPf0SfcVxwEiaQ9DGieYPxKHaaeLY8f2Xv36dzfV6b0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=benjamin.gaignard@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1788183489; s=zohomail; d=collabora.com; i=benjamin.gaignard@collabora.com; h=Message-ID:Date:Date:MIME-Version:Subject:Subject:From:From:To:To:Cc:Cc:In-Reply-To:Content-Type:Content-Transfer-Encoding:Message-Id:Reply-To; bh=zdEqHU01IjF92t+B1+W0pEI1Sf51+S0bk3C3C5oJ47w=; b=BteJHwZlsgZJ8RcgueK380Af5N8zubcpfqtfZhAqybs4zxdKIn4NYZhmd2dqyVww 2UcoAcsQ36Hbu4khHk4nVl99D9k+JKtoMhrz5Py4qoEpl6BCS83+Tiz2ks5LL2V53rn WMS2daAXognNfi3djKVSxVRWxpBMp4C3EyXe7NbQ= Received: by mx.zohomail.com with SMTPS id 1788183487750755.1901236467753; Mon, 31 Aug 2026 06:38:07 -0700 (PDT) Message-ID: <25e17f59-e637-48a2-8a9b-4913738b7c4e@collabora.com> Date: Mon, 31 Aug 2026 15:38:03 +0200 Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v5] media: verisilicon: Create AV1 helper library From: Benjamin Gaignard To: nicolas.dufresne@collabora.com, p.zabel@pengutronix.de, mchehab@kernel.org, heiko@sntech.de Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, kernel@collabora.com References: <20260512075949.87441-1-benjamin.gaignard@collabora.com> <6eb8768e-e46c-47f4-966d-bfc05c8a6fe4@collabora.com> Content-Language: en-US In-Reply-To: <6eb8768e-e46c-47f4-966d-bfc05c8a6fe4@collabora.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Le 10/07/2026 à 11:45, Benjamin Gaignard a écrit : > Gentle ping on this one. > > Regards, > Benjamin > > Le 12/05/2026 à 09:59, Benjamin Gaignard a écrit : >> Regroup all none hardware related AV1 functions into a helper library. >> The goal is to avoid code duplication for future AV1 codecs. >> >> Tested on rock 5b board Fluster score remains the same 204/241. >> >> Signed-off-by: Benjamin Gaignard >> Reviewed-by: Nicolas Dufresne Hi Hans, Maybe something is missing or blocking this patch but I don't know what. I would like to progress on it because I plan to do other improvements for Verisilicon drivers and they depend of this one. If there any I can do to unlock this situation please tell me. Thanks for your time. Regards, Benjamin >> --- >> version 5: >> - be more strict about checking arrays range and the value returned >>    by hantro_av1_get_frame_index() >> - rebased on v7.1-rc3 tag >> >> version 4: >> - change functions prototypes to use a structure. >> - rebased on v7.1-rc2 tag. >> >>   drivers/media/platform/verisilicon/Makefile   |    7 +- >>   .../media/platform/verisilicon/hantro_av1.c   |  790 +++++++++++++ >>   .../media/platform/verisilicon/hantro_av1.h   |   64 ++ >>   ...entropymode.c => hantro_av1_entropymode.c} |   18 +- >>   ...entropymode.h => hantro_av1_entropymode.h} |   18 +- >>   ...av1_filmgrain.c => hantro_av1_filmgrain.c} |  125 +- >>   .../verisilicon/hantro_av1_filmgrain.h        |   48 + >>   .../media/platform/verisilicon/hantro_hw.h    |    7 +- >>   .../verisilicon/rockchip_av1_filmgrain.h      |   36 - >>   .../verisilicon/rockchip_vpu981_hw_av1_dec.c  | 1014 ++--------------- >>   .../platform/verisilicon/rockchip_vpu_hw.c    |    7 +- >>   11 files changed, 1115 insertions(+), 1019 deletions(-) >>   create mode 100644 drivers/media/platform/verisilicon/hantro_av1.c >>   create mode 100644 drivers/media/platform/verisilicon/hantro_av1.h >>   rename >> drivers/media/platform/verisilicon/{rockchip_av1_entropymode.c => >> hantro_av1_entropymode.c} (99%) >>   rename >> drivers/media/platform/verisilicon/{rockchip_av1_entropymode.h => >> hantro_av1_entropymode.h} (95%) >>   rename drivers/media/platform/verisilicon/{rockchip_av1_filmgrain.c >> => hantro_av1_filmgrain.c} (85%) >>   create mode 100644 >> drivers/media/platform/verisilicon/hantro_av1_filmgrain.h >>   delete mode 100644 >> drivers/media/platform/verisilicon/rockchip_av1_filmgrain.h >> >> diff --git a/drivers/media/platform/verisilicon/Makefile >> b/drivers/media/platform/verisilicon/Makefile >> index f6f019d04ff0..a1dd6c2d29be 100644 >> --- a/drivers/media/platform/verisilicon/Makefile >> +++ b/drivers/media/platform/verisilicon/Makefile >> @@ -19,7 +19,10 @@ hantro-vpu-y += \ >>           hantro_hevc.o \ >>           hantro_mpeg2.o \ >>           hantro_vp8.o \ >> -        hantro_vp9.o >> +        hantro_vp9.o \ >> +        hantro_av1.o \ >> +        hantro_av1_filmgrain.o \ >> +        hantro_av1_entropymode.o >>     hantro-vpu-$(CONFIG_VIDEO_HANTRO_IMX8M) += \ >>           imx8m_vpu_hw.o >> @@ -33,8 +36,6 @@ hantro-vpu-$(CONFIG_VIDEO_HANTRO_ROCKCHIP) += \ >>           rockchip_vpu2_hw_mpeg2_dec.o \ >>           rockchip_vpu2_hw_vp8_dec.o \ >>           rockchip_vpu981_hw_av1_dec.o \ >> -        rockchip_av1_filmgrain.o \ >> -        rockchip_av1_entropymode.o \ >>           rockchip_vpu_hw.o >>     hantro-vpu-$(CONFIG_VIDEO_HANTRO_SUNXI) += \ >> diff --git a/drivers/media/platform/verisilicon/hantro_av1.c >> b/drivers/media/platform/verisilicon/hantro_av1.c >> new file mode 100644 >> index 000000000000..ac7ae8e87f50 >> --- /dev/null >> +++ b/drivers/media/platform/verisilicon/hantro_av1.c >> @@ -0,0 +1,790 @@ >> +// SPDX-License-Identifier: GPL-2.0-only >> +/* >> + * Copyright (c) 2026, Collabora >> + * >> + * Author: Benjamin Gaignard >> + */ >> + >> +#include >> +#include >> +#include >> + >> +#include "hantro.h" >> +#include "hantro_av1.h" >> +#include "hantro_hw.h" >> + >> +#define GM_GLOBAL_MODELS_PER_FRAME    7 >> +#define GLOBAL_MODEL_TOTAL_SIZE    (6 * 4 + 4 * 2) >> +#define GLOBAL_MODEL_SIZE    ALIGN(GM_GLOBAL_MODELS_PER_FRAME * >> GLOBAL_MODEL_TOTAL_SIZE, 2048) >> +#define AV1_MAX_TILES        128 >> +#define AV1_TILE_INFO_SIZE    (AV1_MAX_TILES * 16) >> +#define AV1_TILE_SIZE        ALIGN(32 * 128, 4096) >> + >> +#define SUPERRES_SCALE_BITS 3 >> + >> +#define DIV_LUT_PREC_BITS 14 >> +#define DIV_LUT_BITS 8 >> +#define DIV_LUT_NUM BIT(DIV_LUT_BITS) >> +#define WARP_PARAM_REDUCE_BITS 6 >> +#define WARPEDMODEL_PREC_BITS 16 >> + >> +#define AV1_DIV_ROUND_UP_POW2(value, n)            \ >> +({                            \ >> +    typeof(n) _n  = n;                \ >> +    typeof(value) _value = value;            \ >> +    (_value + (BIT(_n) >> 1)) >> _n;        \ >> +}) >> + >> +#define AV1_DIV_ROUND_UP_POW2_SIGNED(value, n)                \ >> +({                                    \ >> +    typeof(n) _n_  = n;                        \ >> +    typeof(value) _value_ = value;                    \ >> +    (((_value_) < 0) ? -AV1_DIV_ROUND_UP_POW2(-(_value_), (_n_))    \ >> +        : AV1_DIV_ROUND_UP_POW2((_value_), (_n_)));        \ >> +}) >> + >> +static const short div_lut[DIV_LUT_NUM + 1] = { >> +    16384, 16320, 16257, 16194, 16132, 16070, 16009, 15948, 15888, >> 15828, 15768, >> +    15709, 15650, 15592, 15534, 15477, 15420, 15364, 15308, 15252, >> 15197, 15142, >> +    15087, 15033, 14980, 14926, 14873, 14821, 14769, 14717, 14665, >> 14614, 14564, >> +    14513, 14463, 14413, 14364, 14315, 14266, 14218, 14170, 14122, >> 14075, 14028, >> +    13981, 13935, 13888, 13843, 13797, 13752, 13707, 13662, 13618, >> 13574, 13530, >> +    13487, 13443, 13400, 13358, 13315, 13273, 13231, 13190, 13148, >> 13107, 13066, >> +    13026, 12985, 12945, 12906, 12866, 12827, 12788, 12749, 12710, >> 12672, 12633, >> +    12596, 12558, 12520, 12483, 12446, 12409, 12373, 12336, 12300, >> 12264, 12228, >> +    12193, 12157, 12122, 12087, 12053, 12018, 11984, 11950, 11916, >> 11882, 11848, >> +    11815, 11782, 11749, 11716, 11683, 11651, 11619, 11586, 11555, >> 11523, 11491, >> +    11460, 11429, 11398, 11367, 11336, 11305, 11275, 11245, 11215, >> 11185, 11155, >> +    11125, 11096, 11067, 11038, 11009, 10980, 10951, 10923, 10894, >> 10866, 10838, >> +    10810, 10782, 10755, 10727, 10700, 10673, 10645, 10618, 10592, >> 10565, 10538, >> +    10512, 10486, 10460, 10434, 10408, 10382, 10356, 10331, 10305, >> 10280, 10255, >> +    10230, 10205, 10180, 10156, 10131, 10107, 10082, 10058, 10034, >> 10010, 9986, >> +    9963,  9939,  9916,  9892,  9869,  9846,  9823,  9800, 9777,  >> 9754,  9732, >> +    9709,  9687,  9664,  9642,  9620,  9598,  9576,  9554, 9533,  >> 9511,  9489, >> +    9468,  9447,  9425,  9404,  9383,  9362,  9341,  9321, 9300,  >> 9279,  9259, >> +    9239,  9218,  9198,  9178,  9158,  9138,  9118,  9098, 9079,  >> 9059,  9039, >> +    9020,  9001,  8981,  8962,  8943,  8924,  8905,  8886, 8867,  >> 8849,  8830, >> +    8812,  8793,  8775,  8756,  8738,  8720,  8702,  8684, 8666,  >> 8648,  8630, >> +    8613,  8595,  8577,  8560,  8542,  8525,  8508,  8490, 8473,  >> 8456,  8439, >> +    8422,  8405,  8389,  8372,  8355,  8339,  8322,  8306, 8289,  >> 8273,  8257, >> +    8240,  8224,  8208,  8192, >> +}; >> + >> +enum hantro_av1_tx_mode { >> +    HANTRO_AV1_TX_MODE_ONLY_4X4    = 0, >> +    HANTRO_AV1_TX_MODE_8X8        = 1, >> +    HANTRO_AV1_TX_MODE_16x16    = 2, >> +    HANTRO_AV1_TX_MODE_32x32    = 3, >> +    HANTRO_AV1_TX_MODE_SELECT    = 4, >> +}; >> + >> +enum hantro_av1_inter_prediction_filter_type { >> +    HANTRO_AV1_EIGHT_TAP_SMOOTH    = 0, >> +    HANTRO_AV1_EIGHT_TAP        = 1, >> +    HANTRO_AV1_EIGHT_TAP_SHARP    = 2, >> +    HANTRO_AV1_BILINEAR        = 3, >> +    HANTRO_AV1_SWITCHABLE        = 4, >> +}; >> + >> +int hantro_av1_get_hardware_tx_mode(enum v4l2_av1_tx_mode tx_mode) >> +{ >> +    switch (tx_mode) { >> +    case V4L2_AV1_TX_MODE_ONLY_4X4: >> +        return HANTRO_AV1_TX_MODE_ONLY_4X4; >> +    case V4L2_AV1_TX_MODE_LARGEST: >> +        return HANTRO_AV1_TX_MODE_32x32; >> +    case V4L2_AV1_TX_MODE_SELECT: >> +        return HANTRO_AV1_TX_MODE_SELECT; >> +    } >> + >> +    return HANTRO_AV1_TX_MODE_32x32; >> +} >> + >> +int hantro_av1_get_hardware_mcomp_filt_type(int interpolation_filter) >> +{ >> +    switch (interpolation_filter) { >> +    case V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP: >> +        return HANTRO_AV1_EIGHT_TAP; >> +    case V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP_SMOOTH: >> +        return HANTRO_AV1_EIGHT_TAP_SMOOTH; >> +    case V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP_SHARP: >> +        return HANTRO_AV1_EIGHT_TAP_SHARP; >> +    case V4L2_AV1_INTERPOLATION_FILTER_BILINEAR: >> +        return HANTRO_AV1_BILINEAR; >> +    case V4L2_AV1_INTERPOLATION_FILTER_SWITCHABLE: >> +        return HANTRO_AV1_SWITCHABLE; >> +    } >> + >> +    return HANTRO_AV1_EIGHT_TAP_SMOOTH; >> +} >> + >> +int hantro_av1_get_frame_index(struct hantro_ctx *ctx, int ref) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> +    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> +    u64 timestamp; >> +    int i, idx; >> + >> +    if (ref < 0 || ref >= V4L2_AV1_REFS_PER_FRAME) >> +        return AV1_INVALID_IDX; >> + >> +    idx = frame->ref_frame_idx[ref]; >> + >> +    if (idx >= V4L2_AV1_TOTAL_REFS_PER_FRAME || idx < 0) >> +        return AV1_INVALID_IDX; >> + >> +    timestamp = frame->reference_frame_ts[idx]; >> +    for (i = 0; i < AV1_MAX_FRAME_BUF_COUNT; i++) { >> +        if (!av1_dec->frame_refs[i].used) >> +            continue; >> +        if (av1_dec->frame_refs[i].timestamp == timestamp) >> +            return i; >> +    } >> + >> +    return AV1_INVALID_IDX; >> +} >> + >> +int hantro_av1_get_order_hint(struct hantro_ctx *ctx, int ref) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    int idx = hantro_av1_get_frame_index(ctx, ref); >> + >> +    if (idx != AV1_INVALID_IDX) >> +        return av1_dec->frame_refs[idx].order_hint; >> + >> +    return 0; >> +} >> + >> +int hantro_av1_frame_ref(struct hantro_ctx *ctx, u64 timestamp) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> +    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> +    int i; >> + >> +    for (i = 0; i < AV1_MAX_FRAME_BUF_COUNT; i++) { >> +        int j; >> + >> +        if (av1_dec->frame_refs[i].used) >> +            continue; >> + >> +        av1_dec->frame_refs[i].width = frame->frame_width_minus_1 + 1; >> +        av1_dec->frame_refs[i].height = frame->frame_height_minus_1 >> + 1; >> +        av1_dec->frame_refs[i].mi_cols = >> DIV_ROUND_UP(frame->frame_width_minus_1 + 1, 8); >> +        av1_dec->frame_refs[i].mi_rows = >> DIV_ROUND_UP(frame->frame_height_minus_1 + 1, 8); >> +        av1_dec->frame_refs[i].timestamp = timestamp; >> +        av1_dec->frame_refs[i].frame_type = frame->frame_type; >> +        av1_dec->frame_refs[i].order_hint = frame->order_hint; >> +        av1_dec->frame_refs[i].vb2_ref = hantro_get_dst_buf(ctx); >> + >> +        for (j = 0; j < V4L2_AV1_TOTAL_REFS_PER_FRAME; j++) >> +            av1_dec->frame_refs[i].order_hints[j] = >> frame->order_hints[j]; >> +        av1_dec->frame_refs[i].used = true; >> +        av1_dec->current_frame_index = i; >> + >> +        return i; >> +    } >> + >> +    return AV1_INVALID_IDX; >> +} >> + >> +static void hantro_av1_frame_unref(struct hantro_ctx *ctx, int idx) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> + >> +    if (idx >= 0) >> +        av1_dec->frame_refs[idx].used = false; >> +} >> + >> +void hantro_av1_clean_refs(struct hantro_ctx *ctx) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> + >> +    int ref, idx; >> + >> +    for (idx = 0; idx < AV1_MAX_FRAME_BUF_COUNT; idx++) { >> +        u64 timestamp = av1_dec->frame_refs[idx].timestamp; >> +        bool used = false; >> + >> +        if (!av1_dec->frame_refs[idx].used) >> +            continue; >> + >> +        for (ref = 0; ref < V4L2_AV1_TOTAL_REFS_PER_FRAME; ref++) { >> +            if (ctrls->frame->reference_frame_ts[ref] == timestamp) >> +                used = true; >> +        } >> + >> +        if (!used) >> +            hantro_av1_frame_unref(ctx, idx); >> +    } >> +} >> + >> +size_t hantro_av1_luma_size(struct hantro_ctx *ctx) >> +{ >> +    return ctx->ref_fmt.plane_fmt[0].bytesperline * >> ctx->ref_fmt.height; >> +} >> + >> +size_t hantro_av1_chroma_size(struct hantro_ctx *ctx) >> +{ >> +    size_t cr_offset = hantro_av1_luma_size(ctx); >> + >> +    return ALIGN((cr_offset * 3) / 2, 64); >> +} >> + >> +static void hantro_av1_tiles_free(struct hantro_ctx *ctx) >> +{ >> +    struct hantro_dev *vpu = ctx->dev; >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> + >> +    if (av1_dec->db_data_col.cpu) >> +        dma_free_coherent(vpu->dev, av1_dec->db_data_col.size, >> +                  av1_dec->db_data_col.cpu, >> +                  av1_dec->db_data_col.dma); >> +    av1_dec->db_data_col.cpu = NULL; >> + >> +    if (av1_dec->db_ctrl_col.cpu) >> +        dma_free_coherent(vpu->dev, av1_dec->db_ctrl_col.size, >> +                  av1_dec->db_ctrl_col.cpu, >> +                  av1_dec->db_ctrl_col.dma); >> +    av1_dec->db_ctrl_col.cpu = NULL; >> + >> +    if (av1_dec->cdef_col.cpu) >> +        dma_free_coherent(vpu->dev, av1_dec->cdef_col.size, >> +                  av1_dec->cdef_col.cpu, av1_dec->cdef_col.dma); >> +    av1_dec->cdef_col.cpu = NULL; >> + >> +    if (av1_dec->sr_col.cpu) >> +        dma_free_coherent(vpu->dev, av1_dec->sr_col.size, >> +                  av1_dec->sr_col.cpu, av1_dec->sr_col.dma); >> +    av1_dec->sr_col.cpu = NULL; >> + >> +    if (av1_dec->lr_col.cpu) >> +        dma_free_coherent(vpu->dev, av1_dec->lr_col.size, >> +                  av1_dec->lr_col.cpu, av1_dec->lr_col.dma); >> +    av1_dec->lr_col.cpu = NULL; >> +} >> + >> +static int hantro_av1_tiles_reallocate(struct hantro_ctx *ctx) >> +{ >> +    struct hantro_dev *vpu = ctx->dev; >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> +    const struct v4l2_av1_tile_info *tile_info = >> &ctrls->frame->tile_info; >> +    unsigned int num_tile_cols = tile_info->tile_cols; >> +    unsigned int height = ALIGN(ctrls->frame->frame_height_minus_1 + >> 1, 64); >> +    unsigned int height_in_sb = height / 64; >> +    unsigned int stripe_num = ((height + 8) + 63) / 64; >> +    size_t size; >> + >> +    if (av1_dec->db_data_col.size >= >> +        ALIGN(height * 12 * ctx->bit_depth / 8, 128) * num_tile_cols) >> +        return 0; >> + >> +    hantro_av1_tiles_free(ctx); >> + >> +    size = ALIGN(height * 12 * ctx->bit_depth / 8, 128) * >> num_tile_cols; >> +    av1_dec->db_data_col.cpu = dma_alloc_coherent(vpu->dev, size, >> +                              &av1_dec->db_data_col.dma, >> +                              GFP_KERNEL); >> +    if (!av1_dec->db_data_col.cpu) >> +        goto buffer_allocation_error; >> +    av1_dec->db_data_col.size = size; >> + >> +    size = ALIGN(height * 2 * 16 / 4, 128) * num_tile_cols; >> +    av1_dec->db_ctrl_col.cpu = dma_alloc_coherent(vpu->dev, size, >> +                              &av1_dec->db_ctrl_col.dma, >> +                              GFP_KERNEL); >> +    if (!av1_dec->db_ctrl_col.cpu) >> +        goto buffer_allocation_error; >> +    av1_dec->db_ctrl_col.size = size; >> + >> +    size = ALIGN(height_in_sb * 44 * ctx->bit_depth * 16 / 8, 128) * >> num_tile_cols; >> +    av1_dec->cdef_col.cpu = dma_alloc_coherent(vpu->dev, size, >> +                           &av1_dec->cdef_col.dma, >> +                           GFP_KERNEL); >> +    if (!av1_dec->cdef_col.cpu) >> +        goto buffer_allocation_error; >> +    av1_dec->cdef_col.size = size; >> + >> +    size = ALIGN(height_in_sb * (3040 + 1280), 128) * num_tile_cols; >> +    av1_dec->sr_col.cpu = dma_alloc_coherent(vpu->dev, size, >> +                         &av1_dec->sr_col.dma, >> +                         GFP_KERNEL); >> +    if (!av1_dec->sr_col.cpu) >> +        goto buffer_allocation_error; >> +    av1_dec->sr_col.size = size; >> + >> +    size = ALIGN(stripe_num * 1536 * ctx->bit_depth / 8, 128) * >> num_tile_cols; >> +    av1_dec->lr_col.cpu = dma_alloc_coherent(vpu->dev, size, >> +                         &av1_dec->lr_col.dma, >> +                         GFP_KERNEL); >> +    if (!av1_dec->lr_col.cpu) >> +        goto buffer_allocation_error; >> +    av1_dec->lr_col.size = size; >> + >> +    av1_dec->num_tile_cols_allocated = num_tile_cols; >> +    return 0; >> + >> +buffer_allocation_error: >> +    hantro_av1_tiles_free(ctx); >> +    return -ENOMEM; >> +} >> + >> +void hantro_av1_exit(struct hantro_ctx *ctx) >> +{ >> +    struct hantro_dev *vpu = ctx->dev; >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> + >> +    if (av1_dec->global_model.cpu) >> +        dma_free_coherent(vpu->dev, av1_dec->global_model.size, >> +                  av1_dec->global_model.cpu, >> +                  av1_dec->global_model.dma); >> +    av1_dec->global_model.cpu = NULL; >> + >> +    if (av1_dec->tile_info.cpu) >> +        dma_free_coherent(vpu->dev, av1_dec->tile_info.size, >> +                  av1_dec->tile_info.cpu, >> +                  av1_dec->tile_info.dma); >> +    av1_dec->tile_info.cpu = NULL; >> + >> +    if (av1_dec->film_grain.cpu) >> +        dma_free_coherent(vpu->dev, av1_dec->film_grain.size, >> +                  av1_dec->film_grain.cpu, >> +                  av1_dec->film_grain.dma); >> +    av1_dec->film_grain.cpu = NULL; >> + >> +    if (av1_dec->prob_tbl.cpu) >> +        dma_free_coherent(vpu->dev, av1_dec->prob_tbl.size, >> +                  av1_dec->prob_tbl.cpu, av1_dec->prob_tbl.dma); >> +    av1_dec->prob_tbl.cpu = NULL; >> + >> +    if (av1_dec->prob_tbl_out.cpu) >> +        dma_free_coherent(vpu->dev, av1_dec->prob_tbl_out.size, >> +                  av1_dec->prob_tbl_out.cpu, >> +                  av1_dec->prob_tbl_out.dma); >> +    av1_dec->prob_tbl_out.cpu = NULL; >> + >> +    if (av1_dec->tile_buf.cpu) >> +        dma_free_coherent(vpu->dev, av1_dec->tile_buf.size, >> +                  av1_dec->tile_buf.cpu, av1_dec->tile_buf.dma); >> +    av1_dec->tile_buf.cpu = NULL; >> + >> +    hantro_av1_tiles_free(ctx); >> +} >> + >> +int hantro_av1_init(struct hantro_ctx *ctx) >> +{ >> +    struct hantro_dev *vpu = ctx->dev; >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> + >> +    memset(av1_dec, 0, sizeof(*av1_dec)); >> + >> +    av1_dec->global_model.cpu = dma_alloc_coherent(vpu->dev, >> GLOBAL_MODEL_SIZE, >> + &av1_dec->global_model.dma, >> +                               GFP_KERNEL); >> +    if (!av1_dec->global_model.cpu) >> +        return -ENOMEM; >> +    av1_dec->global_model.size = GLOBAL_MODEL_SIZE; >> + >> +    av1_dec->tile_info.cpu = dma_alloc_coherent(vpu->dev, >> AV1_TILE_INFO_SIZE, >> +                            &av1_dec->tile_info.dma, >> +                            GFP_KERNEL); >> +    if (!av1_dec->tile_info.cpu) >> +        return -ENOMEM; >> +    av1_dec->tile_info.size = AV1_TILE_INFO_SIZE; >> + >> +    av1_dec->film_grain.cpu = dma_alloc_coherent(vpu->dev, >> +                             ALIGN(sizeof(struct >> hantro_av1_film_grain), >> +                               2048), >> +                             &av1_dec->film_grain.dma, >> +                             GFP_KERNEL); >> +    if (!av1_dec->film_grain.cpu) >> +        return -ENOMEM; >> +    av1_dec->film_grain.size = ALIGN(sizeof(struct >> hantro_av1_film_grain), 2048); >> + >> +    av1_dec->prob_tbl.cpu = dma_alloc_coherent(vpu->dev, >> +                           ALIGN(sizeof(struct av1cdfs), 2048), >> +                           &av1_dec->prob_tbl.dma, >> +                           GFP_KERNEL); >> +    if (!av1_dec->prob_tbl.cpu) >> +        return -ENOMEM; >> +    av1_dec->prob_tbl.size = ALIGN(sizeof(struct av1cdfs), 2048); >> + >> +    av1_dec->prob_tbl_out.cpu = dma_alloc_coherent(vpu->dev, >> +                               ALIGN(sizeof(struct av1cdfs), 2048), >> + &av1_dec->prob_tbl_out.dma, >> +                               GFP_KERNEL); >> +    if (!av1_dec->prob_tbl_out.cpu) >> +        return -ENOMEM; >> +    av1_dec->prob_tbl_out.size = ALIGN(sizeof(struct av1cdfs), 2048); >> +    av1_dec->cdfs = &av1_dec->default_cdfs; >> +    av1_dec->cdfs_ndvc = &av1_dec->default_cdfs_ndvc; >> + >> +    hantro_av1_set_default_cdfs(av1_dec->cdfs, av1_dec->cdfs_ndvc); >> + >> +    av1_dec->tile_buf.cpu = dma_alloc_coherent(vpu->dev, >> +                           AV1_TILE_SIZE, >> +                           &av1_dec->tile_buf.dma, >> +                           GFP_KERNEL); >> +    if (!av1_dec->tile_buf.cpu) >> +        return -ENOMEM; >> +    av1_dec->tile_buf.size = AV1_TILE_SIZE; >> + >> +    return 0; >> +} >> + >> +int hantro_av1_prepare_run(struct hantro_ctx *ctx) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> + >> +    ctrls->sequence = hantro_get_ctrl(ctx, >> V4L2_CID_STATELESS_AV1_SEQUENCE); >> +    if (WARN_ON(!ctrls->sequence)) >> +        return -EINVAL; >> + >> +    ctrls->tile_group_entry = >> +        hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY); >> +    if (WARN_ON(!ctrls->tile_group_entry)) >> +        return -EINVAL; >> + >> +    ctrls->frame = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_FRAME); >> +    if (WARN_ON(!ctrls->frame)) >> +        return -EINVAL; >> + >> +    ctrls->film_grain = >> +        hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_FILM_GRAIN); >> + >> +    return hantro_av1_tiles_reallocate(ctx); >> +} >> + >> +static int hantro_av1_get_msb(u32 n) >> +{ >> +    if (n == 0) >> +        return 0; >> +    return 31 ^ __builtin_clz(n); >> +} >> + >> +static short hantro_av1_resolve_divisor_32(u32 d, short *shift) >> +{ >> +    int f; >> +    u64 e; >> + >> +    *shift = hantro_av1_get_msb(d); >> +    /* e is obtained from D after resetting the most significant 1 >> bit. */ >> +    e = d - ((u32)1 << *shift); >> +    /* Get the most significant DIV_LUT_BITS (8) bits of e into f */ >> +    if (*shift > DIV_LUT_BITS) >> +        f = AV1_DIV_ROUND_UP_POW2(e, *shift - DIV_LUT_BITS); >> +    else >> +        f = e << (DIV_LUT_BITS - *shift); >> +    if (f > DIV_LUT_NUM) >> +        return -1; >> +    *shift += DIV_LUT_PREC_BITS; >> +    /* Use f as lookup into the precomputed table of multipliers */ >> +    return div_lut[f]; >> +} >> + >> +static void hantro_av1_get_shear_params(const u32 *params, s64 *alpha, >> +                    s64 *beta, s64 *gamma, s64 *delta) >> +{ >> +    const int *mat = params; >> +    short shift; >> +    short y; >> +    long long gv, dv; >> + >> +    if (mat[2] <= 0) >> +        return; >> + >> +    *alpha = clamp_val(mat[2] - (1 << WARPEDMODEL_PREC_BITS), >> S16_MIN, S16_MAX); >> +    *beta = clamp_val(mat[3], S16_MIN, S16_MAX); >> + >> +    y = hantro_av1_resolve_divisor_32(abs(mat[2]), &shift) * (mat[2] >> < 0 ? -1 : 1); >> + >> +    gv = ((long long)mat[4] * (1 << WARPEDMODEL_PREC_BITS)) * y; >> + >> +    *gamma = clamp_val((int)AV1_DIV_ROUND_UP_POW2_SIGNED(gv, shift), >> S16_MIN, S16_MAX); >> + >> +    dv = ((long long)mat[3] * mat[4]) * y; >> +    *delta = clamp_val(mat[5] - >> +        (int)AV1_DIV_ROUND_UP_POW2_SIGNED(dv, shift) - (1 << >> WARPEDMODEL_PREC_BITS), >> +        S16_MIN, S16_MAX); >> + >> +    *alpha = AV1_DIV_ROUND_UP_POW2_SIGNED(*alpha, >> WARP_PARAM_REDUCE_BITS) >> +         * (1 << WARP_PARAM_REDUCE_BITS); >> +    *beta = AV1_DIV_ROUND_UP_POW2_SIGNED(*beta, WARP_PARAM_REDUCE_BITS) >> +        * (1 << WARP_PARAM_REDUCE_BITS); >> +    *gamma = AV1_DIV_ROUND_UP_POW2_SIGNED(*gamma, >> WARP_PARAM_REDUCE_BITS) >> +         * (1 << WARP_PARAM_REDUCE_BITS); >> +    *delta = AV1_DIV_ROUND_UP_POW2_SIGNED(*delta, >> WARP_PARAM_REDUCE_BITS) >> +        * (1 << WARP_PARAM_REDUCE_BITS); >> +} >> + >> +void hantro_av1_set_global_model(struct hantro_ctx *ctx) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> +    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> +    const struct v4l2_av1_global_motion *gm = &frame->global_motion; >> +    u8 *dst = av1_dec->global_model.cpu; >> +    int ref_frame, i; >> + >> +    memset(dst, 0, GLOBAL_MODEL_SIZE); >> +    for (ref_frame = 0; ref_frame < V4L2_AV1_REFS_PER_FRAME; >> ++ref_frame) { >> +        s64 alpha = 0, beta = 0, gamma = 0, delta = 0; >> + >> +        for (i = 0; i < 6; ++i) { >> +            if (i == 2) >> +                *(s32 *)dst = >> +                    gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][3]; >> +            else if (i == 3) >> +                *(s32 *)dst = >> +                    gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][2]; >> +            else >> +                *(s32 *)dst = >> +                    gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][i]; >> +            dst += 4; >> +        } >> + >> +        if (gm->type[V4L2_AV1_REF_LAST_FRAME + ref_frame] <= >> V4L2_AV1_WARP_MODEL_AFFINE) >> + hantro_av1_get_shear_params(&gm->params[V4L2_AV1_REF_LAST_FRAME + >> ref_frame][0], >> +                            &alpha, &beta, &gamma, &delta); >> + >> +        *(s16 *)dst = alpha; >> +        dst += 2; >> +        *(s16 *)dst = beta; >> +        dst += 2; >> +        *(s16 *)dst = gamma; >> +        dst += 2; >> +        *(s16 *)dst = delta; >> +        dst += 2; >> +    } >> +} >> + >> +int hantro_av1_tile_log2(int target) >> +{ >> +    int k; >> + >> +    /* >> +     * returns the smallest value for k such that 1 << k is greater >> +     * than or equal to target >> +     */ >> +    for (k = 0; (1 << k) < target; k++) >> +        ; >> + >> +    return k; >> +} >> + >> +int hantro_av1_get_dist(struct hantro_ctx *ctx, int a, int b) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> +    int bits = ctrls->sequence->order_hint_bits - 1; >> +    int diff, m; >> + >> +    if (!ctrls->sequence->order_hint_bits) >> +        return 0; >> + >> +    diff = a - b; >> +    m = 1 << bits; >> +    diff = (diff & (m - 1)) - (diff & m); >> + >> +    return diff; >> +} >> + >> +void hantro_av1_set_frame_sign_bias(struct hantro_ctx *ctx) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> +    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> +    const struct v4l2_ctrl_av1_sequence *sequence = ctrls->sequence; >> +    int i; >> + >> +    if (!sequence->order_hint_bits || IS_INTRA(frame->frame_type)) { >> +        for (i = 0; i < V4L2_AV1_TOTAL_REFS_PER_FRAME; i++) >> +            av1_dec->ref_frame_sign_bias[i] = 0; >> + >> +        return; >> +    } >> +    // Identify the nearest forward and backward references. >> +    for (i = 0; i < V4L2_AV1_TOTAL_REFS_PER_FRAME - 1; i++) { >> +        if (hantro_av1_get_frame_index(ctx, i) >= 0) { >> +            int rel_off = >> +                hantro_av1_get_dist(ctx, >> +                        hantro_av1_get_order_hint(ctx, i), >> +                        frame->order_hint); >> +            av1_dec->ref_frame_sign_bias[i + 1] = (rel_off <= 0) ? 0 >> : 1; >> +        } >> +    } >> +} >> + >> +void hantro_av1_init_scaling_function(const u8 *values, const u8 >> *scaling, >> +                      u8 num_points, u8 *scaling_lut) >> +{ >> +    int i, point; >> + >> +    if (num_points == 0) { >> +        memset(scaling_lut, 0, 256); >> +        return; >> +    } >> + >> +    for (point = 0; point < num_points - 1; point++) { >> +        int x; >> +        s32 delta_y = scaling[point + 1] - scaling[point]; >> +        s32 delta_x = values[point + 1] - values[point]; >> +        s64 delta = >> +            delta_x ? delta_y * ((65536 + (delta_x >> 1)) / >> +                     delta_x) : 0; >> + >> +        for (x = 0; x < delta_x; x++) { >> +            scaling_lut[values[point] + x] = >> +                scaling[point] + >> +                (s32)((x * delta + 32768) >> 16); >> +        } >> +    } >> + >> +    for (i = values[num_points - 1]; i < 256; i++) >> +        scaling_lut[i] = scaling[num_points - 1]; >> +} >> + >> +void hantro_av1_set_tile_info(struct hantro_ctx *ctx) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> +    const struct v4l2_av1_tile_info *tile_info = >> &ctrls->frame->tile_info; >> +    const struct v4l2_ctrl_av1_tile_group_entry *group_entry = >> +        ctrls->tile_group_entry; >> +    u8 *dst = av1_dec->tile_info.cpu; >> +    int tile0, tile1; >> + >> +    memset(dst, 0, av1_dec->tile_info.size); >> + >> +    for (tile0 = 0; tile0 < tile_info->tile_cols; tile0++) { >> +        for (tile1 = 0; tile1 < tile_info->tile_rows; tile1++) { >> +            int tile_id = tile1 * tile_info->tile_cols + tile0; >> +            u32 start, end; >> +            u32 y0 = >> +                tile_info->height_in_sbs_minus_1[tile1] + 1; >> +            u32 x0 = tile_info->width_in_sbs_minus_1[tile0] + 1; >> + >> +            /* tile size in SB units (width,height) */ >> +            *dst++ = x0; >> +            *dst++ = 0; >> +            *dst++ = 0; >> +            *dst++ = 0; >> +            *dst++ = y0; >> +            *dst++ = 0; >> +            *dst++ = 0; >> +            *dst++ = 0; >> + >> +            /* tile start position */ >> +            start = group_entry[tile_id].tile_offset - >> group_entry[0].tile_offset; >> +            *dst++ = start & 255; >> +            *dst++ = (start >> 8) & 255; >> +            *dst++ = (start >> 16) & 255; >> +            *dst++ = (start >> 24) & 255; >> + >> +            /* number of bytes in tile data */ >> +            end = start + group_entry[tile_id].tile_size; >> +            *dst++ = end & 255; >> +            *dst++ = (end >> 8) & 255; >> +            *dst++ = (end >> 16) & 255; >> +            *dst++ = (end >> 24) & 255; >> +        } >> +    } >> +} >> + >> +bool hantro_av1_is_lossless(struct hantro_ctx *ctx) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> +    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> +    const struct v4l2_av1_segmentation *segmentation = >> &frame->segmentation; >> +    const struct v4l2_av1_quantization *quantization = >> &frame->quantization; >> +    int i; >> + >> +    for (i = 0; i < V4L2_AV1_MAX_SEGMENTS; i++) { >> +        int qindex = quantization->base_q_idx; >> + >> +        if (segmentation->feature_enabled[i] & >> + V4L2_AV1_SEGMENT_FEATURE_ENABLED(V4L2_AV1_SEG_LVL_ALT_Q)) { >> +            qindex += >> segmentation->feature_data[i][V4L2_AV1_SEG_LVL_ALT_Q]; >> +        } >> +        qindex = clamp(qindex, 0, 255); >> + >> +        if (qindex || >> +            quantization->delta_q_y_dc || >> +            quantization->delta_q_u_dc || >> +            quantization->delta_q_u_ac || >> +            quantization->delta_q_v_dc || >> +            quantization->delta_q_v_ac) >> +            return false; >> +    } >> + >> +    return true; >> +} >> + >> +void hantro_av1_update_prob(struct hantro_ctx *ctx) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> +    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> +    bool frame_is_intra = IS_INTRA(frame->frame_type); >> +    struct av1cdfs *out_cdfs = (struct av1cdfs >> *)av1_dec->prob_tbl_out.cpu; >> +    int i; >> + >> +    if (frame->flags & >> V4L2_AV1_FRAME_FLAG_DISABLE_FRAME_END_UPDATE_CDF) >> +        return; >> + >> +    for (i = 0; i < NUM_REF_FRAMES; i++) { >> +        if (frame->refresh_frame_flags & BIT(i)) { >> +            struct mvcdfs stored_mv_cdf; >> + >> +            hantro_av1_get_cdfs(ctx, i); >> +            stored_mv_cdf = av1_dec->cdfs->mv_cdf; >> +            *av1_dec->cdfs = *out_cdfs; >> +            if (frame_is_intra) { >> +                av1_dec->cdfs->mv_cdf = stored_mv_cdf; >> +                *av1_dec->cdfs_ndvc = out_cdfs->mv_cdf; >> +            } >> +            hantro_av1_store_cdfs(ctx, frame->refresh_frame_flags); >> +            break; >> +        } >> +    } >> +} >> + >> +void hantro_av1_set_prob(struct hantro_ctx *ctx) >> +{ >> +    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> +    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> +    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> +    const struct v4l2_av1_quantization *quantization = >> &frame->quantization; >> +    bool error_resilient_mode = >> +        !!(frame->flags & V4L2_AV1_FRAME_FLAG_ERROR_RESILIENT_MODE); >> +    bool frame_is_intra = IS_INTRA(frame->frame_type); >> + >> +    if (error_resilient_mode || frame_is_intra || >> +        frame->primary_ref_frame == AV1_PRIMARY_REF_NONE) { >> +        av1_dec->cdfs = &av1_dec->default_cdfs; >> +        av1_dec->cdfs_ndvc = &av1_dec->default_cdfs_ndvc; >> + hantro_av1_default_coeff_probs(quantization->base_q_idx, >> +                           av1_dec->cdfs); >> +    } else { >> +        if (frame->primary_ref_frame < 0 || >> +            frame->primary_ref_frame >= V4L2_AV1_REFS_PER_FRAME) >> +            return; >> + >> +        hantro_av1_get_cdfs(ctx, >> frame->ref_frame_idx[frame->primary_ref_frame]); >> +    } >> +    hantro_av1_store_cdfs(ctx, frame->refresh_frame_flags); >> + >> +    memcpy(av1_dec->prob_tbl.cpu, av1_dec->cdfs, sizeof(struct >> av1cdfs)); >> + >> +    if (frame_is_intra) { >> +        int mv_offset = offsetof(struct av1cdfs, mv_cdf); >> +        /* Overwrite MV context area with intrabc MV context */ >> +        memcpy(av1_dec->prob_tbl.cpu + mv_offset, av1_dec->cdfs_ndvc, >> +               sizeof(struct mvcdfs)); >> +    } >> +} >> diff --git a/drivers/media/platform/verisilicon/hantro_av1.h >> b/drivers/media/platform/verisilicon/hantro_av1.h >> new file mode 100644 >> index 000000000000..d91c814eefcb >> --- /dev/null >> +++ b/drivers/media/platform/verisilicon/hantro_av1.h >> @@ -0,0 +1,64 @@ >> +/* SPDX-License-Identifier: GPL-2.0-only */ >> + >> +#ifndef _HANTRO_AV1_H_ >> +#define _HANTRO_AV1_H_ >> + >> +#define AV1_PRIMARY_REF_NONE    7 >> +#define AV1_REF_SCALE_SHIFT    14 >> +#define MAX_FRAME_DISTANCE    31 >> +#define AV1DEC_MAX_PIC_BUFFERS    24 >> + >> +#define SCALE_NUMERATOR 8 >> +#define SUPERRES_SCALE_DENOMINATOR_MIN (SCALE_NUMERATOR + 1) >> + >> +#define RS_SCALE_SUBPEL_BITS 14 >> +#define RS_SCALE_SUBPEL_MASK ((1 << RS_SCALE_SUBPEL_BITS) - 1) >> +#define RS_SUBPEL_BITS 6 >> +#define RS_SUBPEL_MASK ((1 << RS_SUBPEL_BITS) - 1) >> +#define RS_SCALE_EXTRA_BITS (RS_SCALE_SUBPEL_BITS - RS_SUBPEL_BITS) >> +#define RS_SCALE_EXTRA_OFF (1 << (RS_SCALE_EXTRA_BITS - 1)) >> + >> +/* >> + * These 3 values aren't defined enum v4l2_av1_segment_feature because >> + * they are not part of the specification >> + */ >> +#define V4L2_AV1_SEG_LVL_ALT_LF_Y_H    2 >> +#define V4L2_AV1_SEG_LVL_ALT_LF_U    3 >> +#define V4L2_AV1_SEG_LVL_ALT_LF_V    4 >> + >> +#define IS_INTRA(type) ((type == V4L2_AV1_KEY_FRAME) || (type == >> V4L2_AV1_INTRA_ONLY_FRAME)) >> + >> +#define LST_BUF_IDX (V4L2_AV1_REF_LAST_FRAME - V4L2_AV1_REF_LAST_FRAME) >> +#define LST2_BUF_IDX (V4L2_AV1_REF_LAST2_FRAME - >> V4L2_AV1_REF_LAST_FRAME) >> +#define LST3_BUF_IDX (V4L2_AV1_REF_LAST3_FRAME - >> V4L2_AV1_REF_LAST_FRAME) >> +#define GLD_BUF_IDX (V4L2_AV1_REF_GOLDEN_FRAME - >> V4L2_AV1_REF_LAST_FRAME) >> +#define BWD_BUF_IDX (V4L2_AV1_REF_BWDREF_FRAME - >> V4L2_AV1_REF_LAST_FRAME) >> +#define ALT2_BUF_IDX (V4L2_AV1_REF_ALTREF2_FRAME - >> V4L2_AV1_REF_LAST_FRAME) >> +#define ALT_BUF_IDX (V4L2_AV1_REF_ALTREF_FRAME - >> V4L2_AV1_REF_LAST_FRAME) >> + >> +#define AV1_INVALID_IDX        -1 >> + >> +int hantro_av1_get_frame_index(struct hantro_ctx *ctx, int ref); >> +int hantro_av1_get_order_hint(struct hantro_ctx *ctx, int ref); >> +int hantro_av1_frame_ref(struct hantro_ctx *ctx, u64 timestamp); >> +void hantro_av1_clean_refs(struct hantro_ctx *ctx); >> +size_t hantro_av1_luma_size(struct hantro_ctx *ctx); >> +size_t hantro_av1_chroma_size(struct hantro_ctx *ctx); >> +void hantro_av1_exit(struct hantro_ctx *ctx); >> +int hantro_av1_init(struct hantro_ctx *ctx); >> +int hantro_av1_prepare_run(struct hantro_ctx *ctx); >> +void hantro_av1_set_global_model(struct hantro_ctx *ctx); >> +int hantro_av1_tile_log2(int target); >> +int hantro_av1_get_dist(struct hantro_ctx *ctx, int a, int b); >> +void hantro_av1_set_frame_sign_bias(struct hantro_ctx *ctx); >> +void hantro_av1_init_scaling_function(const u8 *values, const u8 >> *scaling, >> +                      u8 num_points, u8 *scaling_lut); >> +void hantro_av1_set_tile_info(struct hantro_ctx *ctx); >> +bool hantro_av1_is_lossless(struct hantro_ctx *ctx); >> +void hantro_av1_update_prob(struct hantro_ctx *ctx); >> +void hantro_av1_set_prob(struct hantro_ctx *ctx); >> + >> +int hantro_av1_get_hardware_mcomp_filt_type(int interpolation_filter); >> +int hantro_av1_get_hardware_tx_mode(enum v4l2_av1_tx_mode tx_mode); >> + >> +#endif >> diff --git >> a/drivers/media/platform/verisilicon/rockchip_av1_entropymode.c >> b/drivers/media/platform/verisilicon/hantro_av1_entropymode.c >> similarity index 99% >> rename from >> drivers/media/platform/verisilicon/rockchip_av1_entropymode.c >> rename to drivers/media/platform/verisilicon/hantro_av1_entropymode.c >> index b1ae72ad675e..4f7bfec73668 100644 >> --- a/drivers/media/platform/verisilicon/rockchip_av1_entropymode.c >> +++ b/drivers/media/platform/verisilicon/hantro_av1_entropymode.c >> @@ -11,7 +11,7 @@ >>    */ >>     #include "hantro.h" >> -#include "rockchip_av1_entropymode.h" >> +#include "hantro_av1_entropymode.h" >>     #define AOM_ICDF ICDF >>   #define AOM_CDF2(a0) AOM_ICDF(a0) >> @@ -4195,7 +4195,7 @@ static const u16 default_bits_cdf[][10] = { >>       } >>   }; >>   -static int rockchip_av1_get_q_ctx(int q) >> +static int hantro_av1_get_q_ctx(int q) >>   { >>       if (q <= 20) >>           return 0; >> @@ -4206,10 +4206,10 @@ static int rockchip_av1_get_q_ctx(int q) >>       return 3; >>   } >>   -void rockchip_av1_default_coeff_probs(u32 base_qindex, void *ptr) >> +void hantro_av1_default_coeff_probs(u32 base_qindex, void *ptr) >>   { >>       struct av1cdfs *cdfs = (struct av1cdfs *)ptr; >> -    const int index = rockchip_av1_get_q_ctx(base_qindex); >> +    const int index = hantro_av1_get_q_ctx(base_qindex); >>         memcpy(cdfs->txb_skip_cdf, av1_default_txb_skip_cdfs[index], >>              sizeof(av1_default_txb_skip_cdfs[0])); >> @@ -4240,8 +4240,8 @@ void rockchip_av1_default_coeff_probs(u32 >> base_qindex, void *ptr) >>              sizeof(av1_default_eob_multi1024_cdfs[0])); >>   } >>   -void rockchip_av1_set_default_cdfs(struct av1cdfs *cdfs, >> -                   struct mvcdfs *cdfs_ndvc) >> +void hantro_av1_set_default_cdfs(struct av1cdfs *cdfs, >> +                 struct mvcdfs *cdfs_ndvc) >>   { >>       memcpy(cdfs->partition_cdf, default_partition_cdf, >>              sizeof(cdfs->partition_cdf)); >> @@ -4398,7 +4398,7 @@ void rockchip_av1_set_default_cdfs(struct >> av1cdfs *cdfs, >>              sizeof(cdfs->compound_idx_cdf)); >>   } >>   -void rockchip_av1_get_cdfs(struct hantro_ctx *ctx, u32 ref_idx) >> +void hantro_av1_get_cdfs(struct hantro_ctx *ctx, u32 ref_idx) >>   { >>       struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >>   @@ -4406,8 +4406,8 @@ void rockchip_av1_get_cdfs(struct hantro_ctx >> *ctx, u32 ref_idx) >>       av1_dec->cdfs_ndvc = &av1_dec->cdfs_last_ndvc[ref_idx]; >>   } >>   -void rockchip_av1_store_cdfs(struct hantro_ctx *ctx, >> -                 u32 refresh_frame_flags) >> +void hantro_av1_store_cdfs(struct hantro_ctx *ctx, >> +               u32 refresh_frame_flags) >>   { >>       struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >>       int i; >> diff --git >> a/drivers/media/platform/verisilicon/rockchip_av1_entropymode.h >> b/drivers/media/platform/verisilicon/hantro_av1_entropymode.h >> similarity index 95% >> rename from >> drivers/media/platform/verisilicon/rockchip_av1_entropymode.h >> rename to drivers/media/platform/verisilicon/hantro_av1_entropymode.h >> index bbf8424c7d2c..abbc660ecce3 100644 >> --- a/drivers/media/platform/verisilicon/rockchip_av1_entropymode.h >> +++ b/drivers/media/platform/verisilicon/hantro_av1_entropymode.h >> @@ -1,7 +1,7 @@ >>   /* SPDX-License-Identifier: GPL-2.0-only */ >>   -#ifndef _ROCKCHIP_AV1_ENTROPYMODE_H_ >> -#define _ROCKCHIP_AV1_ENTROPYMODE_H_ >> +#ifndef _HANTRO_AV1_ENTROPYMODE_H_ >> +#define _HANTRO_AV1_ENTROPYMODE_H_ >>     #include >>   @@ -262,11 +262,11 @@ struct av1cdfs { >>       u16 dummy3[16]; >>   }; >>   -void rockchip_av1_store_cdfs(struct hantro_ctx *ctx, >> -                 u32 refresh_frame_flags); >> -void rockchip_av1_get_cdfs(struct hantro_ctx *ctx, u32 ref_idx); >> -void rockchip_av1_set_default_cdfs(struct av1cdfs *cdfs, >> -                   struct mvcdfs *cdfs_ndvc); >> -void rockchip_av1_default_coeff_probs(u32 base_qindex, void *ptr); >> +void hantro_av1_store_cdfs(struct hantro_ctx *ctx, >> +               u32 refresh_frame_flags); >> +void hantro_av1_get_cdfs(struct hantro_ctx *ctx, u32 ref_idx); >> +void hantro_av1_set_default_cdfs(struct av1cdfs *cdfs, >> +                 struct mvcdfs *cdfs_ndvc); >> +void hantro_av1_default_coeff_probs(u32 base_qindex, void *ptr); >>   -#endif /* _ROCKCHIP_AV1_ENTROPYMODE_H_ */ >> +#endif /* _HANTRO_AV1_ENTROPYMODE_H_ */ >> diff --git >> a/drivers/media/platform/verisilicon/rockchip_av1_filmgrain.c >> b/drivers/media/platform/verisilicon/hantro_av1_filmgrain.c >> similarity index 85% >> rename from drivers/media/platform/verisilicon/rockchip_av1_filmgrain.c >> rename to drivers/media/platform/verisilicon/hantro_av1_filmgrain.c >> index f64dea797eff..a1fc40e0218a 100644 >> --- a/drivers/media/platform/verisilicon/rockchip_av1_filmgrain.c >> +++ b/drivers/media/platform/verisilicon/hantro_av1_filmgrain.c >> @@ -1,6 +1,6 @@ >>   // SPDX-License-Identifier: GPL-2.0-only OR Apache-2.0 >>   -#include "rockchip_av1_filmgrain.h" >> +#include "hantro_av1_filmgrain.h" >>     static const s32 gaussian_sequence[2048] = { >>       56, 568, -180, 172, 124, -84, 172, -64, -900, 24, 820, >> @@ -204,8 +204,8 @@ static inline s32 round_power_of_two(const s32 >> val, s32 n) >>       return (val + a) >> n; >>   } >>   -static void rockchip_av1_init_random_generator(u8 luma_num, u16 seed, >> -                           u16 *random_register) >> +static void hantro_av1_init_random_generator(u8 luma_num, u16 seed, >> +                         u16 *random_register) >>   { >>       u16 random_reg = seed; >>   @@ -214,7 +214,7 @@ static void >> rockchip_av1_init_random_generator(u8 luma_num, u16 seed, >>       *random_register = random_reg; >>   } >>   -static inline void rockchip_av1_update_random_register(u16 >> *random_register) >> +static inline void hantro_av1_update_random_register(u16 >> *random_register) >>   { >>       u16 bit; >>       u16 random_reg = *random_register; >> @@ -224,21 +224,20 @@ static inline void >> rockchip_av1_update_random_register(u16 *random_register) >>       *random_register = (random_reg >> 1) | (bit << 15); >>   } >>   -static inline s32 rockchip_av1_get_random_number(u16 random_register) >> +static inline s32 hantro_av1_get_random_number(u16 random_register) >>   { >>       return (random_register >> 5) & ((1 << 11) - 1); >>   } >>   -void rockchip_av1_generate_luma_grain_block(s32 >> (*luma_grain_block)[73][82], >> -                        s32 bitdepth, >> -                        u8 num_y_points, >> -                        s32 grain_scale_shift, >> -                        s32 ar_coeff_lag, >> -                        s32 (*ar_coeffs_y)[24], >> -                        s32 ar_coeff_shift, >> -                        s32 grain_min, >> -                        s32 grain_max, >> -                        u16 random_seed) >> +void hantro_av1_generate_luma_grain_block(struct >> hantro_av1_coeffs_grain_block *coeffs, >> +                      s32 bitdepth, >> +                      u8 num_y_points, >> +                      s32 grain_scale_shift, >> +                      s32 ar_coeff_lag, >> +                      s32 ar_coeff_shift, >> +                      s32 grain_min, >> +                      s32 grain_max, >> +                      u16 random_seed) >>   { >>       s32 gauss_sec_shift = 12 - bitdepth + grain_scale_shift; >>       u16 grain_random_register = random_seed; >> @@ -247,15 +246,15 @@ void rockchip_av1_generate_luma_grain_block(s32 >> (*luma_grain_block)[73][82], >>       for (i = 0; i < 73; i++) { >>           for (j = 0; j < 82; j++) { >>               if (num_y_points > 0) { >> -                rockchip_av1_update_random_register >> +                hantro_av1_update_random_register >>                       (&grain_random_register); >> -                (*luma_grain_block)[i][j] = >> +                coeffs->luma_grain_block[i][j] = >>                       round_power_of_two(gaussian_sequence >> -                         [rockchip_av1_get_random_number >> +                         [hantro_av1_get_random_number >>                             (grain_random_register)], >>                            gauss_sec_shift); >>               } else { >> -                (*luma_grain_block)[i][j] = 0; >> +                coeffs->luma_grain_block[i][j] = 0; >>               } >>           } >>       } >> @@ -272,72 +271,68 @@ void rockchip_av1_generate_luma_grain_block(s32 >> (*luma_grain_block)[73][82], >>                        deltacol <= ar_coeff_lag; deltacol++) { >>                       if (deltarow == 0 && deltacol == 0) >>                           break; >> -                    wsum = wsum + (*ar_coeffs_y)[pos] * >> -                        (*luma_grain_block)[i + deltarow][j + >> deltacol]; >> +                    wsum = wsum + coeffs->ar_coeffs_y[pos] * >> +                        coeffs->luma_grain_block[i + deltarow][j + >> deltacol]; >>                       ++pos; >>                   } >>               } >> -            (*luma_grain_block)[i][j] = >> -                clamp((*luma_grain_block)[i][j] + >> +            coeffs->luma_grain_block[i][j] = >> +                clamp(coeffs->luma_grain_block[i][j] + >>                         round_power_of_two(wsum, ar_coeff_shift), >>                         grain_min, grain_max); >>           } >>   } >>     // Calculate chroma grain noise once per frame >> -void rockchip_av1_generate_chroma_grain_block(s32 >> (*luma_grain_block)[73][82], >> -                          s32 (*cb_grain_block)[38][44], >> -                          s32 (*cr_grain_block)[38][44], >> -                          s32 bitdepth, >> -                          u8 num_y_points, >> -                          u8 num_cb_points, >> -                          u8 num_cr_points, >> -                          s32 grain_scale_shift, >> -                          s32 ar_coeff_lag, >> -                          s32 (*ar_coeffs_cb)[25], >> -                          s32 (*ar_coeffs_cr)[25], >> -                          s32 ar_coeff_shift, >> -                          s32 grain_min, >> -                          s32 grain_max, >> -                          u8 chroma_scaling_from_luma, >> -                          u16 random_seed) >> +void hantro_av1_generate_chroma_grain_block(struct >> hantro_av1_coeffs_grain_block *coeffs, >> +                        s32 bitdepth, >> +                        u8 num_y_points, >> +                        u8 num_cb_points, >> +                        u8 num_cr_points, >> +                        s32 grain_scale_shift, >> +                        s32 ar_coeff_lag, >> +                        s32 ar_coeff_shift, >> +                        s32 grain_min, >> +                        s32 grain_max, >> +                        u8 chroma_scaling_from_luma, >> +                        u16 random_seed) >>   { >>       s32 gauss_sec_shift = 12 - bitdepth + grain_scale_shift; >>       u16 grain_random_register = 0; >>       s32 i, j; >>   -    rockchip_av1_init_random_generator(7, random_seed, >> -                       &grain_random_register); >> +    hantro_av1_init_random_generator(7, random_seed, >> +                     &grain_random_register); >>       for (i = 0; i < 38; i++) { >>           for (j = 0; j < 44; j++) { >>               if (num_cb_points || chroma_scaling_from_luma) { >> -                rockchip_av1_update_random_register >> +                hantro_av1_update_random_register >>                       (&grain_random_register); >> -                (*cb_grain_block)[i][j] = >> +                coeffs->cb_grain_block[i][j] = >>                       round_power_of_two(gaussian_sequence >> -                         [rockchip_av1_get_random_number >> +                         [hantro_av1_get_random_number >>                             (grain_random_register)], >>                            gauss_sec_shift); >>               } else { >> -                (*cb_grain_block)[i][j] = 0; >> +                coeffs->cb_grain_block[i][j] = 0; >>               } >>           } >>       } >>   -    rockchip_av1_init_random_generator(11, random_seed, >> -                       &grain_random_register); >> +    hantro_av1_init_random_generator(11, random_seed, >> +                     &grain_random_register); >>       for (i = 0; i < 38; i++) { >>           for (j = 0; j < 44; j++) { >>               if (num_cr_points || chroma_scaling_from_luma) { >> -                rockchip_av1_update_random_register >> +                hantro_av1_update_random_register >>                       (&grain_random_register); >> -                (*cr_grain_block)[i][j] = >> +                coeffs->cr_grain_block[i][j] = >>                       round_power_of_two(gaussian_sequence >> -                         [rockchip_av1_get_random_number >> +                         [hantro_av1_get_random_number >>                             (grain_random_register)], >>                            gauss_sec_shift); >>               } else { >> -                (*cr_grain_block)[i][j] = 0; >> +                coeffs->cr_grain_block[i][j] = 0; >>               } >>           } >>       } >> @@ -355,12 +350,12 @@ void >> rockchip_av1_generate_chroma_grain_block(s32 >> (*luma_grain_block)[73][82], >>                        deltacol <= ar_coeff_lag; deltacol++) { >>                       if (deltarow == 0 && deltacol == 0) >>                           break; >> -                    wsum_cb = wsum_cb + (*ar_coeffs_cb)[pos] * >> -                        (*cb_grain_block)[i + deltarow][j + deltacol]; >> +                    wsum_cb = wsum_cb + coeffs->ar_coeffs_cb[pos] * >> +                        coeffs->cb_grain_block[i + deltarow][j + >> deltacol]; >>                       wsum_cr = >>                           wsum_cr + >> -                        (*ar_coeffs_cr)[pos] * >> -                        (*cr_grain_block)[i + deltarow][j + deltacol]; >> +                        coeffs->ar_coeffs_cr[pos] * >> +                        coeffs->cr_grain_block[i + deltarow][j + >> deltacol]; >>                       ++pos; >>                   } >>               } >> @@ -371,28 +366,28 @@ void >> rockchip_av1_generate_chroma_grain_block(s32 >> (*luma_grain_block)[73][82], >>                   s32 luma_coord_x = (j << 1) - 3; >>                     av_luma += >> - (*luma_grain_block)[luma_coord_y][luma_coord_x]; >> + coeffs->luma_grain_block[luma_coord_y][luma_coord_x]; >>                   av_luma += >> - (*luma_grain_block)[luma_coord_y][luma_coord_x + 1]; >> + coeffs->luma_grain_block[luma_coord_y][luma_coord_x + 1]; >>                   av_luma += >> -                    (*luma_grain_block)[luma_coord_y + >> 1][luma_coord_x]; >> +                    coeffs->luma_grain_block[luma_coord_y + >> 1][luma_coord_x]; >>                   av_luma += >> -                    (*luma_grain_block)[(luma_coord_y + >> 1)][luma_coord_x + 1]; >> +                    coeffs->luma_grain_block[(luma_coord_y + >> 1)][luma_coord_x + 1]; >>                   av_luma = round_power_of_two(av_luma, 2); >>   -                wsum_cb = wsum_cb + (*ar_coeffs_cb)[pos] * av_luma; >> -                wsum_cr = wsum_cr + (*ar_coeffs_cr)[pos] * av_luma; >> +                wsum_cb = wsum_cb + coeffs->ar_coeffs_cb[pos] * >> av_luma; >> +                wsum_cr = wsum_cr + coeffs->ar_coeffs_cr[pos] * >> av_luma; >>               } >>                 if (num_cb_points || chroma_scaling_from_luma) { >> -                (*cb_grain_block)[i][j] = >> -                    clamp((*cb_grain_block)[i][j] + >> +                coeffs->cb_grain_block[i][j] = >> +                    clamp(coeffs->cb_grain_block[i][j] + >>                         round_power_of_two(wsum_cb, ar_coeff_shift), >>                         grain_min, grain_max); >>               } >>               if (num_cr_points || chroma_scaling_from_luma) { >> -                (*cr_grain_block)[i][j] = >> -                    clamp((*cr_grain_block)[i][j] + >> +                coeffs->cr_grain_block[i][j] = >> +                    clamp(coeffs->cr_grain_block[i][j] + >>                         round_power_of_two(wsum_cr, ar_coeff_shift), >>                         grain_min, grain_max); >>               } >> diff --git >> a/drivers/media/platform/verisilicon/hantro_av1_filmgrain.h >> b/drivers/media/platform/verisilicon/hantro_av1_filmgrain.h >> new file mode 100644 >> index 000000000000..d80be7c011a0 >> --- /dev/null >> +++ b/drivers/media/platform/verisilicon/hantro_av1_filmgrain.h >> @@ -0,0 +1,48 @@ >> +/* SPDX-License-Identifier: GPL-2.0-only */ >> + >> +#ifndef _HANTRO_AV1_FILMGRAIN_H_ >> +#define _HANTRO_AV1_FILMGRAIN_H_ >> + >> +#include >> + >> +struct hantro_av1_film_grain { >> +    u8 scaling_lut_y[256]; >> +    u8 scaling_lut_cb[256]; >> +    u8 scaling_lut_cr[256]; >> +    s16 cropped_luma_grain_block[4096]; >> +    s16 cropped_chroma_grain_block[1024 * 2]; >> +}; >> + >> +struct hantro_av1_coeffs_grain_block { >> +    s32 ar_coeffs_y[24]; >> +    s32 ar_coeffs_cb[25]; >> +    s32 ar_coeffs_cr[25]; >> +    s32 luma_grain_block[73][82]; >> +    s32 cb_grain_block[38][44]; >> +    s32 cr_grain_block[38][44]; >> +}; >> + >> +void hantro_av1_generate_luma_grain_block(struct >> hantro_av1_coeffs_grain_block *coeffs, >> +                      s32 bitdepth, >> +                      u8 num_y_points, >> +                      s32 grain_scale_shift, >> +                      s32 ar_coeff_lag, >> +                      s32 ar_coeff_shift, >> +                      s32 grain_min, >> +                      s32 grain_max, >> +                      u16 random_seed); >> + >> +void hantro_av1_generate_chroma_grain_block(struct >> hantro_av1_coeffs_grain_block *coeffs, >> +                        s32 bitdepth, >> +                        u8 num_y_points, >> +                        u8 num_cb_points, >> +                        u8 num_cr_points, >> +                        s32 grain_scale_shift, >> +                        s32 ar_coeff_lag, >> +                        s32 ar_coeff_shift, >> +                        s32 grain_min, >> +                        s32 grain_max, >> +                        u8 chroma_scaling_from_luma, >> +                        u16 random_seed); >> + >> +#endif >> diff --git a/drivers/media/platform/verisilicon/hantro_hw.h >> b/drivers/media/platform/verisilicon/hantro_hw.h >> index 5f2011529f02..d1d39d1df5d2 100644 >> --- a/drivers/media/platform/verisilicon/hantro_hw.h >> +++ b/drivers/media/platform/verisilicon/hantro_hw.h >> @@ -15,8 +15,8 @@ >>   #include >>   #include >>   -#include "rockchip_av1_entropymode.h" >> -#include "rockchip_av1_filmgrain.h" >> +#include "hantro_av1_entropymode.h" >> +#include "hantro_av1_filmgrain.h" >>     #define DEC_8190_ALIGN_MASK    0x07U >>   @@ -459,10 +459,7 @@ void hantro_hevc_ref_init(struct hantro_ctx >> *ctx); >>   dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, s32 poc); >>   int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, >> dma_addr_t addr); >>   -int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx); >> -void rockchip_vpu981_av1_dec_exit(struct hantro_ctx *ctx); >>   int rockchip_vpu981_av1_dec_run(struct hantro_ctx *ctx); >> -void rockchip_vpu981_av1_dec_done(struct hantro_ctx *ctx); >>     static inline unsigned short hantro_vp9_num_sbs(unsigned short >> dimension) >>   { >> diff --git >> a/drivers/media/platform/verisilicon/rockchip_av1_filmgrain.h >> b/drivers/media/platform/verisilicon/rockchip_av1_filmgrain.h >> deleted file mode 100644 >> index 31a8b7920c31..000000000000 >> --- a/drivers/media/platform/verisilicon/rockchip_av1_filmgrain.h >> +++ /dev/null >> @@ -1,36 +0,0 @@ >> -/* SPDX-License-Identifier: GPL-2.0-only */ >> - >> -#ifndef _ROCKCHIP_AV1_FILMGRAIN_H_ >> -#define _ROCKCHIP_AV1_FILMGRAIN_H_ >> - >> -#include >> - >> -void rockchip_av1_generate_luma_grain_block(s32 >> (*luma_grain_block)[73][82], >> -                        s32 bitdepth, >> -                        u8 num_y_points, >> -                        s32 grain_scale_shift, >> -                        s32 ar_coeff_lag, >> -                        s32 (*ar_coeffs_y)[24], >> -                        s32 ar_coeff_shift, >> -                        s32 grain_min, >> -                        s32 grain_max, >> -                        u16 random_seed); >> - >> -void rockchip_av1_generate_chroma_grain_block(s32 >> (*luma_grain_block)[73][82], >> -                          s32 (*cb_grain_block)[38][44], >> -                          s32 (*cr_grain_block)[38][44], >> -                          s32 bitdepth, >> -                          u8 num_y_points, >> -                          u8 num_cb_points, >> -                          u8 num_cr_points, >> -                          s32 grain_scale_shift, >> -                          s32 ar_coeff_lag, >> -                          s32 (*ar_coeffs_cb)[25], >> -                          s32 (*ar_coeffs_cr)[25], >> -                          s32 ar_coeff_shift, >> -                          s32 grain_min, >> -                          s32 grain_max, >> -                          u8 chroma_scaling_from_luma, >> -                          u16 random_seed); >> - >> -#endif >> diff --git >> a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c >> b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c >> index e4e21ad37323..61e30338422d 100644 >> --- a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c >> +++ b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c >> @@ -7,622 +7,35 @@ >>     #include >>   #include "hantro.h" >> +#include "hantro_av1.h" >>   #include "hantro_v4l2.h" >>   #include "rockchip_vpu981_regs.h" >>     #define AV1_DEC_MODE        17 >> -#define GM_GLOBAL_MODELS_PER_FRAME    7 >> -#define GLOBAL_MODEL_TOTAL_SIZE    (6 * 4 + 4 * 2) >> -#define GLOBAL_MODEL_SIZE    ALIGN(GM_GLOBAL_MODELS_PER_FRAME * >> GLOBAL_MODEL_TOTAL_SIZE, 2048) >> -#define AV1_MAX_TILES        128 >> -#define AV1_TILE_INFO_SIZE    (AV1_MAX_TILES * 16) >> -#define AV1DEC_MAX_PIC_BUFFERS    24 >> -#define AV1_REF_SCALE_SHIFT    14 >> -#define AV1_INVALID_IDX        -1 >> -#define MAX_FRAME_DISTANCE    31 >> -#define AV1_PRIMARY_REF_NONE    7 >> -#define AV1_TILE_SIZE        ALIGN(32 * 128, 4096) >> -/* >> - * These 3 values aren't defined enum v4l2_av1_segment_feature because >> - * they are not part of the specification >> - */ >> -#define V4L2_AV1_SEG_LVL_ALT_LF_Y_H    2 >> -#define V4L2_AV1_SEG_LVL_ALT_LF_U    3 >> -#define V4L2_AV1_SEG_LVL_ALT_LF_V    4 >> - >> -#define SUPERRES_SCALE_BITS 3 >> -#define SCALE_NUMERATOR 8 >> -#define SUPERRES_SCALE_DENOMINATOR_MIN (SCALE_NUMERATOR + 1) >> - >> -#define RS_SUBPEL_BITS 6 >> -#define RS_SUBPEL_MASK ((1 << RS_SUBPEL_BITS) - 1) >> -#define RS_SCALE_SUBPEL_BITS 14 >> -#define RS_SCALE_SUBPEL_MASK ((1 << RS_SCALE_SUBPEL_BITS) - 1) >> -#define RS_SCALE_EXTRA_BITS (RS_SCALE_SUBPEL_BITS - RS_SUBPEL_BITS) >> -#define RS_SCALE_EXTRA_OFF (1 << (RS_SCALE_EXTRA_BITS - 1)) >> - >> -#define IS_INTRA(type) ((type == V4L2_AV1_KEY_FRAME) || (type == >> V4L2_AV1_INTRA_ONLY_FRAME)) >> - >> -#define LST_BUF_IDX (V4L2_AV1_REF_LAST_FRAME - V4L2_AV1_REF_LAST_FRAME) >> -#define LST2_BUF_IDX (V4L2_AV1_REF_LAST2_FRAME - >> V4L2_AV1_REF_LAST_FRAME) >> -#define LST3_BUF_IDX (V4L2_AV1_REF_LAST3_FRAME - >> V4L2_AV1_REF_LAST_FRAME) >> -#define GLD_BUF_IDX (V4L2_AV1_REF_GOLDEN_FRAME - >> V4L2_AV1_REF_LAST_FRAME) >> -#define BWD_BUF_IDX (V4L2_AV1_REF_BWDREF_FRAME - >> V4L2_AV1_REF_LAST_FRAME) >> -#define ALT2_BUF_IDX (V4L2_AV1_REF_ALTREF2_FRAME - >> V4L2_AV1_REF_LAST_FRAME) >> -#define ALT_BUF_IDX (V4L2_AV1_REF_ALTREF_FRAME - >> V4L2_AV1_REF_LAST_FRAME) >> - >> -#define DIV_LUT_PREC_BITS 14 >> -#define DIV_LUT_BITS 8 >> -#define DIV_LUT_NUM BIT(DIV_LUT_BITS) >> -#define WARP_PARAM_REDUCE_BITS 6 >> -#define WARPEDMODEL_PREC_BITS 16 >> - >> -#define AV1_DIV_ROUND_UP_POW2(value, n)            \ >> -({                            \ >> -    typeof(n) _n  = n;                \ >> -    typeof(value) _value = value;            \ >> -    (_value + (BIT(_n) >> 1)) >> _n;        \ >> -}) >> - >> -#define AV1_DIV_ROUND_UP_POW2_SIGNED(value, n)                \ >> -({                                    \ >> -    typeof(n) _n_  = n;                        \ >> -    typeof(value) _value_ = value;                    \ >> -    (((_value_) < 0) ? -AV1_DIV_ROUND_UP_POW2(-(_value_), (_n_))    \ >> -        : AV1_DIV_ROUND_UP_POW2((_value_), (_n_)));        \ >> -}) >> - >> -enum rockchip_av1_tx_mode { >> -    ROCKCHIP_AV1_TX_MODE_ONLY_4X4    = 0, >> -    ROCKCHIP_AV1_TX_MODE_8X8    = 1, >> -    ROCKCHIP_AV1_TX_MODE_16x16    = 2, >> -    ROCKCHIP_AV1_TX_MODE_32x32    = 3, >> -    ROCKCHIP_AV1_TX_MODE_SELECT    = 4, >> -}; >> - >> -struct rockchip_av1_film_grain { >> -    u8 scaling_lut_y[256]; >> -    u8 scaling_lut_cb[256]; >> -    u8 scaling_lut_cr[256]; >> -    s16 cropped_luma_grain_block[4096]; >> -    s16 cropped_chroma_grain_block[1024 * 2]; >> -}; >> - >> -static const short div_lut[DIV_LUT_NUM + 1] = { >> -    16384, 16320, 16257, 16194, 16132, 16070, 16009, 15948, 15888, >> 15828, 15768, >> -    15709, 15650, 15592, 15534, 15477, 15420, 15364, 15308, 15252, >> 15197, 15142, >> -    15087, 15033, 14980, 14926, 14873, 14821, 14769, 14717, 14665, >> 14614, 14564, >> -    14513, 14463, 14413, 14364, 14315, 14266, 14218, 14170, 14122, >> 14075, 14028, >> -    13981, 13935, 13888, 13843, 13797, 13752, 13707, 13662, 13618, >> 13574, 13530, >> -    13487, 13443, 13400, 13358, 13315, 13273, 13231, 13190, 13148, >> 13107, 13066, >> -    13026, 12985, 12945, 12906, 12866, 12827, 12788, 12749, 12710, >> 12672, 12633, >> -    12596, 12558, 12520, 12483, 12446, 12409, 12373, 12336, 12300, >> 12264, 12228, >> -    12193, 12157, 12122, 12087, 12053, 12018, 11984, 11950, 11916, >> 11882, 11848, >> -    11815, 11782, 11749, 11716, 11683, 11651, 11619, 11586, 11555, >> 11523, 11491, >> -    11460, 11429, 11398, 11367, 11336, 11305, 11275, 11245, 11215, >> 11185, 11155, >> -    11125, 11096, 11067, 11038, 11009, 10980, 10951, 10923, 10894, >> 10866, 10838, >> -    10810, 10782, 10755, 10727, 10700, 10673, 10645, 10618, 10592, >> 10565, 10538, >> -    10512, 10486, 10460, 10434, 10408, 10382, 10356, 10331, 10305, >> 10280, 10255, >> -    10230, 10205, 10180, 10156, 10131, 10107, 10082, 10058, 10034, >> 10010, 9986, >> -    9963,  9939,  9916,  9892,  9869,  9846,  9823,  9800, 9777,  >> 9754,  9732, >> -    9709,  9687,  9664,  9642,  9620,  9598,  9576,  9554, 9533,  >> 9511,  9489, >> -    9468,  9447,  9425,  9404,  9383,  9362,  9341,  9321, 9300,  >> 9279,  9259, >> -    9239,  9218,  9198,  9178,  9158,  9138,  9118,  9098, 9079,  >> 9059,  9039, >> -    9020,  9001,  8981,  8962,  8943,  8924,  8905,  8886, 8867,  >> 8849,  8830, >> -    8812,  8793,  8775,  8756,  8738,  8720,  8702,  8684, 8666,  >> 8648,  8630, >> -    8613,  8595,  8577,  8560,  8542,  8525,  8508,  8490, 8473,  >> 8456,  8439, >> -    8422,  8405,  8389,  8372,  8355,  8339,  8322,  8306, 8289,  >> 8273,  8257, >> -    8240,  8224,  8208,  8192, >> -}; >> - >> -static int rockchip_vpu981_get_frame_index(struct hantro_ctx *ctx, >> int ref) >> -{ >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> -    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> -    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> -    u64 timestamp; >> -    int i, idx = frame->ref_frame_idx[ref]; >> - >> -    if (idx >= V4L2_AV1_TOTAL_REFS_PER_FRAME || idx < 0) >> -        return AV1_INVALID_IDX; >> - >> -    timestamp = frame->reference_frame_ts[idx]; >> -    for (i = 0; i < AV1_MAX_FRAME_BUF_COUNT; i++) { >> -        if (!av1_dec->frame_refs[i].used) >> -            continue; >> -        if (av1_dec->frame_refs[i].timestamp == timestamp) >> -            return i; >> -    } >> - >> -    return AV1_INVALID_IDX; >> -} >> - >> -static int rockchip_vpu981_get_order_hint(struct hantro_ctx *ctx, >> int ref) >> -{ >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> -    int idx = rockchip_vpu981_get_frame_index(ctx, ref); >> - >> -    if (idx != AV1_INVALID_IDX) >> -        return av1_dec->frame_refs[idx].order_hint; >> - >> -    return 0; >> -} >> - >> -static int rockchip_vpu981_av1_dec_frame_ref(struct hantro_ctx *ctx, >> -                         u64 timestamp) >> -{ >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> -    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> -    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> -    int i; >> - >> -    for (i = 0; i < AV1_MAX_FRAME_BUF_COUNT; i++) { >> -        int j; >> - >> -        if (av1_dec->frame_refs[i].used) >> -            continue; >> - >> -        av1_dec->frame_refs[i].width = frame->frame_width_minus_1 + 1; >> -        av1_dec->frame_refs[i].height = frame->frame_height_minus_1 >> + 1; >> -        av1_dec->frame_refs[i].mi_cols = >> DIV_ROUND_UP(frame->frame_width_minus_1 + 1, 8); >> -        av1_dec->frame_refs[i].mi_rows = >> DIV_ROUND_UP(frame->frame_height_minus_1 + 1, 8); >> -        av1_dec->frame_refs[i].timestamp = timestamp; >> -        av1_dec->frame_refs[i].frame_type = frame->frame_type; >> -        av1_dec->frame_refs[i].order_hint = frame->order_hint; >> -        av1_dec->frame_refs[i].vb2_ref = hantro_get_dst_buf(ctx); >> - >> -        for (j = 0; j < V4L2_AV1_TOTAL_REFS_PER_FRAME; j++) >> -            av1_dec->frame_refs[i].order_hints[j] = >> frame->order_hints[j]; >> -        av1_dec->frame_refs[i].used = true; >> -        av1_dec->current_frame_index = i; >> - >> -        return i; >> -    } >> - >> -    return AV1_INVALID_IDX; >> -} >> - >> -static void rockchip_vpu981_av1_dec_frame_unref(struct hantro_ctx >> *ctx, int idx) >> -{ >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> - >> -    if (idx >= 0) >> -        av1_dec->frame_refs[idx].used = false; >> -} >> - >> -static void rockchip_vpu981_av1_dec_clean_refs(struct hantro_ctx *ctx) >> -{ >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> -    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> - >> -    int ref, idx; >> - >> -    for (idx = 0; idx < AV1_MAX_FRAME_BUF_COUNT; idx++) { >> -        u64 timestamp = av1_dec->frame_refs[idx].timestamp; >> -        bool used = false; >> - >> -        if (!av1_dec->frame_refs[idx].used) >> -            continue; >> - >> -        for (ref = 0; ref < V4L2_AV1_TOTAL_REFS_PER_FRAME; ref++) { >> -            if (ctrls->frame->reference_frame_ts[ref] == timestamp) >> -                used = true; >> -        } >> - >> -        if (!used) >> -            rockchip_vpu981_av1_dec_frame_unref(ctx, idx); >> -    } >> -} >> - >> -static size_t rockchip_vpu981_av1_dec_luma_size(struct hantro_ctx *ctx) >> -{ >> -    return ctx->dst_fmt.width * ctx->dst_fmt.height * ctx->bit_depth >> / 8; >> -} >> - >> -static size_t rockchip_vpu981_av1_dec_chroma_size(struct hantro_ctx >> *ctx) >> -{ >> -    size_t cr_offset = rockchip_vpu981_av1_dec_luma_size(ctx); >> - >> -    return ALIGN((cr_offset * 3) / 2, 64); >> -} >> - >> -static void rockchip_vpu981_av1_dec_tiles_free(struct hantro_ctx *ctx) >> -{ >> -    struct hantro_dev *vpu = ctx->dev; >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> - >> -    if (av1_dec->db_data_col.cpu) >> -        dma_free_coherent(vpu->dev, av1_dec->db_data_col.size, >> -                  av1_dec->db_data_col.cpu, >> -                  av1_dec->db_data_col.dma); >> -    av1_dec->db_data_col.cpu = NULL; >> - >> -    if (av1_dec->db_ctrl_col.cpu) >> -        dma_free_coherent(vpu->dev, av1_dec->db_ctrl_col.size, >> -                  av1_dec->db_ctrl_col.cpu, >> -                  av1_dec->db_ctrl_col.dma); >> -    av1_dec->db_ctrl_col.cpu = NULL; >> - >> -    if (av1_dec->cdef_col.cpu) >> -        dma_free_coherent(vpu->dev, av1_dec->cdef_col.size, >> -                  av1_dec->cdef_col.cpu, av1_dec->cdef_col.dma); >> -    av1_dec->cdef_col.cpu = NULL; >> - >> -    if (av1_dec->sr_col.cpu) >> -        dma_free_coherent(vpu->dev, av1_dec->sr_col.size, >> -                  av1_dec->sr_col.cpu, av1_dec->sr_col.dma); >> -    av1_dec->sr_col.cpu = NULL; >> - >> -    if (av1_dec->lr_col.cpu) >> -        dma_free_coherent(vpu->dev, av1_dec->lr_col.size, >> -                  av1_dec->lr_col.cpu, av1_dec->lr_col.dma); >> -    av1_dec->lr_col.cpu = NULL; >> -} >> - >> -static int rockchip_vpu981_av1_dec_tiles_reallocate(struct >> hantro_ctx *ctx) >> -{ >> -    struct hantro_dev *vpu = ctx->dev; >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> -    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> -    const struct v4l2_av1_tile_info *tile_info = >> &ctrls->frame->tile_info; >> -    unsigned int num_tile_cols = tile_info->tile_cols; >> -    unsigned int height = ALIGN(ctrls->frame->frame_height_minus_1 + >> 1, 64); >> -    unsigned int height_in_sb = height / 64; >> -    unsigned int stripe_num = ((height + 8) + 63) / 64; >> -    size_t size; >> - >> -    if (av1_dec->db_data_col.size >= >> -        ALIGN(height * 12 * ctx->bit_depth / 8, 128) * num_tile_cols) >> -        return 0; >> - >> -    rockchip_vpu981_av1_dec_tiles_free(ctx); >> - >> -    size = ALIGN(height * 12 * ctx->bit_depth / 8, 128) * >> num_tile_cols; >> -    av1_dec->db_data_col.cpu = dma_alloc_coherent(vpu->dev, size, >> -                              &av1_dec->db_data_col.dma, >> -                              GFP_KERNEL); >> -    if (!av1_dec->db_data_col.cpu) >> -        goto buffer_allocation_error; >> -    av1_dec->db_data_col.size = size; >> - >> -    size = ALIGN(height * 2 * 16 / 4, 128) * num_tile_cols; >> -    av1_dec->db_ctrl_col.cpu = dma_alloc_coherent(vpu->dev, size, >> -                              &av1_dec->db_ctrl_col.dma, >> -                              GFP_KERNEL); >> -    if (!av1_dec->db_ctrl_col.cpu) >> -        goto buffer_allocation_error; >> -    av1_dec->db_ctrl_col.size = size; >> - >> -    size = ALIGN(height_in_sb * 44 * ctx->bit_depth * 16 / 8, 128) * >> num_tile_cols; >> -    av1_dec->cdef_col.cpu = dma_alloc_coherent(vpu->dev, size, >> -                           &av1_dec->cdef_col.dma, >> -                           GFP_KERNEL); >> -    if (!av1_dec->cdef_col.cpu) >> -        goto buffer_allocation_error; >> -    av1_dec->cdef_col.size = size; >> - >> -    size = ALIGN(height_in_sb * (3040 + 1280), 128) * num_tile_cols; >> -    av1_dec->sr_col.cpu = dma_alloc_coherent(vpu->dev, size, >> -                         &av1_dec->sr_col.dma, >> -                         GFP_KERNEL); >> -    if (!av1_dec->sr_col.cpu) >> -        goto buffer_allocation_error; >> -    av1_dec->sr_col.size = size; >> - >> -    size = ALIGN(stripe_num * 1536 * ctx->bit_depth / 8, 128) * >> num_tile_cols; >> -    av1_dec->lr_col.cpu = dma_alloc_coherent(vpu->dev, size, >> -                         &av1_dec->lr_col.dma, >> -                         GFP_KERNEL); >> -    if (!av1_dec->lr_col.cpu) >> -        goto buffer_allocation_error; >> -    av1_dec->lr_col.size = size; >> - >> -    av1_dec->num_tile_cols_allocated = num_tile_cols; >> -    return 0; >> - >> -buffer_allocation_error: >> -    rockchip_vpu981_av1_dec_tiles_free(ctx); >> -    return -ENOMEM; >> -} >> - >> -void rockchip_vpu981_av1_dec_exit(struct hantro_ctx *ctx) >> -{ >> -    struct hantro_dev *vpu = ctx->dev; >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> - >> -    if (av1_dec->global_model.cpu) >> -        dma_free_coherent(vpu->dev, av1_dec->global_model.size, >> -                  av1_dec->global_model.cpu, >> -                  av1_dec->global_model.dma); >> -    av1_dec->global_model.cpu = NULL; >> - >> -    if (av1_dec->tile_info.cpu) >> -        dma_free_coherent(vpu->dev, av1_dec->tile_info.size, >> -                  av1_dec->tile_info.cpu, >> -                  av1_dec->tile_info.dma); >> -    av1_dec->tile_info.cpu = NULL; >> - >> -    if (av1_dec->film_grain.cpu) >> -        dma_free_coherent(vpu->dev, av1_dec->film_grain.size, >> -                  av1_dec->film_grain.cpu, >> -                  av1_dec->film_grain.dma); >> -    av1_dec->film_grain.cpu = NULL; >> - >> -    if (av1_dec->prob_tbl.cpu) >> -        dma_free_coherent(vpu->dev, av1_dec->prob_tbl.size, >> -                  av1_dec->prob_tbl.cpu, av1_dec->prob_tbl.dma); >> -    av1_dec->prob_tbl.cpu = NULL; >> - >> -    if (av1_dec->prob_tbl_out.cpu) >> -        dma_free_coherent(vpu->dev, av1_dec->prob_tbl_out.size, >> -                  av1_dec->prob_tbl_out.cpu, >> -                  av1_dec->prob_tbl_out.dma); >> -    av1_dec->prob_tbl_out.cpu = NULL; >> - >> -    if (av1_dec->tile_buf.cpu) >> -        dma_free_coherent(vpu->dev, av1_dec->tile_buf.size, >> -                  av1_dec->tile_buf.cpu, av1_dec->tile_buf.dma); >> -    av1_dec->tile_buf.cpu = NULL; >> - >> -    rockchip_vpu981_av1_dec_tiles_free(ctx); >> -} >> - >> -int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx) >> -{ >> -    struct hantro_dev *vpu = ctx->dev; >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> - >> -    memset(av1_dec, 0, sizeof(*av1_dec)); >> - >> -    av1_dec->global_model.cpu = dma_alloc_coherent(vpu->dev, >> GLOBAL_MODEL_SIZE, >> - &av1_dec->global_model.dma, >> -                               GFP_KERNEL); >> -    if (!av1_dec->global_model.cpu) >> -        return -ENOMEM; >> -    av1_dec->global_model.size = GLOBAL_MODEL_SIZE; >> - >> -    av1_dec->tile_info.cpu = dma_alloc_coherent(vpu->dev, >> AV1_TILE_INFO_SIZE, >> -                            &av1_dec->tile_info.dma, >> -                            GFP_KERNEL); >> -    if (!av1_dec->tile_info.cpu) >> -        return -ENOMEM; >> -    av1_dec->tile_info.size = AV1_TILE_INFO_SIZE; >> - >> -    av1_dec->film_grain.cpu = dma_alloc_coherent(vpu->dev, >> -                             ALIGN(sizeof(struct >> rockchip_av1_film_grain), 2048), >> -                             &av1_dec->film_grain.dma, >> -                             GFP_KERNEL); >> -    if (!av1_dec->film_grain.cpu) >> -        return -ENOMEM; >> -    av1_dec->film_grain.size = ALIGN(sizeof(struct >> rockchip_av1_film_grain), 2048); >> - >> -    av1_dec->prob_tbl.cpu = dma_alloc_coherent(vpu->dev, >> -                           ALIGN(sizeof(struct av1cdfs), 2048), >> -                           &av1_dec->prob_tbl.dma, >> -                           GFP_KERNEL); >> -    if (!av1_dec->prob_tbl.cpu) >> -        return -ENOMEM; >> -    av1_dec->prob_tbl.size = ALIGN(sizeof(struct av1cdfs), 2048); >> - >> -    av1_dec->prob_tbl_out.cpu = dma_alloc_coherent(vpu->dev, >> -                               ALIGN(sizeof(struct av1cdfs), 2048), >> - &av1_dec->prob_tbl_out.dma, >> -                               GFP_KERNEL); >> -    if (!av1_dec->prob_tbl_out.cpu) >> -        return -ENOMEM; >> -    av1_dec->prob_tbl_out.size = ALIGN(sizeof(struct av1cdfs), 2048); >> -    av1_dec->cdfs = &av1_dec->default_cdfs; >> -    av1_dec->cdfs_ndvc = &av1_dec->default_cdfs_ndvc; >> - >> -    rockchip_av1_set_default_cdfs(av1_dec->cdfs, av1_dec->cdfs_ndvc); >> - >> -    av1_dec->tile_buf.cpu = dma_alloc_coherent(vpu->dev, >> -                           AV1_TILE_SIZE, >> -                           &av1_dec->tile_buf.dma, >> -                           GFP_KERNEL); >> -    if (!av1_dec->tile_buf.cpu) >> -        return -ENOMEM; >> -    av1_dec->tile_buf.size = AV1_TILE_SIZE; >> - >> -    return 0; >> -} >> - >> -static int rockchip_vpu981_av1_dec_prepare_run(struct hantro_ctx *ctx) >> -{ >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> -    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> - >> -    ctrls->sequence = hantro_get_ctrl(ctx, >> V4L2_CID_STATELESS_AV1_SEQUENCE); >> -    if (WARN_ON(!ctrls->sequence)) >> -        return -EINVAL; >> - >> -    ctrls->tile_group_entry = >> -        hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY); >> -    if (WARN_ON(!ctrls->tile_group_entry)) >> -        return -EINVAL; >> - >> -    ctrls->frame = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_FRAME); >> -    if (WARN_ON(!ctrls->frame)) >> -        return -EINVAL; >> - >> -    ctrls->film_grain = >> -        hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_FILM_GRAIN); >> - >> -    return rockchip_vpu981_av1_dec_tiles_reallocate(ctx); >> -} >> - >> -static inline int rockchip_vpu981_av1_dec_get_msb(u32 n) >> -{ >> -    if (n == 0) >> -        return 0; >> -    return 31 ^ __builtin_clz(n); >> -} >> - >> -static short rockchip_vpu981_av1_dec_resolve_divisor_32(u32 d, short >> *shift) >> -{ >> -    int f; >> -    u64 e; >> - >> -    *shift = rockchip_vpu981_av1_dec_get_msb(d); >> -    /* e is obtained from D after resetting the most significant 1 >> bit. */ >> -    e = d - ((u32)1 << *shift); >> -    /* Get the most significant DIV_LUT_BITS (8) bits of e into f */ >> -    if (*shift > DIV_LUT_BITS) >> -        f = AV1_DIV_ROUND_UP_POW2(e, *shift - DIV_LUT_BITS); >> -    else >> -        f = e << (DIV_LUT_BITS - *shift); >> -    if (f > DIV_LUT_NUM) >> -        return -1; >> -    *shift += DIV_LUT_PREC_BITS; >> -    /* Use f as lookup into the precomputed table of multipliers */ >> -    return div_lut[f]; >> -} >> - >> -static void >> -rockchip_vpu981_av1_dec_get_shear_params(const u32 *params, s64 *alpha, >> -                     s64 *beta, s64 *gamma, s64 *delta) >> -{ >> -    const int *mat = params; >> -    short shift; >> -    short y; >> -    long long gv, dv; >> - >> -    if (mat[2] <= 0) >> -        return; >> - >> -    *alpha = clamp_val(mat[2] - (1 << WARPEDMODEL_PREC_BITS), >> S16_MIN, S16_MAX); >> -    *beta = clamp_val(mat[3], S16_MIN, S16_MAX); >> - >> -    y = rockchip_vpu981_av1_dec_resolve_divisor_32(abs(mat[2]), >> &shift) * (mat[2] < 0 ? -1 : 1); >> - >> -    gv = ((long long)mat[4] * (1 << WARPEDMODEL_PREC_BITS)) * y; >> - >> -    *gamma = clamp_val((int)AV1_DIV_ROUND_UP_POW2_SIGNED(gv, shift), >> S16_MIN, S16_MAX); >> - >> -    dv = ((long long)mat[3] * mat[4]) * y; >> -    *delta = clamp_val(mat[5] - >> -        (int)AV1_DIV_ROUND_UP_POW2_SIGNED(dv, shift) - (1 << >> WARPEDMODEL_PREC_BITS), >> -        S16_MIN, S16_MAX); >> - >> -    *alpha = AV1_DIV_ROUND_UP_POW2_SIGNED(*alpha, >> WARP_PARAM_REDUCE_BITS) >> -         * (1 << WARP_PARAM_REDUCE_BITS); >> -    *beta = AV1_DIV_ROUND_UP_POW2_SIGNED(*beta, WARP_PARAM_REDUCE_BITS) >> -        * (1 << WARP_PARAM_REDUCE_BITS); >> -    *gamma = AV1_DIV_ROUND_UP_POW2_SIGNED(*gamma, >> WARP_PARAM_REDUCE_BITS) >> -         * (1 << WARP_PARAM_REDUCE_BITS); >> -    *delta = AV1_DIV_ROUND_UP_POW2_SIGNED(*delta, >> WARP_PARAM_REDUCE_BITS) >> -        * (1 << WARP_PARAM_REDUCE_BITS); >> -} >>     static void rockchip_vpu981_av1_dec_set_global_model(struct >> hantro_ctx *ctx) >>   { >>       struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> -    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> -    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> -    const struct v4l2_av1_global_motion *gm = &frame->global_motion; >> -    u8 *dst = av1_dec->global_model.cpu; >>       struct hantro_dev *vpu = ctx->dev; >> -    int ref_frame, i; >> - >> -    memset(dst, 0, GLOBAL_MODEL_SIZE); >> -    for (ref_frame = 0; ref_frame < V4L2_AV1_REFS_PER_FRAME; >> ++ref_frame) { >> -        s64 alpha = 0, beta = 0, gamma = 0, delta = 0; >> - >> -        for (i = 0; i < 6; ++i) { >> -            if (i == 2) >> -                *(s32 *)dst = >> -                    gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][3]; >> -            else if (i == 3) >> -                *(s32 *)dst = >> -                    gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][2]; >> -            else >> -                *(s32 *)dst = >> -                    gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][i]; >> -            dst += 4; >> -        } >> - >> -        if (gm->type[V4L2_AV1_REF_LAST_FRAME + ref_frame] <= >> V4L2_AV1_WARP_MODEL_AFFINE) >> - >> rockchip_vpu981_av1_dec_get_shear_params(&gm->params[V4L2_AV1_REF_LAST_FRAME >> + ref_frame][0], >> -                                 &alpha, &beta, &gamma, &delta); >> - >> -        *(s16 *)dst = alpha; >> -        dst += 2; >> -        *(s16 *)dst = beta; >> -        dst += 2; >> -        *(s16 *)dst = gamma; >> -        dst += 2; >> -        *(s16 *)dst = delta; >> -        dst += 2; >> -    } >>   +    hantro_av1_set_global_model(ctx); >>       hantro_write_addr(vpu, AV1_GLOBAL_MODEL, >> av1_dec->global_model.dma); >>   } >>   -static int rockchip_vpu981_av1_tile_log2(int target) >> -{ >> -    int k; >> - >> -    /* >> -     * returns the smallest value for k such that 1 << k is greater >> -     * than or equal to target >> -     */ >> -    for (k = 0; (1 << k) < target; k++); >> - >> -    return k; >> -} >> - >>   static void rockchip_vpu981_av1_dec_set_tile_info(struct hantro_ctx >> *ctx) >>   { >>       struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >>       struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >>       const struct v4l2_av1_tile_info *tile_info = >> &ctrls->frame->tile_info; >> -    const struct v4l2_ctrl_av1_tile_group_entry *group_entry = >> -        ctrls->tile_group_entry; >>       int context_update_y = >>           tile_info->context_update_tile_id / tile_info->tile_cols; >>       int context_update_x = >>           tile_info->context_update_tile_id % tile_info->tile_cols; >>       int context_update_tile_id = >>           context_update_x * tile_info->tile_rows + context_update_y; >> -    u8 *dst = av1_dec->tile_info.cpu; >>       struct hantro_dev *vpu = ctx->dev; >> -    int tile0, tile1; >> - >> -    memset(dst, 0, av1_dec->tile_info.size); >> - >> -    for (tile0 = 0; tile0 < tile_info->tile_cols; tile0++) { >> -        for (tile1 = 0; tile1 < tile_info->tile_rows; tile1++) { >> -            int tile_id = tile1 * tile_info->tile_cols + tile0; >> -            u32 start, end; >> -            u32 y0 = >> -                tile_info->height_in_sbs_minus_1[tile1] + 1; >> -            u32 x0 = tile_info->width_in_sbs_minus_1[tile0] + 1; >> - >> -            /* tile size in SB units (width,height) */ >> -            *dst++ = x0; >> -            *dst++ = 0; >> -            *dst++ = 0; >> -            *dst++ = 0; >> -            *dst++ = y0; >> -            *dst++ = 0; >> -            *dst++ = 0; >> -            *dst++ = 0; >> - >> -            /* tile start position */ >> -            start = group_entry[tile_id].tile_offset - >> group_entry[0].tile_offset; >> -            *dst++ = start & 255; >> -            *dst++ = (start >> 8) & 255; >> -            *dst++ = (start >> 16) & 255; >> -            *dst++ = (start >> 24) & 255; >> - >> -            /* number of bytes in tile data */ >> -            end = start + group_entry[tile_id].tile_size; >> -            *dst++ = end & 255; >> -            *dst++ = (end >> 8) & 255; >> -            *dst++ = (end >> 16) & 255; >> -            *dst++ = (end >> 24) & 255; >> -        } >> -    } >> + >> +    hantro_av1_set_tile_info(ctx); >>         hantro_reg_write(vpu, &av1_multicore_expect_context_update, >> !!(context_update_x == 0)); >>       hantro_reg_write(vpu, &av1_tile_enable, >> @@ -631,8 +44,8 @@ static void >> rockchip_vpu981_av1_dec_set_tile_info(struct hantro_ctx *ctx) >>       hantro_reg_write(vpu, &av1_num_tile_rows_8k, >> tile_info->tile_rows); >>       hantro_reg_write(vpu, &av1_context_update_tile_id, >> context_update_tile_id); >>       hantro_reg_write(vpu, &av1_tile_transpose, 1); >> -    if (rockchip_vpu981_av1_tile_log2(tile_info->tile_cols) || >> -        rockchip_vpu981_av1_tile_log2(tile_info->tile_rows)) >> +    if (hantro_av1_tile_log2(tile_info->tile_cols) || >> +        hantro_av1_tile_log2(tile_info->tile_rows)) >>           hantro_reg_write(vpu, &av1_dec_tile_size_mag, >> tile_info->tile_size_bytes - 1); >>       else >>           hantro_reg_write(vpu, &av1_dec_tile_size_mag, 3); >> @@ -640,50 +53,6 @@ static void >> rockchip_vpu981_av1_dec_set_tile_info(struct hantro_ctx *ctx) >>       hantro_write_addr(vpu, AV1_TILE_BASE, av1_dec->tile_info.dma); >>   } >>   -static int rockchip_vpu981_av1_dec_get_dist(struct hantro_ctx *ctx, >> -                        int a, int b) >> -{ >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> -    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> -    int bits = ctrls->sequence->order_hint_bits - 1; >> -    int diff, m; >> - >> -    if (!ctrls->sequence->order_hint_bits) >> -        return 0; >> - >> -    diff = a - b; >> -    m = 1 << bits; >> -    diff = (diff & (m - 1)) - (diff & m); >> - >> -    return diff; >> -} >> - >> -static void rockchip_vpu981_av1_dec_set_frame_sign_bias(struct >> hantro_ctx *ctx) >> -{ >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> -    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> -    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> -    const struct v4l2_ctrl_av1_sequence *sequence = ctrls->sequence; >> -    int i; >> - >> -    if (!sequence->order_hint_bits || IS_INTRA(frame->frame_type)) { >> -        for (i = 0; i < V4L2_AV1_TOTAL_REFS_PER_FRAME; i++) >> -            av1_dec->ref_frame_sign_bias[i] = 0; >> - >> -        return; >> -    } >> -    // Identify the nearest forward and backward references. >> -    for (i = 0; i < V4L2_AV1_TOTAL_REFS_PER_FRAME - 1; i++) { >> -        if (rockchip_vpu981_get_frame_index(ctx, i) >= 0) { >> -            int rel_off = >> -                rockchip_vpu981_av1_dec_get_dist(ctx, >> - rockchip_vpu981_get_order_hint(ctx, i), >> -                                 frame->order_hint); >> -            av1_dec->ref_frame_sign_bias[i + 1] = (rel_off <= 0) ? 0 >> : 1; >> -        } >> -    } >> -} >> - >>   static bool >>   rockchip_vpu981_av1_dec_set_ref(struct hantro_ctx *ctx, int ref, >> int idx, >>                   int width, int height) >> @@ -806,12 +175,12 @@ static void >> rockchip_vpu981_av1_dec_set_segmentation(struct hantro_ctx *ctx) >>         if (!!(seg->flags & V4L2_AV1_SEGMENTATION_FLAG_ENABLED) && >>           frame->primary_ref_frame < V4L2_AV1_REFS_PER_FRAME) { >> -        int idx = rockchip_vpu981_get_frame_index(ctx, >> frame->primary_ref_frame); >> +        int idx = hantro_av1_get_frame_index(ctx, >> frame->primary_ref_frame); >>   -        if (idx >= 0) { >> +        if (idx != AV1_INVALID_IDX) { >>               dma_addr_t luma_addr, mv_addr = 0; >>               struct hantro_decoded_buffer *seg; >> -            size_t mv_offset = >> rockchip_vpu981_av1_dec_chroma_size(ctx); >> +            size_t mv_offset = hantro_av1_chroma_size(ctx); >>                 seg = >> vb2_to_hantro_decoded_buf(&av1_dec->frame_refs[idx].vb2_ref->vb2_buf); >>               luma_addr = hantro_get_dec_buf_addr(ctx, >> &seg->base.vb.vb2_buf); >> @@ -1041,35 +410,6 @@ static void >> rockchip_vpu981_av1_dec_set_segmentation(struct hantro_ctx *ctx) >>                segval[7][V4L2_AV1_SEG_LVL_REF_GLOBALMV]); >>   } >>   -static bool rockchip_vpu981_av1_dec_is_lossless(struct hantro_ctx >> *ctx) >> -{ >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> -    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> -    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> -    const struct v4l2_av1_segmentation *segmentation = >> &frame->segmentation; >> -    const struct v4l2_av1_quantization *quantization = >> &frame->quantization; >> -    int i; >> - >> -    for (i = 0; i < V4L2_AV1_MAX_SEGMENTS; i++) { >> -        int qindex = quantization->base_q_idx; >> - >> -        if (segmentation->feature_enabled[i] & >> - V4L2_AV1_SEGMENT_FEATURE_ENABLED(V4L2_AV1_SEG_LVL_ALT_Q)) { >> -            qindex += >> segmentation->feature_data[i][V4L2_AV1_SEG_LVL_ALT_Q]; >> -        } >> -        qindex = clamp(qindex, 0, 255); >> - >> -        if (qindex || >> -            quantization->delta_q_y_dc || >> -            quantization->delta_q_u_dc || >> -            quantization->delta_q_u_ac || >> -            quantization->delta_q_v_dc || >> -            quantization->delta_q_v_ac) >> -            return false; >> -    } >> -    return true; >> -} >> - >>   static void rockchip_vpu981_av1_dec_set_loopfilter(struct >> hantro_ctx *ctx) >>   { >>       struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> @@ -1089,7 +429,7 @@ static void >> rockchip_vpu981_av1_dec_set_loopfilter(struct hantro_ctx *ctx) >>       hantro_reg_write(vpu, &av1_filt_level3, loop_filter->level[3]); >>         if (loop_filter->flags & >> V4L2_AV1_LOOP_FILTER_FLAG_DELTA_ENABLED && >> -        !rockchip_vpu981_av1_dec_is_lossless(ctx) && >> +        !hantro_av1_is_lossless(ctx) && >>           !(frame->flags & V4L2_AV1_FRAME_FLAG_ALLOW_INTRABC)) { >>           hantro_reg_write(vpu, &av1_filt_ref_adj_0, >>                    loop_filter->ref_deltas[0]); >> @@ -1128,121 +468,27 @@ static void >> rockchip_vpu981_av1_dec_set_loopfilter(struct hantro_ctx *ctx) >>       hantro_write_addr(vpu, AV1_DB_CTRL_COL, av1_dec->db_ctrl_col.dma); >>   } >>   -static void rockchip_vpu981_av1_dec_update_prob(struct hantro_ctx >> *ctx) >> -{ >> -    struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> -    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> -    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> -    bool frame_is_intra = IS_INTRA(frame->frame_type); >> -    struct av1cdfs *out_cdfs = (struct av1cdfs >> *)av1_dec->prob_tbl_out.cpu; >> -    int i; >> - >> -    if (frame->flags & >> V4L2_AV1_FRAME_FLAG_DISABLE_FRAME_END_UPDATE_CDF) >> -        return; >> - >> -    for (i = 0; i < NUM_REF_FRAMES; i++) { >> -        if (frame->refresh_frame_flags & BIT(i)) { >> -            struct mvcdfs stored_mv_cdf; >> - >> -            rockchip_av1_get_cdfs(ctx, i); >> -            stored_mv_cdf = av1_dec->cdfs->mv_cdf; >> -            *av1_dec->cdfs = *out_cdfs; >> -            if (frame_is_intra) { >> -                av1_dec->cdfs->mv_cdf = stored_mv_cdf; >> -                *av1_dec->cdfs_ndvc = out_cdfs->mv_cdf; >> -            } >> -            rockchip_av1_store_cdfs(ctx, >> -                        frame->refresh_frame_flags); >> -            break; >> -        } >> -    } >> -} >> - >> -void rockchip_vpu981_av1_dec_done(struct hantro_ctx *ctx) >> -{ >> -    rockchip_vpu981_av1_dec_update_prob(ctx); >> -} >> - >>   static void rockchip_vpu981_av1_dec_set_prob(struct hantro_ctx *ctx) >>   { >>       struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >> -    struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >> -    const struct v4l2_ctrl_av1_frame *frame = ctrls->frame; >> -    const struct v4l2_av1_quantization *quantization = >> &frame->quantization; >>       struct hantro_dev *vpu = ctx->dev; >> -    bool error_resilient_mode = >> -        !!(frame->flags & V4L2_AV1_FRAME_FLAG_ERROR_RESILIENT_MODE); >> -    bool frame_is_intra = IS_INTRA(frame->frame_type); >> - >> -    if (error_resilient_mode || frame_is_intra || >> -        frame->primary_ref_frame == AV1_PRIMARY_REF_NONE) { >> -        av1_dec->cdfs = &av1_dec->default_cdfs; >> -        av1_dec->cdfs_ndvc = &av1_dec->default_cdfs_ndvc; >> - rockchip_av1_default_coeff_probs(quantization->base_q_idx, >> -                         av1_dec->cdfs); >> -    } else { >> -        rockchip_av1_get_cdfs(ctx, >> frame->ref_frame_idx[frame->primary_ref_frame]); >> -    } >> -    rockchip_av1_store_cdfs(ctx, frame->refresh_frame_flags); >> - >> -    memcpy(av1_dec->prob_tbl.cpu, av1_dec->cdfs, sizeof(struct >> av1cdfs)); >> - >> -    if (frame_is_intra) { >> -        int mv_offset = offsetof(struct av1cdfs, mv_cdf); >> -        /* Overwrite MV context area with intrabc MV context */ >> -        memcpy(av1_dec->prob_tbl.cpu + mv_offset, av1_dec->cdfs_ndvc, >> -               sizeof(struct mvcdfs)); >> -    } >>   +    hantro_av1_set_prob(ctx); >>       hantro_write_addr(vpu, AV1_PROP_TABLE_OUT, >> av1_dec->prob_tbl_out.dma); >>       hantro_write_addr(vpu, AV1_PROP_TABLE, av1_dec->prob_tbl.dma); >>   } >>   -static void >> -rockchip_vpu981_av1_dec_init_scaling_function(const u8 *values, >> const u8 *scaling, >> -                          u8 num_points, u8 *scaling_lut) >> -{ >> -    int i, point; >> - >> -    if (num_points == 0) { >> -        memset(scaling_lut, 0, 256); >> -        return; >> -    } >> - >> -    for (point = 0; point < num_points - 1; point++) { >> -        int x; >> -        s32 delta_y = scaling[point + 1] - scaling[point]; >> -        s32 delta_x = values[point + 1] - values[point]; >> -        s64 delta = >> -            delta_x ? delta_y * ((65536 + (delta_x >> 1)) / >> -                     delta_x) : 0; >> - >> -        for (x = 0; x < delta_x; x++) { >> -            scaling_lut[values[point] + x] = >> -                scaling[point] + >> -                (s32)((x * delta + 32768) >> 16); >> -        } >> -    } >> - >> -    for (i = values[num_points - 1]; i < 256; i++) >> -        scaling_lut[i] = scaling[num_points - 1]; >> -} >>     static void rockchip_vpu981_av1_dec_set_fgs(struct hantro_ctx *ctx) >>   { >>       struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; >>       struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; >>       const struct v4l2_ctrl_av1_film_grain *film_grain = >> ctrls->film_grain; >> -    struct rockchip_av1_film_grain *fgmem = av1_dec->film_grain.cpu; >> +    struct hantro_av1_film_grain *fgmem = av1_dec->film_grain.cpu; >>       struct hantro_dev *vpu = ctx->dev; >>       bool scaling_from_luma = >>           !!(film_grain->flags & >> V4L2_AV1_FILM_GRAIN_FLAG_CHROMA_SCALING_FROM_LUMA); >> -    s32 (*ar_coeffs_y)[24]; >> -    s32 (*ar_coeffs_cb)[25]; >> -    s32 (*ar_coeffs_cr)[25]; >> -    s32 (*luma_grain_block)[73][82]; >> -    s32 (*cb_grain_block)[38][44]; >> -    s32 (*cr_grain_block)[38][44]; >> +    struct hantro_av1_coeffs_grain_block *coeffs; >>       s32 ar_coeff_lag, ar_coeff_shift; >>       s32 grain_scale_shift, bitdepth; >>       s32 grain_center, grain_min, grain_max; >> @@ -1269,18 +515,9 @@ static void >> rockchip_vpu981_av1_dec_set_fgs(struct hantro_ctx *ctx) >>           return; >>       } >>   -    ar_coeffs_y = kzalloc(sizeof(int32_t) * 24, GFP_KERNEL); >> -    ar_coeffs_cb = kzalloc(sizeof(int32_t) * 25, GFP_KERNEL); >> -    ar_coeffs_cr = kzalloc(sizeof(int32_t) * 25, GFP_KERNEL); >> -    luma_grain_block = kzalloc(sizeof(int32_t) * 73 * 82, GFP_KERNEL); >> -    cb_grain_block = kzalloc(sizeof(int32_t) * 38 * 44, GFP_KERNEL); >> -    cr_grain_block = kzalloc(sizeof(int32_t) * 38 * 44, GFP_KERNEL); >> - >> -    if (!ar_coeffs_y || !ar_coeffs_cb || !ar_coeffs_cr || >> -        !luma_grain_block || !cb_grain_block || !cr_grain_block) { >> -        pr_warn("Fail allocating memory for film grain parameters\n"); >> -        goto alloc_fail; >> -    } >> +    coeffs = kzalloc(sizeof(*coeffs), GFP_KERNEL); >> +    if (!coeffs) >> +        return; >>         hantro_reg_write(vpu, &av1_apply_grain, 1); >>   @@ -1316,10 +553,10 @@ static void >> rockchip_vpu981_av1_dec_set_fgs(struct hantro_ctx *ctx) >>       hantro_reg_write(vpu, &av1_chroma_scaling_from_luma, >> scaling_from_luma); >>       hantro_reg_write(vpu, &av1_random_seed, film_grain->grain_seed); >>   - >> rockchip_vpu981_av1_dec_init_scaling_function(film_grain->point_y_value, >> -                              film_grain->point_y_scaling, >> -                              film_grain->num_y_points, >> -                              fgmem->scaling_lut_y); >> + hantro_av1_init_scaling_function(film_grain->point_y_value, >> +                     film_grain->point_y_scaling, >> +                     film_grain->num_y_points, >> +                     fgmem->scaling_lut_y); >>         if (film_grain->flags & >>           V4L2_AV1_FILM_GRAIN_FLAG_CHROMA_SCALING_FROM_LUMA) { >> @@ -1328,19 +565,19 @@ static void >> rockchip_vpu981_av1_dec_set_fgs(struct hantro_ctx *ctx) >>           memcpy(fgmem->scaling_lut_cr, fgmem->scaling_lut_y, >>                  sizeof(*fgmem->scaling_lut_y) * 256); >>       } else { >> -        rockchip_vpu981_av1_dec_init_scaling_function >> +        hantro_av1_init_scaling_function >>               (film_grain->point_cb_value, film_grain->point_cb_scaling, >>                film_grain->num_cb_points, fgmem->scaling_lut_cb); >> -        rockchip_vpu981_av1_dec_init_scaling_function >> +        hantro_av1_init_scaling_function >>               (film_grain->point_cr_value, film_grain->point_cr_scaling, >>                film_grain->num_cr_points, fgmem->scaling_lut_cr); >>       } >>         for (i = 0; i < V4L2_AV1_AR_COEFFS_SIZE; i++) { >>           if (i < 24) >> -            (*ar_coeffs_y)[i] = film_grain->ar_coeffs_y_plus_128[i] >> - 128; >> -        (*ar_coeffs_cb)[i] = film_grain->ar_coeffs_cb_plus_128[i] - >> 128; >> -        (*ar_coeffs_cr)[i] = film_grain->ar_coeffs_cr_plus_128[i] - >> 128; >> +            coeffs->ar_coeffs_y[i] = >> film_grain->ar_coeffs_y_plus_128[i] - 128; >> +        coeffs->ar_coeffs_cb[i] = >> film_grain->ar_coeffs_cb_plus_128[i] - 128; >> +        coeffs->ar_coeffs_cr[i] = >> film_grain->ar_coeffs_cr_plus_128[i] - 128; >>       } >>         ar_coeff_lag = film_grain->ar_coeff_lag; >> @@ -1351,46 +588,38 @@ static void >> rockchip_vpu981_av1_dec_set_fgs(struct hantro_ctx *ctx) >>       grain_min = 0 - grain_center; >>       grain_max = (256 << (bitdepth - 8)) - 1 - grain_center; >>   -    rockchip_av1_generate_luma_grain_block(luma_grain_block, >> bitdepth, >> -                           film_grain->num_y_points, grain_scale_shift, >> -                           ar_coeff_lag, ar_coeffs_y, ar_coeff_shift, >> -                           grain_min, grain_max, >> film_grain->grain_seed); >> - >> -    rockchip_av1_generate_chroma_grain_block(luma_grain_block, >> cb_grain_block, >> -                         cr_grain_block, bitdepth, >> -                         film_grain->num_y_points, >> -                         film_grain->num_cb_points, >> -                         film_grain->num_cr_points, >> -                         grain_scale_shift, ar_coeff_lag, ar_coeffs_cb, >> -                         ar_coeffs_cr, ar_coeff_shift, grain_min, >> -                         grain_max, >> -                         scaling_from_luma, >> -                         film_grain->grain_seed); >> +    hantro_av1_generate_luma_grain_block(coeffs, bitdepth, >> +                         film_grain->num_y_points, grain_scale_shift, >> +                         ar_coeff_lag, ar_coeff_shift, >> +                         grain_min, grain_max, film_grain->grain_seed); >> + >> +    hantro_av1_generate_chroma_grain_block(coeffs, bitdepth, >> +                           film_grain->num_y_points, >> +                           film_grain->num_cb_points, >> +                           film_grain->num_cr_points, >> +                           grain_scale_shift, ar_coeff_lag, >> +                           ar_coeff_shift, grain_min, >> +                           grain_max, >> +                           scaling_from_luma, >> +                           film_grain->grain_seed); >>         for (i = 0; i < 64; i++) { >>           for (j = 0; j < 64; j++) >>               fgmem->cropped_luma_grain_block[i * 64 + j] = >> -                (*luma_grain_block)[i + 9][j + 9]; >> +                coeffs->luma_grain_block[i + 9][j + 9]; >>       } >>         for (i = 0; i < 32; i++) { >>           for (j = 0; j < 32; j++) { >>               fgmem->cropped_chroma_grain_block[i * 64 + 2 * j] = >> -                (*cb_grain_block)[i + 6][j + 6]; >> +                coeffs->cb_grain_block[i + 6][j + 6]; >>               fgmem->cropped_chroma_grain_block[i * 64 + 2 * j + 1] = >> -                (*cr_grain_block)[i + 6][j + 6]; >> +                coeffs->cr_grain_block[i + 6][j + 6]; >>           } >>       } >>   +    kfree(coeffs); >>       hantro_write_addr(vpu, AV1_FILM_GRAIN, av1_dec->film_grain.dma); >> - >> -alloc_fail: >> -    kfree(ar_coeffs_y); >> -    kfree(ar_coeffs_cb); >> -    kfree(ar_coeffs_cr); >> -    kfree(luma_grain_block); >> -    kfree(cb_grain_block); >> -    kfree(cr_grain_block); >>   } >>     static void rockchip_vpu981_av1_dec_set_cdef(struct hantro_ctx *ctx) >> @@ -1617,13 +846,13 @@ static void >> rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx) >>       int ref_ind = 0; >>       int rf, idx; >>   -    alt_frame_offset = rockchip_vpu981_get_order_hint(ctx, >> ALT_BUF_IDX); >> -    gld_frame_offset = rockchip_vpu981_get_order_hint(ctx, >> GLD_BUF_IDX); >> -    bwd_frame_offset = rockchip_vpu981_get_order_hint(ctx, >> BWD_BUF_IDX); >> -    alt2_frame_offset = rockchip_vpu981_get_order_hint(ctx, >> ALT2_BUF_IDX); >> +    alt_frame_offset = hantro_av1_get_order_hint(ctx, ALT_BUF_IDX); >> +    gld_frame_offset = hantro_av1_get_order_hint(ctx, GLD_BUF_IDX); >> +    bwd_frame_offset = hantro_av1_get_order_hint(ctx, BWD_BUF_IDX); >> +    alt2_frame_offset = hantro_av1_get_order_hint(ctx, ALT2_BUF_IDX); >>   -    idx = rockchip_vpu981_get_frame_index(ctx, LST_BUF_IDX); >> -    if (idx >= 0) { >> +    idx = hantro_av1_get_frame_index(ctx, LST_BUF_IDX); >> +    if (idx != AV1_INVALID_IDX) { >>           int alt_frame_offset_in_lst = >> av1_dec->frame_refs[idx].order_hints[V4L2_AV1_REF_ALTREF_FRAME]; >>           bool is_lst_overlay = >> @@ -1644,8 +873,9 @@ static void >> rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx) >>           ref_stamp--; >>       } >>   -    idx = rockchip_vpu981_get_frame_index(ctx, BWD_BUF_IDX); >> -    if (rockchip_vpu981_av1_dec_get_dist(ctx, bwd_frame_offset, >> cur_frame_offset) > 0) { >> +    idx = hantro_av1_get_frame_index(ctx, BWD_BUF_IDX); >> +    if (idx != AV1_INVALID_IDX && >> +        hantro_av1_get_dist(ctx, bwd_frame_offset, cur_frame_offset) >> > 0) { >>           int bwd_mi_cols = av1_dec->frame_refs[idx].mi_cols; >>           int bwd_mi_rows = av1_dec->frame_refs[idx].mi_rows; >>           bool bwd_intra_only = >> @@ -1659,8 +889,9 @@ static void >> rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx) >>           } >>       } >>   -    idx = rockchip_vpu981_get_frame_index(ctx, ALT2_BUF_IDX); >> -    if (rockchip_vpu981_av1_dec_get_dist(ctx, alt2_frame_offset, >> cur_frame_offset) > 0) { >> +    idx = hantro_av1_get_frame_index(ctx, ALT2_BUF_IDX); >> +    if (idx != AV1_INVALID_IDX && >> +        hantro_av1_get_dist(ctx, alt2_frame_offset, >> cur_frame_offset) > 0) { >>           int alt2_mi_cols = av1_dec->frame_refs[idx].mi_cols; >>           int alt2_mi_rows = av1_dec->frame_refs[idx].mi_rows; >>           bool alt2_intra_only = >> @@ -1674,8 +905,9 @@ static void >> rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx) >>           } >>       } >>   -    idx = rockchip_vpu981_get_frame_index(ctx, ALT_BUF_IDX); >> -    if (rockchip_vpu981_av1_dec_get_dist(ctx, alt_frame_offset, >> cur_frame_offset) > 0 && >> +    idx = hantro_av1_get_frame_index(ctx, ALT_BUF_IDX); >> +    if (idx != AV1_INVALID_IDX && >> +        hantro_av1_get_dist(ctx, alt_frame_offset, cur_frame_offset) >> > 0 && >>           ref_stamp >= 0) { >>           int alt_mi_cols = av1_dec->frame_refs[idx].mi_cols; >>           int alt_mi_rows = av1_dec->frame_refs[idx].mi_rows; >> @@ -1690,8 +922,8 @@ static void >> rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx) >>           } >>       } >>   -    idx = rockchip_vpu981_get_frame_index(ctx, LST2_BUF_IDX); >> -    if (idx >= 0 && ref_stamp >= 0) { >> +    idx = hantro_av1_get_frame_index(ctx, LST2_BUF_IDX); >> +    if (idx != AV1_INVALID_IDX && ref_stamp >= 0) { >>           int lst2_mi_cols = av1_dec->frame_refs[idx].mi_cols; >>           int lst2_mi_rows = av1_dec->frame_refs[idx].mi_rows; >>           bool lst2_intra_only = >> @@ -1706,14 +938,14 @@ static void >> rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx) >>       } >>         for (rf = 0; rf < V4L2_AV1_TOTAL_REFS_PER_FRAME - 1; ++rf) { >> -        idx = rockchip_vpu981_get_frame_index(ctx, rf); >> -        if (idx >= 0) { >> -            int rf_order_hint = rockchip_vpu981_get_order_hint(ctx, >> rf); >> +        idx = hantro_av1_get_frame_index(ctx, rf); >> +        if (idx != AV1_INVALID_IDX) { >> +            int rf_order_hint = hantro_av1_get_order_hint(ctx, rf); >>                 cur_offset[rf] = >> -                rockchip_vpu981_av1_dec_get_dist(ctx, >> cur_frame_offset, rf_order_hint); >> +                hantro_av1_get_dist(ctx, cur_frame_offset, >> rf_order_hint); >>               cur_roffset[rf] = >> -                rockchip_vpu981_av1_dec_get_dist(ctx, rf_order_hint, >> cur_frame_offset); >> +                hantro_av1_get_dist(ctx, rf_order_hint, >> cur_frame_offset); >>           } else { >>               cur_offset[rf] = 0; >>               cur_roffset[rf] = 0; >> @@ -1736,35 +968,41 @@ static void >> rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx) >>       if (use_ref_frame_mvs && ref_ind > 0 && >>           cur_offset[mf_types[0] - V4L2_AV1_REF_LAST_FRAME] <= >> MAX_FRAME_DISTANCE && >>           cur_offset[mf_types[0] - V4L2_AV1_REF_LAST_FRAME] >= >> -MAX_FRAME_DISTANCE) { >> -        int rf = rockchip_vpu981_get_order_hint(ctx, refs_selected[0]); >> -        int idx = rockchip_vpu981_get_frame_index(ctx, >> refs_selected[0]); >> -        u32 *oh = av1_dec->frame_refs[idx].order_hints; >> +        int rf = hantro_av1_get_order_hint(ctx, refs_selected[0]); >> +        int idx = hantro_av1_get_frame_index(ctx, refs_selected[0]); >> +        u32 *oh; >>           int val; >>   +        if (idx == AV1_INVALID_IDX) >> +            goto second_ref; >> + >> +        oh = av1_dec->frame_refs[idx].order_hints; >> + >>           hantro_reg_write(vpu, &av1_use_temporal0_mvs, 1); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST_FRAME]); >>           hantro_reg_write(vpu, &av1_mf1_last_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST2_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST2_FRAME]); >>           hantro_reg_write(vpu, &av1_mf1_last2_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST3_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST3_FRAME]); >>           hantro_reg_write(vpu, &av1_mf1_last3_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_GOLDEN_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_GOLDEN_FRAME]); >>           hantro_reg_write(vpu, &av1_mf1_golden_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_BWDREF_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_BWDREF_FRAME]); >>           hantro_reg_write(vpu, &av1_mf1_bwdref_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_ALTREF2_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_ALTREF2_FRAME]); >>           hantro_reg_write(vpu, &av1_mf1_altref2_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_ALTREF_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_ALTREF_FRAME]); >>           hantro_reg_write(vpu, &av1_mf1_altref_offset, val); >>       } >>   +second_ref: >>       hantro_reg_write(vpu, &av1_mf2_last_offset, 0); >>       hantro_reg_write(vpu, &av1_mf2_last2_offset, 0); >>       hantro_reg_write(vpu, &av1_mf2_last3_offset, 0); >> @@ -1776,35 +1014,41 @@ static void >> rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx) >>       if (use_ref_frame_mvs && ref_ind > 1 && >>           cur_offset[mf_types[1] - V4L2_AV1_REF_LAST_FRAME] <= >> MAX_FRAME_DISTANCE && >>           cur_offset[mf_types[1] - V4L2_AV1_REF_LAST_FRAME] >= >> -MAX_FRAME_DISTANCE) { >> -        int rf = rockchip_vpu981_get_order_hint(ctx, refs_selected[1]); >> -        int idx = rockchip_vpu981_get_frame_index(ctx, >> refs_selected[1]); >> -        u32 *oh = av1_dec->frame_refs[idx].order_hints; >> +        int rf = hantro_av1_get_order_hint(ctx, refs_selected[1]); >> +        int idx = hantro_av1_get_frame_index(ctx, refs_selected[1]); >> +        u32 *oh; >>           int val; >>   +        if (idx == AV1_INVALID_IDX) >> +            goto third_ref; >> + >> +        oh = av1_dec->frame_refs[idx].order_hints; >> + >>           hantro_reg_write(vpu, &av1_use_temporal1_mvs, 1); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST_FRAME]); >>           hantro_reg_write(vpu, &av1_mf2_last_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST2_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST2_FRAME]); >>           hantro_reg_write(vpu, &av1_mf2_last2_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST3_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST3_FRAME]); >>           hantro_reg_write(vpu, &av1_mf2_last3_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_GOLDEN_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_GOLDEN_FRAME]); >>           hantro_reg_write(vpu, &av1_mf2_golden_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_BWDREF_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_BWDREF_FRAME]); >>           hantro_reg_write(vpu, &av1_mf2_bwdref_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_ALTREF2_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_ALTREF2_FRAME]); >>           hantro_reg_write(vpu, &av1_mf2_altref2_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_ALTREF_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_ALTREF_FRAME]); >>           hantro_reg_write(vpu, &av1_mf2_altref_offset, val); >>       } >>   +third_ref: >>       hantro_reg_write(vpu, &av1_mf3_last_offset, 0); >>       hantro_reg_write(vpu, &av1_mf3_last2_offset, 0); >>       hantro_reg_write(vpu, &av1_mf3_last3_offset, 0); >> @@ -1816,35 +1060,41 @@ static void >> rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx) >>       if (use_ref_frame_mvs && ref_ind > 2 && >>           cur_offset[mf_types[2] - V4L2_AV1_REF_LAST_FRAME] <= >> MAX_FRAME_DISTANCE && >>           cur_offset[mf_types[2] - V4L2_AV1_REF_LAST_FRAME] >= >> -MAX_FRAME_DISTANCE) { >> -        int rf = rockchip_vpu981_get_order_hint(ctx, refs_selected[2]); >> -        int idx = rockchip_vpu981_get_frame_index(ctx, >> refs_selected[2]); >> -        u32 *oh = av1_dec->frame_refs[idx].order_hints; >> +        int rf = hantro_av1_get_order_hint(ctx, refs_selected[2]); >> +        int idx = hantro_av1_get_frame_index(ctx, refs_selected[2]); >> +        u32 *oh; >>           int val; >>   +        if (idx == AV1_INVALID_IDX) >> +            goto offsets; >> + >> +        oh = av1_dec->frame_refs[idx].order_hints; >> + >>           hantro_reg_write(vpu, &av1_use_temporal2_mvs, 1); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST_FRAME]); >>           hantro_reg_write(vpu, &av1_mf3_last_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST2_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST2_FRAME]); >>           hantro_reg_write(vpu, &av1_mf3_last2_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST3_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_LAST3_FRAME]); >>           hantro_reg_write(vpu, &av1_mf3_last3_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_GOLDEN_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_GOLDEN_FRAME]); >>           hantro_reg_write(vpu, &av1_mf3_golden_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_BWDREF_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_BWDREF_FRAME]); >>           hantro_reg_write(vpu, &av1_mf3_bwdref_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_ALTREF2_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_ALTREF2_FRAME]); >>           hantro_reg_write(vpu, &av1_mf3_altref2_offset, val); >>   -        val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_ALTREF_FRAME]); >> +        val = hantro_av1_get_dist(ctx, rf, >> oh[V4L2_AV1_REF_ALTREF_FRAME]); >>           hantro_reg_write(vpu, &av1_mf3_altref_offset, val); >>       } >>   +offsets: >>       hantro_reg_write(vpu, &av1_cur_last_offset, cur_offset[0]); >>       hantro_reg_write(vpu, &av1_cur_last2_offset, cur_offset[1]); >>       hantro_reg_write(vpu, &av1_cur_last3_offset, cur_offset[2]); >> @@ -1883,9 +1133,9 @@ static void >> rockchip_vpu981_av1_dec_set_reference_frames(struct hantro_ctx *ctx) >>         if (!allow_intrabc) { >>           for (i = 0; i < V4L2_AV1_REFS_PER_FRAME; i++) { >> -            int idx = rockchip_vpu981_get_frame_index(ctx, i); >> +            int idx = hantro_av1_get_frame_index(ctx, i); >>   -            if (idx >= 0) >> +            if (idx != AV1_INVALID_IDX) >>                   ref_count[idx]++; >>           } >>   @@ -1898,7 +1148,7 @@ static void >> rockchip_vpu981_av1_dec_set_reference_frames(struct hantro_ctx *ctx) >>       } >>       hantro_reg_write(vpu, &av1_ref_frames, ref_frames); >>   -    rockchip_vpu981_av1_dec_set_frame_sign_bias(ctx); >> +    hantro_av1_set_frame_sign_bias(ctx); >>         for (i = V4L2_AV1_REF_LAST_FRAME; i < >> V4L2_AV1_TOTAL_REFS_PER_FRAME; i++) { >>           u32 ref = i - 1; >> @@ -1910,8 +1160,8 @@ static void >> rockchip_vpu981_av1_dec_set_reference_frames(struct hantro_ctx *ctx) >>               width = frame->frame_width_minus_1 + 1; >>               height = frame->frame_height_minus_1 + 1; >>           } else { >> -            if (rockchip_vpu981_get_frame_index(ctx, ref) > 0) >> -                idx = rockchip_vpu981_get_frame_index(ctx, ref); >> +            if (hantro_av1_get_frame_index(ctx, ref) != >> AV1_INVALID_IDX) >> +                idx = hantro_av1_get_frame_index(ctx, ref); >>               width = av1_dec->frame_refs[idx].width; >>               height = av1_dec->frame_refs[idx].height; >>           } >> @@ -1943,20 +1193,6 @@ static void >> rockchip_vpu981_av1_dec_set_reference_frames(struct hantro_ctx *ctx) >>       rockchip_vpu981_av1_dec_set_other_frames(ctx); >>   } >>   -static int rockchip_vpu981_av1_get_hardware_tx_mode(enum >> v4l2_av1_tx_mode tx_mode) >> -{ >> -    switch (tx_mode) { >> -    case V4L2_AV1_TX_MODE_ONLY_4X4: >> -        return ROCKCHIP_AV1_TX_MODE_ONLY_4X4; >> -    case V4L2_AV1_TX_MODE_LARGEST: >> -        return ROCKCHIP_AV1_TX_MODE_32x32; >> -    case V4L2_AV1_TX_MODE_SELECT: >> -        return ROCKCHIP_AV1_TX_MODE_SELECT; >> -    } >> - >> -    return ROCKCHIP_AV1_TX_MODE_32x32; >> -} >> - >>   static void rockchip_vpu981_av1_dec_set_parameters(struct >> hantro_ctx *ctx) >>   { >>       struct hantro_dev *vpu = ctx->dev; >> @@ -2029,7 +1265,7 @@ static void >> rockchip_vpu981_av1_dec_set_parameters(struct hantro_ctx *ctx) >>       hantro_reg_write(vpu, &av1_comp_pred_mode, >>                (ctrls->frame->flags & >> V4L2_AV1_FRAME_FLAG_REFERENCE_SELECT) ? 2 : 0); >>   -    tx_mode = >> rockchip_vpu981_av1_get_hardware_tx_mode(ctrls->frame->tx_mode); >> +    tx_mode = hantro_av1_get_hardware_tx_mode(ctrls->frame->tx_mode); >>       hantro_reg_write(vpu, &av1_transform_mode, tx_mode); >>       hantro_reg_write(vpu, &av1_max_cb_size, >>                (ctrls->sequence->flags >> @@ -2061,7 +1297,7 @@ static void >> rockchip_vpu981_av1_dec_set_parameters(struct hantro_ctx *ctx) >>           hantro_reg_write(vpu, &av1_qmlevel_v, 0xff); >>       } >>   -    hantro_reg_write(vpu, &av1_lossless_e, >> rockchip_vpu981_av1_dec_is_lossless(ctx)); >> +    hantro_reg_write(vpu, &av1_lossless_e, >> hantro_av1_is_lossless(ctx)); >>       hantro_reg_write(vpu, &av1_quant_delta_v_dc, >> ctrls->frame->quantization.delta_q_v_dc); >>       hantro_reg_write(vpu, &av1_quant_delta_v_ac, >> ctrls->frame->quantization.delta_q_v_ac); >>   @@ -2109,8 +1345,8 @@ >> rockchip_vpu981_av1_dec_set_output_buffer(struct hantro_ctx *ctx) >>       struct hantro_decoded_buffer *dst; >>       struct vb2_v4l2_buffer *vb2_dst; >>       dma_addr_t luma_addr, chroma_addr, mv_addr = 0; >> -    size_t cr_offset = rockchip_vpu981_av1_dec_luma_size(ctx); >> -    size_t mv_offset = rockchip_vpu981_av1_dec_chroma_size(ctx); >> +    size_t cr_offset = hantro_av1_luma_size(ctx); >> +    size_t mv_offset = hantro_av1_chroma_size(ctx); >>         vb2_dst = >> av1_dec->frame_refs[av1_dec->current_frame_index].vb2_ref; >>       dst = vb2_to_hantro_decoded_buf(&vb2_dst->vb2_buf); >> @@ -2134,7 +1370,7 @@ int rockchip_vpu981_av1_dec_run(struct >> hantro_ctx *ctx) >>         hantro_start_prepare_run(ctx); >>   -    ret = rockchip_vpu981_av1_dec_prepare_run(ctx); >> +    ret = hantro_av1_prepare_run(ctx); >>       if (ret) >>           goto prepare_error; >>   @@ -2144,8 +1380,8 @@ int rockchip_vpu981_av1_dec_run(struct >> hantro_ctx *ctx) >>           goto prepare_error; >>       } >>   -    rockchip_vpu981_av1_dec_clean_refs(ctx); >> -    rockchip_vpu981_av1_dec_frame_ref(ctx, vb2_src->vb2_buf.timestamp); >> +    hantro_av1_clean_refs(ctx); >> +    hantro_av1_frame_ref(ctx, vb2_src->vb2_buf.timestamp); >>         rockchip_vpu981_av1_dec_set_parameters(ctx); >>       rockchip_vpu981_av1_dec_set_global_model(ctx); >> diff --git a/drivers/media/platform/verisilicon/rockchip_vpu_hw.c >> b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c >> index 02673be9878e..f50a3e38097e 100644 >> --- a/drivers/media/platform/verisilicon/rockchip_vpu_hw.c >> +++ b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c >> @@ -9,6 +9,7 @@ >>   #include >>     #include "hantro.h" >> +#include "hantro_av1.h" >>   #include "hantro_jpeg.h" >>   #include "hantro_g1_regs.h" >>   #include "hantro_h1_regs.h" >> @@ -608,9 +609,9 @@ static const struct hantro_codec_ops >> rk3568_vepu_codec_ops[] = { >>   static const struct hantro_codec_ops rk3588_vpu981_codec_ops[] = { >>       [HANTRO_MODE_AV1_DEC] = { >>           .run = rockchip_vpu981_av1_dec_run, >> -        .init = rockchip_vpu981_av1_dec_init, >> -        .exit = rockchip_vpu981_av1_dec_exit, >> -        .done = rockchip_vpu981_av1_dec_done, >> +        .init = hantro_av1_init, >> +        .exit = hantro_av1_exit, >> +        .done = hantro_av1_update_prob, >>       }, >>   }; >>   /* 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 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DA6AFC624A4 for ; Mon, 31 Aug 2026 13:38:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:References:Cc:To:From:Subject: MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=nrY1Z9MimTe4aouigOTBFF+94qGMAJiCP/l/BjCp0IQ=; b=4kg3YuxPE/LXoH +r2/bS70+vW8EeZeqkOYj18bbt81BNsiAmbhSE8mO7hJb3yVGUEsQSOJGwS4GHR0y0wYoQ5Yn2Cqd yQU+7zxu4b5nF/ahykvzPe634OtkmpxTrwkXr3GGOYI/RTScE8d2dfDIhJO8fgydbJ/8W6Doo0puN BOKA3LQ8RBGF2zWS25+24yRPWR5/VyrTCAk5EbiV5ELDROvqshpR0cq9pU3/tQN1PNIxt4bo+obVt IVHEpxE26YMhKB4uBxtjrLZPJ5FvzrjSLQJIfLT5O4Rkv9RAR1q6KWp4ztDrHr5GULNka9N+3+K4m oiB/YQRNq2x2jDT146gw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x12DU-00000009Rkr-3SQR; Mon, 31 Aug 2026 13:38:28 +0000 Received: from sender4-op-o11.zoho.com ([136.143.188.11]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x12DQ-00000009Rk0-1QHq; Mon, 31 Aug 2026 13:38:26 +0000 ARC-Seal: i=1; a=rsa-sha256; t=1788183489; cv=none; d=zohomail.com; s=zohoarc; b=DgPQUzBqluTpdRfkXsbxDkjE98EhJakSW24tVlr/j6QcFklt/wgmkxPJQ5yi+39opgMrUbOzlbnQyl2UMBvoz1K0tGX8uZi6u2uOCZbWi3W6oO8TVtmM9EjmVv1MJfZRY5kvacsUs4/BRnwUUgpiNyOcrVuOoW4QXmHENW1Og40= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788183489; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:Subject:Subject:To:To:Message-Id:Reply-To; bh=zdEqHU01IjF92t+B1+W0pEI1Sf51+S0bk3C3C5oJ47w=; b=Iy4EdWY+TrJJl2TyLmq2wnNNSvZCT+gIseLbKyl3ivPfHaw8QI8Diy9n41mwRUAwYUGUBUk6qIRRkU6pAI2FDjUmFPyxWJY5veL6yU2uY77DPis0DkXEo4cBxG5zxl1OHPf0SfcVxwEiaQ9DGieYPxKHaaeLY8f2Xv36dzfV6b0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=benjamin.gaignard@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1788183489; s=zohomail; d=collabora.com; i=benjamin.gaignard@collabora.com; h=Message-ID:Date:Date:MIME-Version:Subject:Subject:From:From:To:To:Cc:Cc:In-Reply-To:Content-Type:Content-Transfer-Encoding:Message-Id:Reply-To; bh=zdEqHU01IjF92t+B1+W0pEI1Sf51+S0bk3C3C5oJ47w=; b=BteJHwZlsgZJ8RcgueK380Af5N8zubcpfqtfZhAqybs4zxdKIn4NYZhmd2dqyVww 2UcoAcsQ36Hbu4khHk4nVl99D9k+JKtoMhrz5Py4qoEpl6BCS83+Tiz2ks5LL2V53rn WMS2daAXognNfi3djKVSxVRWxpBMp4C3EyXe7NbQ= Received: by mx.zohomail.com with SMTPS id 1788183487750755.1901236467753; Mon, 31 Aug 2026 06:38:07 -0700 (PDT) Message-ID: <25e17f59-e637-48a2-8a9b-4913738b7c4e@collabora.com> Date: Mon, 31 Aug 2026 15:38:03 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v5] media: verisilicon: Create AV1 helper library From: Benjamin Gaignard To: nicolas.dufresne@collabora.com, p.zabel@pengutronix.de, mchehab@kernel.org, heiko@sntech.de Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, kernel@collabora.com References: <20260512075949.87441-1-benjamin.gaignard@collabora.com> <6eb8768e-e46c-47f4-966d-bfc05c8a6fe4@collabora.com> Content-Language: en-US In-Reply-To: <6eb8768e-e46c-47f4-966d-bfc05c8a6fe4@collabora.com> X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org CkxlIDEwLzA3LzIwMjYgw6AgMTE6NDUsIEJlbmphbWluIEdhaWduYXJkIGEgw6ljcml0wqA6Cj4g R2VudGxlIHBpbmcgb24gdGhpcyBvbmUuCj4KPiBSZWdhcmRzLAo+IEJlbmphbWluCj4KPiBMZSAx Mi8wNS8yMDI2IMOgIDA5OjU5LCBCZW5qYW1pbiBHYWlnbmFyZCBhIMOpY3JpdMKgOgo+PiBSZWdy b3VwIGFsbCBub25lIGhhcmR3YXJlIHJlbGF0ZWQgQVYxIGZ1bmN0aW9ucyBpbnRvIGEgaGVscGVy IGxpYnJhcnkuCj4+IFRoZSBnb2FsIGlzIHRvIGF2b2lkIGNvZGUgZHVwbGljYXRpb24gZm9yIGZ1 dHVyZSBBVjEgY29kZWNzLgo+Pgo+PiBUZXN0ZWQgb24gcm9jayA1YiBib2FyZCBGbHVzdGVyIHNj b3JlIHJlbWFpbnMgdGhlIHNhbWUgMjA0LzI0MS4KPj4KPj4gU2lnbmVkLW9mZi1ieTogQmVuamFt aW4gR2FpZ25hcmQgPGJlbmphbWluLmdhaWduYXJkQGNvbGxhYm9yYS5jb20+Cj4+IFJldmlld2Vk LWJ5OiBOaWNvbGFzIER1ZnJlc25lIDxuaWNvbGFzLmR1ZnJlc25lQGNvbGxhYm9yYS5jb20+CgpI aSBIYW5zLAoKTWF5YmUgc29tZXRoaW5nIGlzIG1pc3Npbmcgb3IgYmxvY2tpbmcgdGhpcyBwYXRj aCBidXQgSSBkb24ndCBrbm93IHdoYXQuCkkgd291bGQgbGlrZSB0byBwcm9ncmVzcyBvbiBpdCBi ZWNhdXNlIEkgcGxhbiB0byBkbyBvdGhlciBpbXByb3ZlbWVudHMKZm9yIFZlcmlzaWxpY29uIGRy aXZlcnMgYW5kIHRoZXkgZGVwZW5kIG9mIHRoaXMgb25lLgpJZiB0aGVyZSBhbnkgSSBjYW4gZG8g dG8gdW5sb2NrIHRoaXMgc2l0dWF0aW9uIHBsZWFzZSB0ZWxsIG1lLgoKVGhhbmtzIGZvciB5b3Vy IHRpbWUuClJlZ2FyZHMsCkJlbmphbWluCgo+PiAtLS0KPj4gdmVyc2lvbiA1Ogo+PiAtIGJlIG1v cmUgc3RyaWN0IGFib3V0IGNoZWNraW5nIGFycmF5cyByYW5nZSBhbmQgdGhlIHZhbHVlIHJldHVy bmVkCj4+IMKgwqAgYnkgaGFudHJvX2F2MV9nZXRfZnJhbWVfaW5kZXgoKQo+PiAtIHJlYmFzZWQg b24gdjcuMS1yYzMgdGFnCj4+Cj4+IHZlcnNpb24gNDoKPj4gLSBjaGFuZ2UgZnVuY3Rpb25zIHBy b3RvdHlwZXMgdG8gdXNlIGEgc3RydWN0dXJlLgo+PiAtIHJlYmFzZWQgb24gdjcuMS1yYzIgdGFn Lgo+Pgo+PiDCoCBkcml2ZXJzL21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL01ha2VmaWxlwqDC oCB8wqDCoMKgIDcgKy0KPj4gwqAgLi4uL21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL2hhbnRy b19hdjEuY8KgwqAgfMKgIDc5MCArKysrKysrKysrKysrCj4+IMKgIC4uLi9tZWRpYS9wbGF0Zm9y bS92ZXJpc2lsaWNvbi9oYW50cm9fYXYxLmjCoMKgIHzCoMKgIDY0ICsrCj4+IMKgIC4uLmVudHJv cHltb2RlLmMgPT4gaGFudHJvX2F2MV9lbnRyb3B5bW9kZS5jfSB8wqDCoCAxOCArLQo+PiDCoCAu Li5lbnRyb3B5bW9kZS5oID0+IGhhbnRyb19hdjFfZW50cm9weW1vZGUuaH0gfMKgwqAgMTggKy0K Pj4gwqAgLi4uYXYxX2ZpbG1ncmFpbi5jID0+IGhhbnRyb19hdjFfZmlsbWdyYWluLmN9IHzCoCAx MjUgKy0KPj4gwqAgLi4uL3ZlcmlzaWxpY29uL2hhbnRyb19hdjFfZmlsbWdyYWluLmjCoMKgwqDC oMKgwqDCoCB8wqDCoCA0OCArCj4+IMKgIC4uLi9tZWRpYS9wbGF0Zm9ybS92ZXJpc2lsaWNvbi9o YW50cm9faHcuaMKgwqDCoCB8wqDCoMKgIDcgKy0KPj4gwqAgLi4uL3ZlcmlzaWxpY29uL3JvY2tj aGlwX2F2MV9maWxtZ3JhaW4uaMKgwqDCoMKgwqAgfMKgwqAgMzYgLQo+PiDCoCAuLi4vdmVyaXNp bGljb24vcm9ja2NoaXBfdnB1OTgxX2h3X2F2MV9kZWMuY8KgIHwgMTAxNCArKy0tLS0tLS0tLS0t LS0tLQo+PiDCoCAuLi4vcGxhdGZvcm0vdmVyaXNpbGljb24vcm9ja2NoaXBfdnB1X2h3LmPCoMKg wqAgfMKgwqDCoCA3ICstCj4+IMKgIDExIGZpbGVzIGNoYW5nZWQsIDExMTUgaW5zZXJ0aW9ucygr KSwgMTAxOSBkZWxldGlvbnMoLSkKPj4gwqAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvbWVk aWEvcGxhdGZvcm0vdmVyaXNpbGljb24vaGFudHJvX2F2MS5jCj4+IMKgIGNyZWF0ZSBtb2RlIDEw MDY0NCBkcml2ZXJzL21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL2hhbnRyb19hdjEuaAo+PiDC oCByZW5hbWUgCj4+IGRyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24ve3JvY2tjaGlw X2F2MV9lbnRyb3B5bW9kZS5jID0+IAo+PiBoYW50cm9fYXYxX2VudHJvcHltb2RlLmN9ICg5OSUp Cj4+IMKgIHJlbmFtZSAKPj4gZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS92ZXJpc2lsaWNvbi97cm9j a2NoaXBfYXYxX2VudHJvcHltb2RlLmggPT4gCj4+IGhhbnRyb19hdjFfZW50cm9weW1vZGUuaH0g KDk1JSkKPj4gwqAgcmVuYW1lIGRyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24ve3Jv Y2tjaGlwX2F2MV9maWxtZ3JhaW4uYyAKPj4gPT4gaGFudHJvX2F2MV9maWxtZ3JhaW4uY30gKDg1 JSkKPj4gwqAgY3JlYXRlIG1vZGUgMTAwNjQ0IAo+PiBkcml2ZXJzL21lZGlhL3BsYXRmb3JtL3Zl cmlzaWxpY29uL2hhbnRyb19hdjFfZmlsbWdyYWluLmgKPj4gwqAgZGVsZXRlIG1vZGUgMTAwNjQ0 IAo+PiBkcml2ZXJzL21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL3JvY2tjaGlwX2F2MV9maWxt Z3JhaW4uaAo+Pgo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS92ZXJpc2ls aWNvbi9NYWtlZmlsZSAKPj4gYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL01h a2VmaWxlCj4+IGluZGV4IGY2ZjAxOWQwNGZmMC4uYTFkZDZjMmQyOWJlIDEwMDY0NAo+PiAtLS0g YS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL01ha2VmaWxlCj4+ICsrKyBiL2Ry aXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24vTWFrZWZpbGUKPj4gQEAgLTE5LDcgKzE5 LDEwIEBAIGhhbnRyby12cHUteSArPSBcCj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBoYW50cm9faGV2 Yy5vIFwKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGhhbnRyb19tcGVnMi5vIFwKPj4gwqDCoMKgwqDC oMKgwqDCoMKgIGhhbnRyb192cDgubyBcCj4+IC3CoMKgwqDCoMKgwqDCoCBoYW50cm9fdnA5Lm8K Pj4gK8KgwqDCoMKgwqDCoMKgIGhhbnRyb192cDkubyBcCj4+ICvCoMKgwqDCoMKgwqDCoCBoYW50 cm9fYXYxLm8gXAo+PiArwqDCoMKgwqDCoMKgwqAgaGFudHJvX2F2MV9maWxtZ3JhaW4ubyBcCj4+ ICvCoMKgwqDCoMKgwqDCoCBoYW50cm9fYXYxX2VudHJvcHltb2RlLm8KPj4gwqAgwqAgaGFudHJv LXZwdS0kKENPTkZJR19WSURFT19IQU5UUk9fSU1YOE0pICs9IFwKPj4gwqDCoMKgwqDCoMKgwqDC oMKgIGlteDhtX3ZwdV9ody5vCj4+IEBAIC0zMyw4ICszNiw2IEBAIGhhbnRyby12cHUtJChDT05G SUdfVklERU9fSEFOVFJPX1JPQ0tDSElQKSArPSBcCj4+IMKgwqDCoMKgwqDCoMKgwqDCoCByb2Nr Y2hpcF92cHUyX2h3X21wZWcyX2RlYy5vIFwKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIHJvY2tjaGlw X3ZwdTJfaHdfdnA4X2RlYy5vIFwKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIHJvY2tjaGlwX3ZwdTk4 MV9od19hdjFfZGVjLm8gXAo+PiAtwqDCoMKgwqDCoMKgwqAgcm9ja2NoaXBfYXYxX2ZpbG1ncmFp bi5vIFwKPj4gLcKgwqDCoMKgwqDCoMKgIHJvY2tjaGlwX2F2MV9lbnRyb3B5bW9kZS5vIFwKPj4g wqDCoMKgwqDCoMKgwqDCoMKgIHJvY2tjaGlwX3ZwdV9ody5vCj4+IMKgIMKgIGhhbnRyby12cHUt JChDT05GSUdfVklERU9fSEFOVFJPX1NVTlhJKSArPSBcCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJz L21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL2hhbnRyb19hdjEuYyAKPj4gYi9kcml2ZXJzL21l ZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL2hhbnRyb19hdjEuYwo+PiBuZXcgZmlsZSBtb2RlIDEw MDY0NAo+PiBpbmRleCAwMDAwMDAwMDAwMDAuLmFjN2FlOGU4N2Y1MAo+PiAtLS0gL2Rldi9udWxs Cj4+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24vaGFudHJvX2F2MS5j Cj4+IEBAIC0wLDAgKzEsNzkwIEBACj4+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BM LTIuMC1vbmx5Cj4+ICsvKgo+PiArICogQ29weXJpZ2h0IChjKSAyMDI2LCBDb2xsYWJvcmEKPj4g KyAqCj4+ICsgKiBBdXRob3I6IEJlbmphbWluIEdhaWduYXJkIDxiZW5qYW1pbi5nYWlnbmFyZEBj b2xsYWJvcmEuY29tPgo+PiArICovCj4+ICsKPj4gKyNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgo+ PiArI2luY2x1ZGUgPG1lZGlhL3Y0bDItaDI2NC5oPgo+PiArI2luY2x1ZGUgPG1lZGlhL3Y0bDIt bWVtMm1lbS5oPgo+PiArCj4+ICsjaW5jbHVkZSAiaGFudHJvLmgiCj4+ICsjaW5jbHVkZSAiaGFu dHJvX2F2MS5oIgo+PiArI2luY2x1ZGUgImhhbnRyb19ody5oIgo+PiArCj4+ICsjZGVmaW5lIEdN X0dMT0JBTF9NT0RFTFNfUEVSX0ZSQU1FwqDCoMKgIDcKPj4gKyNkZWZpbmUgR0xPQkFMX01PREVM X1RPVEFMX1NJWkXCoMKgwqAgKDYgKiA0ICsgNCAqIDIpCj4+ICsjZGVmaW5lIEdMT0JBTF9NT0RF TF9TSVpFwqDCoMKgIEFMSUdOKEdNX0dMT0JBTF9NT0RFTFNfUEVSX0ZSQU1FICogCj4+IEdMT0JB TF9NT0RFTF9UT1RBTF9TSVpFLCAyMDQ4KQo+PiArI2RlZmluZSBBVjFfTUFYX1RJTEVTwqDCoMKg wqDCoMKgwqAgMTI4Cj4+ICsjZGVmaW5lIEFWMV9USUxFX0lORk9fU0laRcKgwqDCoCAoQVYxX01B WF9USUxFUyAqIDE2KQo+PiArI2RlZmluZSBBVjFfVElMRV9TSVpFwqDCoMKgwqDCoMKgwqAgQUxJ R04oMzIgKiAxMjgsIDQwOTYpCj4+ICsKPj4gKyNkZWZpbmUgU1VQRVJSRVNfU0NBTEVfQklUUyAz Cj4+ICsKPj4gKyNkZWZpbmUgRElWX0xVVF9QUkVDX0JJVFMgMTQKPj4gKyNkZWZpbmUgRElWX0xV VF9CSVRTIDgKPj4gKyNkZWZpbmUgRElWX0xVVF9OVU0gQklUKERJVl9MVVRfQklUUykKPj4gKyNk ZWZpbmUgV0FSUF9QQVJBTV9SRURVQ0VfQklUUyA2Cj4+ICsjZGVmaW5lIFdBUlBFRE1PREVMX1BS RUNfQklUUyAxNgo+PiArCj4+ICsjZGVmaW5lIEFWMV9ESVZfUk9VTkRfVVBfUE9XMih2YWx1ZSwg binCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFwKPj4gKyh7wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFwKPj4gK8KgwqDCoCB0eXBlb2YobikgX27C oCA9IG47wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFwKPj4gK8KgwqDCoCB0eXBlb2Yo dmFsdWUpIF92YWx1ZSA9IHZhbHVlO8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgXAo+PiArwqDCoMKg IChfdmFsdWUgKyAoQklUKF9uKSA+PiAxKSkgPj4gX247wqDCoMKgwqDCoMKgwqAgXAo+PiArfSkK Pj4gKwo+PiArI2RlZmluZSBBVjFfRElWX1JPVU5EX1VQX1BPVzJfU0lHTkVEKHZhbHVlLCBuKcKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBcCj4+ICsoe8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgXAo+PiAr wqDCoMKgIHR5cGVvZihuKSBfbl/CoCA9IG47wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCBcCj4+ICvCoMKgwqAgdHlwZW9mKHZhbHVlKSBfdmFsdWVfID0gdmFs dWU7wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgXAo+PiArwqDCoMKgICgo KF92YWx1ZV8pIDwgMCkgPyAtQVYxX0RJVl9ST1VORF9VUF9QT1cyKC0oX3ZhbHVlXyksIChfbl8p KcKgwqDCoCBcCj4+ICvCoMKgwqDCoMKgwqDCoCA6IEFWMV9ESVZfUk9VTkRfVVBfUE9XMigoX3Zh bHVlXyksIChfbl8pKSk7wqDCoMKgwqDCoMKgwqAgXAo+PiArfSkKPj4gKwo+PiArc3RhdGljIGNv bnN0IHNob3J0IGRpdl9sdXRbRElWX0xVVF9OVU0gKyAxXSA9IHsKPj4gK8KgwqDCoCAxNjM4NCwg MTYzMjAsIDE2MjU3LCAxNjE5NCwgMTYxMzIsIDE2MDcwLCAxNjAwOSwgMTU5NDgsIDE1ODg4LCAK Pj4gMTU4MjgsIDE1NzY4LAo+PiArwqDCoMKgIDE1NzA5LCAxNTY1MCwgMTU1OTIsIDE1NTM0LCAx NTQ3NywgMTU0MjAsIDE1MzY0LCAxNTMwOCwgMTUyNTIsIAo+PiAxNTE5NywgMTUxNDIsCj4+ICvC oMKgwqAgMTUwODcsIDE1MDMzLCAxNDk4MCwgMTQ5MjYsIDE0ODczLCAxNDgyMSwgMTQ3NjksIDE0 NzE3LCAxNDY2NSwgCj4+IDE0NjE0LCAxNDU2NCwKPj4gK8KgwqDCoCAxNDUxMywgMTQ0NjMsIDE0 NDEzLCAxNDM2NCwgMTQzMTUsIDE0MjY2LCAxNDIxOCwgMTQxNzAsIDE0MTIyLCAKPj4gMTQwNzUs IDE0MDI4LAo+PiArwqDCoMKgIDEzOTgxLCAxMzkzNSwgMTM4ODgsIDEzODQzLCAxMzc5NywgMTM3 NTIsIDEzNzA3LCAxMzY2MiwgMTM2MTgsIAo+PiAxMzU3NCwgMTM1MzAsCj4+ICvCoMKgwqAgMTM0 ODcsIDEzNDQzLCAxMzQwMCwgMTMzNTgsIDEzMzE1LCAxMzI3MywgMTMyMzEsIDEzMTkwLCAxMzE0 OCwgCj4+IDEzMTA3LCAxMzA2NiwKPj4gK8KgwqDCoCAxMzAyNiwgMTI5ODUsIDEyOTQ1LCAxMjkw NiwgMTI4NjYsIDEyODI3LCAxMjc4OCwgMTI3NDksIDEyNzEwLCAKPj4gMTI2NzIsIDEyNjMzLAo+ PiArwqDCoMKgIDEyNTk2LCAxMjU1OCwgMTI1MjAsIDEyNDgzLCAxMjQ0NiwgMTI0MDksIDEyMzcz LCAxMjMzNiwgMTIzMDAsIAo+PiAxMjI2NCwgMTIyMjgsCj4+ICvCoMKgwqAgMTIxOTMsIDEyMTU3 LCAxMjEyMiwgMTIwODcsIDEyMDUzLCAxMjAxOCwgMTE5ODQsIDExOTUwLCAxMTkxNiwgCj4+IDEx ODgyLCAxMTg0OCwKPj4gK8KgwqDCoCAxMTgxNSwgMTE3ODIsIDExNzQ5LCAxMTcxNiwgMTE2ODMs IDExNjUxLCAxMTYxOSwgMTE1ODYsIDExNTU1LCAKPj4gMTE1MjMsIDExNDkxLAo+PiArwqDCoMKg IDExNDYwLCAxMTQyOSwgMTEzOTgsIDExMzY3LCAxMTMzNiwgMTEzMDUsIDExMjc1LCAxMTI0NSwg MTEyMTUsIAo+PiAxMTE4NSwgMTExNTUsCj4+ICvCoMKgwqAgMTExMjUsIDExMDk2LCAxMTA2Nywg MTEwMzgsIDExMDA5LCAxMDk4MCwgMTA5NTEsIDEwOTIzLCAxMDg5NCwgCj4+IDEwODY2LCAxMDgz OCwKPj4gK8KgwqDCoCAxMDgxMCwgMTA3ODIsIDEwNzU1LCAxMDcyNywgMTA3MDAsIDEwNjczLCAx MDY0NSwgMTA2MTgsIDEwNTkyLCAKPj4gMTA1NjUsIDEwNTM4LAo+PiArwqDCoMKgIDEwNTEyLCAx MDQ4NiwgMTA0NjAsIDEwNDM0LCAxMDQwOCwgMTAzODIsIDEwMzU2LCAxMDMzMSwgMTAzMDUsIAo+ PiAxMDI4MCwgMTAyNTUsCj4+ICvCoMKgwqAgMTAyMzAsIDEwMjA1LCAxMDE4MCwgMTAxNTYsIDEw MTMxLCAxMDEwNywgMTAwODIsIDEwMDU4LCAxMDAzNCwgCj4+IDEwMDEwLCA5OTg2LAo+PiArwqDC oMKgIDk5NjMswqAgOTkzOSzCoCA5OTE2LMKgIDk4OTIswqAgOTg2OSzCoCA5ODQ2LMKgIDk4MjMs wqAgOTgwMCwgOTc3NyzCoCAKPj4gOTc1NCzCoCA5NzMyLAo+PiArwqDCoMKgIDk3MDkswqAgOTY4 NyzCoCA5NjY0LMKgIDk2NDIswqAgOTYyMCzCoCA5NTk4LMKgIDk1NzYswqAgOTU1NCwgOTUzMyzC oCAKPj4gOTUxMSzCoCA5NDg5LAo+PiArwqDCoMKgIDk0NjgswqAgOTQ0NyzCoCA5NDI1LMKgIDk0 MDQswqAgOTM4MyzCoCA5MzYyLMKgIDkzNDEswqAgOTMyMSwgOTMwMCzCoCAKPj4gOTI3OSzCoCA5 MjU5LAo+PiArwqDCoMKgIDkyMzkswqAgOTIxOCzCoCA5MTk4LMKgIDkxNzgswqAgOTE1OCzCoCA5 MTM4LMKgIDkxMTgswqAgOTA5OCwgOTA3OSzCoCAKPj4gOTA1OSzCoCA5MDM5LAo+PiArwqDCoMKg IDkwMjAswqAgOTAwMSzCoCA4OTgxLMKgIDg5NjIswqAgODk0MyzCoCA4OTI0LMKgIDg5MDUswqAg ODg4NiwgODg2NyzCoCAKPj4gODg0OSzCoCA4ODMwLAo+PiArwqDCoMKgIDg4MTIswqAgODc5MyzC oCA4Nzc1LMKgIDg3NTYswqAgODczOCzCoCA4NzIwLMKgIDg3MDIswqAgODY4NCwgODY2NizCoCAK Pj4gODY0OCzCoCA4NjMwLAo+PiArwqDCoMKgIDg2MTMswqAgODU5NSzCoCA4NTc3LMKgIDg1NjAs wqAgODU0MizCoCA4NTI1LMKgIDg1MDgswqAgODQ5MCwgODQ3MyzCoCAKPj4gODQ1NizCoCA4NDM5 LAo+PiArwqDCoMKgIDg0MjIswqAgODQwNSzCoCA4Mzg5LMKgIDgzNzIswqAgODM1NSzCoCA4MzM5 LMKgIDgzMjIswqAgODMwNiwgODI4OSzCoCAKPj4gODI3MyzCoCA4MjU3LAo+PiArwqDCoMKgIDgy NDAswqAgODIyNCzCoCA4MjA4LMKgIDgxOTIsCj4+ICt9Owo+PiArCj4+ICtlbnVtIGhhbnRyb19h djFfdHhfbW9kZSB7Cj4+ICvCoMKgwqAgSEFOVFJPX0FWMV9UWF9NT0RFX09OTFlfNFg0wqDCoMKg ID0gMCwKPj4gK8KgwqDCoCBIQU5UUk9fQVYxX1RYX01PREVfOFg4wqDCoMKgwqDCoMKgwqAgPSAx LAo+PiArwqDCoMKgIEhBTlRST19BVjFfVFhfTU9ERV8xNngxNsKgwqDCoCA9IDIsCj4+ICvCoMKg wqAgSEFOVFJPX0FWMV9UWF9NT0RFXzMyeDMywqDCoMKgID0gMywKPj4gK8KgwqDCoCBIQU5UUk9f QVYxX1RYX01PREVfU0VMRUNUwqDCoMKgID0gNCwKPj4gK307Cj4+ICsKPj4gK2VudW0gaGFudHJv X2F2MV9pbnRlcl9wcmVkaWN0aW9uX2ZpbHRlcl90eXBlIHsKPj4gK8KgwqDCoCBIQU5UUk9fQVYx X0VJR0hUX1RBUF9TTU9PVEjCoMKgwqAgPSAwLAo+PiArwqDCoMKgIEhBTlRST19BVjFfRUlHSFRf VEFQwqDCoMKgwqDCoMKgwqAgPSAxLAo+PiArwqDCoMKgIEhBTlRST19BVjFfRUlHSFRfVEFQX1NI QVJQwqDCoMKgID0gMiwKPj4gK8KgwqDCoCBIQU5UUk9fQVYxX0JJTElORUFSwqDCoMKgwqDCoMKg wqAgPSAzLAo+PiArwqDCoMKgIEhBTlRST19BVjFfU1dJVENIQUJMRcKgwqDCoMKgwqDCoMKgID0g NCwKPj4gK307Cj4+ICsKPj4gK2ludCBoYW50cm9fYXYxX2dldF9oYXJkd2FyZV90eF9tb2RlKGVu dW0gdjRsMl9hdjFfdHhfbW9kZSB0eF9tb2RlKQo+PiArewo+PiArwqDCoMKgIHN3aXRjaCAodHhf bW9kZSkgewo+PiArwqDCoMKgIGNhc2UgVjRMMl9BVjFfVFhfTU9ERV9PTkxZXzRYNDoKPj4gK8Kg wqDCoMKgwqDCoMKgIHJldHVybiBIQU5UUk9fQVYxX1RYX01PREVfT05MWV80WDQ7Cj4+ICvCoMKg wqAgY2FzZSBWNEwyX0FWMV9UWF9NT0RFX0xBUkdFU1Q6Cj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1 cm4gSEFOVFJPX0FWMV9UWF9NT0RFXzMyeDMyOwo+PiArwqDCoMKgIGNhc2UgVjRMMl9BVjFfVFhf TU9ERV9TRUxFQ1Q6Cj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gSEFOVFJPX0FWMV9UWF9NT0RF X1NFTEVDVDsKPj4gK8KgwqDCoCB9Cj4+ICsKPj4gK8KgwqDCoCByZXR1cm4gSEFOVFJPX0FWMV9U WF9NT0RFXzMyeDMyOwo+PiArfQo+PiArCj4+ICtpbnQgaGFudHJvX2F2MV9nZXRfaGFyZHdhcmVf bWNvbXBfZmlsdF90eXBlKGludCBpbnRlcnBvbGF0aW9uX2ZpbHRlcikKPj4gK3sKPj4gK8KgwqDC oCBzd2l0Y2ggKGludGVycG9sYXRpb25fZmlsdGVyKSB7Cj4+ICvCoMKgwqAgY2FzZSBWNEwyX0FW MV9JTlRFUlBPTEFUSU9OX0ZJTFRFUl9FSUdIVFRBUDoKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVy biBIQU5UUk9fQVYxX0VJR0hUX1RBUDsKPj4gK8KgwqDCoCBjYXNlIFY0TDJfQVYxX0lOVEVSUE9M QVRJT05fRklMVEVSX0VJR0hUVEFQX1NNT09USDoKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiBI QU5UUk9fQVYxX0VJR0hUX1RBUF9TTU9PVEg7Cj4+ICvCoMKgwqAgY2FzZSBWNEwyX0FWMV9JTlRF UlBPTEFUSU9OX0ZJTFRFUl9FSUdIVFRBUF9TSEFSUDoKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVy biBIQU5UUk9fQVYxX0VJR0hUX1RBUF9TSEFSUDsKPj4gK8KgwqDCoCBjYXNlIFY0TDJfQVYxX0lO VEVSUE9MQVRJT05fRklMVEVSX0JJTElORUFSOgo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIEhB TlRST19BVjFfQklMSU5FQVI7Cj4+ICvCoMKgwqAgY2FzZSBWNEwyX0FWMV9JTlRFUlBPTEFUSU9O X0ZJTFRFUl9TV0lUQ0hBQkxFOgo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIEhBTlRST19BVjFf U1dJVENIQUJMRTsKPj4gK8KgwqDCoCB9Cj4+ICsKPj4gK8KgwqDCoCByZXR1cm4gSEFOVFJPX0FW MV9FSUdIVF9UQVBfU01PT1RIOwo+PiArfQo+PiArCj4+ICtpbnQgaGFudHJvX2F2MV9nZXRfZnJh bWVfaW5kZXgoc3RydWN0IGhhbnRyb19jdHggKmN0eCwgaW50IHJlZikKPj4gK3sKPj4gK8KgwqDC oCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfaHdfY3R4ICphdjFfZGVjID0gJmN0eC0+YXYxX2RlYzsK Pj4gK8KgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfY3RybHMgKmN0cmxzID0gJmF2MV9kZWMt PmN0cmxzOwo+PiArwqDCoMKgIGNvbnN0IHN0cnVjdCB2NGwyX2N0cmxfYXYxX2ZyYW1lICpmcmFt ZSA9IGN0cmxzLT5mcmFtZTsKPj4gK8KgwqDCoCB1NjQgdGltZXN0YW1wOwo+PiArwqDCoMKgIGlu dCBpLCBpZHg7Cj4+ICsKPj4gK8KgwqDCoCBpZiAocmVmIDwgMCB8fCByZWYgPj0gVjRMMl9BVjFf UkVGU19QRVJfRlJBTUUpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gQVYxX0lOVkFMSURfSURY Owo+PiArCj4+ICvCoMKgwqAgaWR4ID0gZnJhbWUtPnJlZl9mcmFtZV9pZHhbcmVmXTsKPj4gKwo+ PiArwqDCoMKgIGlmIChpZHggPj0gVjRMMl9BVjFfVE9UQUxfUkVGU19QRVJfRlJBTUUgfHwgaWR4 IDwgMCkKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiBBVjFfSU5WQUxJRF9JRFg7Cj4+ICsKPj4g K8KgwqDCoCB0aW1lc3RhbXAgPSBmcmFtZS0+cmVmZXJlbmNlX2ZyYW1lX3RzW2lkeF07Cj4+ICvC oMKgwqAgZm9yIChpID0gMDsgaSA8IEFWMV9NQVhfRlJBTUVfQlVGX0NPVU5UOyBpKyspIHsKPj4g K8KgwqDCoMKgwqDCoMKgIGlmICghYXYxX2RlYy0+ZnJhbWVfcmVmc1tpXS51c2VkKQo+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBjb250aW51ZTsKPj4gK8KgwqDCoMKgwqDCoMKgIGlmIChhdjFf ZGVjLT5mcmFtZV9yZWZzW2ldLnRpbWVzdGFtcCA9PSB0aW1lc3RhbXApCj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIHJldHVybiBpOwo+PiArwqDCoMKgIH0KPj4gKwo+PiArwqDCoMKgIHJldHVy biBBVjFfSU5WQUxJRF9JRFg7Cj4+ICt9Cj4+ICsKPj4gK2ludCBoYW50cm9fYXYxX2dldF9vcmRl cl9oaW50KHN0cnVjdCBoYW50cm9fY3R4ICpjdHgsIGludCByZWYpCj4+ICt7Cj4+ICvCoMKgwqAg c3RydWN0IGhhbnRyb19hdjFfZGVjX2h3X2N0eCAqYXYxX2RlYyA9ICZjdHgtPmF2MV9kZWM7Cj4+ ICvCoMKgwqAgaW50IGlkeCA9IGhhbnRyb19hdjFfZ2V0X2ZyYW1lX2luZGV4KGN0eCwgcmVmKTsK Pj4gKwo+PiArwqDCoMKgIGlmIChpZHggIT0gQVYxX0lOVkFMSURfSURYKQo+PiArwqDCoMKgwqDC oMKgwqAgcmV0dXJuIGF2MV9kZWMtPmZyYW1lX3JlZnNbaWR4XS5vcmRlcl9oaW50Owo+PiArCj4+ ICvCoMKgwqAgcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK2ludCBoYW50cm9fYXYxX2ZyYW1lX3Jl ZihzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4LCB1NjQgdGltZXN0YW1wKQo+PiArewo+PiArwqDCoMKg IHN0cnVjdCBoYW50cm9fYXYxX2RlY19od19jdHggKmF2MV9kZWMgPSAmY3R4LT5hdjFfZGVjOwo+ PiArwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19jdHJscyAqY3RybHMgPSAmYXYxX2RlYy0+ Y3RybHM7Cj4+ICvCoMKgwqAgY29uc3Qgc3RydWN0IHY0bDJfY3RybF9hdjFfZnJhbWUgKmZyYW1l ID0gY3RybHMtPmZyYW1lOwo+PiArwqDCoMKgIGludCBpOwo+PiArCj4+ICvCoMKgwqAgZm9yIChp ID0gMDsgaSA8IEFWMV9NQVhfRlJBTUVfQlVGX0NPVU5UOyBpKyspIHsKPj4gK8KgwqDCoMKgwqDC oMKgIGludCBqOwo+PiArCj4+ICvCoMKgwqDCoMKgwqDCoCBpZiAoYXYxX2RlYy0+ZnJhbWVfcmVm c1tpXS51c2VkKQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBjb250aW51ZTsKPj4gKwo+PiAr wqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+ZnJhbWVfcmVmc1tpXS53aWR0aCA9IGZyYW1lLT5mcmFt ZV93aWR0aF9taW51c18xICsgMTsKPj4gK8KgwqDCoMKgwqDCoMKgIGF2MV9kZWMtPmZyYW1lX3Jl ZnNbaV0uaGVpZ2h0ID0gZnJhbWUtPmZyYW1lX2hlaWdodF9taW51c18xIAo+PiArIDE7Cj4+ICvC oMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5mcmFtZV9yZWZzW2ldLm1pX2NvbHMgPSAKPj4gRElWX1JP VU5EX1VQKGZyYW1lLT5mcmFtZV93aWR0aF9taW51c18xICsgMSwgOCk7Cj4+ICvCoMKgwqDCoMKg wqDCoCBhdjFfZGVjLT5mcmFtZV9yZWZzW2ldLm1pX3Jvd3MgPSAKPj4gRElWX1JPVU5EX1VQKGZy YW1lLT5mcmFtZV9oZWlnaHRfbWludXNfMSArIDEsIDgpOwo+PiArwqDCoMKgwqDCoMKgwqAgYXYx X2RlYy0+ZnJhbWVfcmVmc1tpXS50aW1lc3RhbXAgPSB0aW1lc3RhbXA7Cj4+ICvCoMKgwqDCoMKg wqDCoCBhdjFfZGVjLT5mcmFtZV9yZWZzW2ldLmZyYW1lX3R5cGUgPSBmcmFtZS0+ZnJhbWVfdHlw ZTsKPj4gK8KgwqDCoMKgwqDCoMKgIGF2MV9kZWMtPmZyYW1lX3JlZnNbaV0ub3JkZXJfaGludCA9 IGZyYW1lLT5vcmRlcl9oaW50Owo+PiArwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+ZnJhbWVfcmVm c1tpXS52YjJfcmVmID0gaGFudHJvX2dldF9kc3RfYnVmKGN0eCk7Cj4+ICsKPj4gK8KgwqDCoMKg wqDCoMKgIGZvciAoaiA9IDA7IGogPCBWNEwyX0FWMV9UT1RBTF9SRUZTX1BFUl9GUkFNRTsgaisr KQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5mcmFtZV9yZWZzW2ldLm9yZGVy X2hpbnRzW2pdID0gCj4+IGZyYW1lLT5vcmRlcl9oaW50c1tqXTsKPj4gK8KgwqDCoMKgwqDCoMKg IGF2MV9kZWMtPmZyYW1lX3JlZnNbaV0udXNlZCA9IHRydWU7Cj4+ICvCoMKgwqDCoMKgwqDCoCBh djFfZGVjLT5jdXJyZW50X2ZyYW1lX2luZGV4ID0gaTsKPj4gKwo+PiArwqDCoMKgwqDCoMKgwqAg cmV0dXJuIGk7Cj4+ICvCoMKgwqAgfQo+PiArCj4+ICvCoMKgwqAgcmV0dXJuIEFWMV9JTlZBTElE X0lEWDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgaGFudHJvX2F2MV9mcmFtZV91bnJlZihz dHJ1Y3QgaGFudHJvX2N0eCAqY3R4LCBpbnQgaWR4KQo+PiArewo+PiArwqDCoMKgIHN0cnVjdCBo YW50cm9fYXYxX2RlY19od19jdHggKmF2MV9kZWMgPSAmY3R4LT5hdjFfZGVjOwo+PiArCj4+ICvC oMKgwqAgaWYgKGlkeCA+PSAwKQo+PiArwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+ZnJhbWVfcmVm c1tpZHhdLnVzZWQgPSBmYWxzZTsKPj4gK30KPj4gKwo+PiArdm9pZCBoYW50cm9fYXYxX2NsZWFu X3JlZnMoc3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gK3sKPj4gK8KgwqDCoCBzdHJ1Y3QgaGFu dHJvX2F2MV9kZWNfaHdfY3R4ICphdjFfZGVjID0gJmN0eC0+YXYxX2RlYzsKPj4gK8KgwqDCoCBz dHJ1Y3QgaGFudHJvX2F2MV9kZWNfY3RybHMgKmN0cmxzID0gJmF2MV9kZWMtPmN0cmxzOwo+PiAr Cj4+ICvCoMKgwqAgaW50IHJlZiwgaWR4Owo+PiArCj4+ICvCoMKgwqAgZm9yIChpZHggPSAwOyBp ZHggPCBBVjFfTUFYX0ZSQU1FX0JVRl9DT1VOVDsgaWR4KyspIHsKPj4gK8KgwqDCoMKgwqDCoMKg IHU2NCB0aW1lc3RhbXAgPSBhdjFfZGVjLT5mcmFtZV9yZWZzW2lkeF0udGltZXN0YW1wOwo+PiAr wqDCoMKgwqDCoMKgwqAgYm9vbCB1c2VkID0gZmFsc2U7Cj4+ICsKPj4gK8KgwqDCoMKgwqDCoMKg IGlmICghYXYxX2RlYy0+ZnJhbWVfcmVmc1tpZHhdLnVzZWQpCj4+ICvCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIGNvbnRpbnVlOwo+PiArCj4+ICvCoMKgwqDCoMKgwqDCoCBmb3IgKHJlZiA9IDA7IHJl ZiA8IFY0TDJfQVYxX1RPVEFMX1JFRlNfUEVSX0ZSQU1FOyByZWYrKykgewo+PiArwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCBpZiAoY3RybHMtPmZyYW1lLT5yZWZlcmVuY2VfZnJhbWVfdHNbcmVmXSA9 PSB0aW1lc3RhbXApCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdXNlZCA9IHRy dWU7Cj4+ICvCoMKgwqDCoMKgwqDCoCB9Cj4+ICsKPj4gK8KgwqDCoMKgwqDCoMKgIGlmICghdXNl ZCkKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaGFudHJvX2F2MV9mcmFtZV91bnJlZihjdHgs IGlkeCk7Cj4+ICvCoMKgwqAgfQo+PiArfQo+PiArCj4+ICtzaXplX3QgaGFudHJvX2F2MV9sdW1h X3NpemUoc3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gK3sKPj4gK8KgwqDCoCByZXR1cm4gY3R4 LT5yZWZfZm10LnBsYW5lX2ZtdFswXS5ieXRlc3BlcmxpbmUgKiAKPj4gY3R4LT5yZWZfZm10Lmhl aWdodDsKPj4gK30KPj4gKwo+PiArc2l6ZV90IGhhbnRyb19hdjFfY2hyb21hX3NpemUoc3RydWN0 IGhhbnRyb19jdHggKmN0eCkKPj4gK3sKPj4gK8KgwqDCoCBzaXplX3QgY3Jfb2Zmc2V0ID0gaGFu dHJvX2F2MV9sdW1hX3NpemUoY3R4KTsKPj4gKwo+PiArwqDCoMKgIHJldHVybiBBTElHTigoY3Jf b2Zmc2V0ICogMykgLyAyLCA2NCk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGhhbnRyb19h djFfdGlsZXNfZnJlZShzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4KQo+PiArewo+PiArwqDCoMKgIHN0 cnVjdCBoYW50cm9fZGV2ICp2cHUgPSBjdHgtPmRldjsKPj4gK8KgwqDCoCBzdHJ1Y3QgaGFudHJv X2F2MV9kZWNfaHdfY3R4ICphdjFfZGVjID0gJmN0eC0+YXYxX2RlYzsKPj4gKwo+PiArwqDCoMKg IGlmIChhdjFfZGVjLT5kYl9kYXRhX2NvbC5jcHUpCj4+ICvCoMKgwqDCoMKgwqDCoCBkbWFfZnJl ZV9jb2hlcmVudCh2cHUtPmRldiwgYXYxX2RlYy0+ZGJfZGF0YV9jb2wuc2l6ZSwKPj4gK8KgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+ZGJfZGF0YV9jb2wuY3B1LAo+ PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5kYl9kYXRhX2Nv bC5kbWEpOwo+PiArwqDCoMKgIGF2MV9kZWMtPmRiX2RhdGFfY29sLmNwdSA9IE5VTEw7Cj4+ICsK Pj4gK8KgwqDCoCBpZiAoYXYxX2RlYy0+ZGJfY3RybF9jb2wuY3B1KQo+PiArwqDCoMKgwqDCoMKg wqAgZG1hX2ZyZWVfY29oZXJlbnQodnB1LT5kZXYsIGF2MV9kZWMtPmRiX2N0cmxfY29sLnNpemUs Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGF2MV9kZWMtPmRiX2N0cmxf Y29sLmNwdSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+ ZGJfY3RybF9jb2wuZG1hKTsKPj4gK8KgwqDCoCBhdjFfZGVjLT5kYl9jdHJsX2NvbC5jcHUgPSBO VUxMOwo+PiArCj4+ICvCoMKgwqAgaWYgKGF2MV9kZWMtPmNkZWZfY29sLmNwdSkKPj4gK8KgwqDC oMKgwqDCoMKgIGRtYV9mcmVlX2NvaGVyZW50KHZwdS0+ZGV2LCBhdjFfZGVjLT5jZGVmX2NvbC5z aXplLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5jZGVm X2NvbC5jcHUsIGF2MV9kZWMtPmNkZWZfY29sLmRtYSk7Cj4+ICvCoMKgwqAgYXYxX2RlYy0+Y2Rl Zl9jb2wuY3B1ID0gTlVMTDsKPj4gKwo+PiArwqDCoMKgIGlmIChhdjFfZGVjLT5zcl9jb2wuY3B1 KQo+PiArwqDCoMKgwqDCoMKgwqAgZG1hX2ZyZWVfY29oZXJlbnQodnB1LT5kZXYsIGF2MV9kZWMt PnNyX2NvbC5zaXplLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFf ZGVjLT5zcl9jb2wuY3B1LCBhdjFfZGVjLT5zcl9jb2wuZG1hKTsKPj4gK8KgwqDCoCBhdjFfZGVj LT5zcl9jb2wuY3B1ID0gTlVMTDsKPj4gKwo+PiArwqDCoMKgIGlmIChhdjFfZGVjLT5scl9jb2wu Y3B1KQo+PiArwqDCoMKgwqDCoMKgwqAgZG1hX2ZyZWVfY29oZXJlbnQodnB1LT5kZXYsIGF2MV9k ZWMtPmxyX2NvbC5zaXplLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBh djFfZGVjLT5scl9jb2wuY3B1LCBhdjFfZGVjLT5scl9jb2wuZG1hKTsKPj4gK8KgwqDCoCBhdjFf ZGVjLT5scl9jb2wuY3B1ID0gTlVMTDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBoYW50cm9f YXYxX3RpbGVzX3JlYWxsb2NhdGUoc3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gK3sKPj4gK8Kg wqDCoCBzdHJ1Y3QgaGFudHJvX2RldiAqdnB1ID0gY3R4LT5kZXY7Cj4+ICvCoMKgwqAgc3RydWN0 IGhhbnRyb19hdjFfZGVjX2h3X2N0eCAqYXYxX2RlYyA9ICZjdHgtPmF2MV9kZWM7Cj4+ICvCoMKg wqAgc3RydWN0IGhhbnRyb19hdjFfZGVjX2N0cmxzICpjdHJscyA9ICZhdjFfZGVjLT5jdHJsczsK Pj4gK8KgwqDCoCBjb25zdCBzdHJ1Y3QgdjRsMl9hdjFfdGlsZV9pbmZvICp0aWxlX2luZm8gPSAK Pj4gJmN0cmxzLT5mcmFtZS0+dGlsZV9pbmZvOwo+PiArwqDCoMKgIHVuc2lnbmVkIGludCBudW1f dGlsZV9jb2xzID0gdGlsZV9pbmZvLT50aWxlX2NvbHM7Cj4+ICvCoMKgwqAgdW5zaWduZWQgaW50 IGhlaWdodCA9IEFMSUdOKGN0cmxzLT5mcmFtZS0+ZnJhbWVfaGVpZ2h0X21pbnVzXzEgKyAKPj4g MSwgNjQpOwo+PiArwqDCoMKgIHVuc2lnbmVkIGludCBoZWlnaHRfaW5fc2IgPSBoZWlnaHQgLyA2 NDsKPj4gK8KgwqDCoCB1bnNpZ25lZCBpbnQgc3RyaXBlX251bSA9ICgoaGVpZ2h0ICsgOCkgKyA2 MykgLyA2NDsKPj4gK8KgwqDCoCBzaXplX3Qgc2l6ZTsKPj4gKwo+PiArwqDCoMKgIGlmIChhdjFf ZGVjLT5kYl9kYXRhX2NvbC5zaXplID49Cj4+ICvCoMKgwqDCoMKgwqDCoCBBTElHTihoZWlnaHQg KiAxMiAqIGN0eC0+Yml0X2RlcHRoIC8gOCwgMTI4KSAqIG51bV90aWxlX2NvbHMpCj4+ICvCoMKg wqDCoMKgwqDCoCByZXR1cm4gMDsKPj4gKwo+PiArwqDCoMKgIGhhbnRyb19hdjFfdGlsZXNfZnJl ZShjdHgpOwo+PiArCj4+ICvCoMKgwqAgc2l6ZSA9IEFMSUdOKGhlaWdodCAqIDEyICogY3R4LT5i aXRfZGVwdGggLyA4LCAxMjgpICogCj4+IG51bV90aWxlX2NvbHM7Cj4+ICvCoMKgwqAgYXYxX2Rl Yy0+ZGJfZGF0YV9jb2wuY3B1ID0gZG1hX2FsbG9jX2NvaGVyZW50KHZwdS0+ZGV2LCBzaXplLAo+ PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCAmYXYxX2RlYy0+ZGJfZGF0YV9jb2wuZG1hLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBHRlBfS0VSTkVMKTsKPj4gK8Kg wqDCoCBpZiAoIWF2MV9kZWMtPmRiX2RhdGFfY29sLmNwdSkKPj4gK8KgwqDCoMKgwqDCoMKgIGdv dG8gYnVmZmVyX2FsbG9jYXRpb25fZXJyb3I7Cj4+ICvCoMKgwqAgYXYxX2RlYy0+ZGJfZGF0YV9j b2wuc2l6ZSA9IHNpemU7Cj4+ICsKPj4gK8KgwqDCoCBzaXplID0gQUxJR04oaGVpZ2h0ICogMiAq IDE2IC8gNCwgMTI4KSAqIG51bV90aWxlX2NvbHM7Cj4+ICvCoMKgwqAgYXYxX2RlYy0+ZGJfY3Ry bF9jb2wuY3B1ID0gZG1hX2FsbG9jX2NvaGVyZW50KHZwdS0+ZGV2LCBzaXplLAo+PiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAmYXYx X2RlYy0+ZGJfY3RybF9jb2wuZG1hLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBHRlBfS0VSTkVMKTsKPj4gK8KgwqDCoCBpZiAo IWF2MV9kZWMtPmRiX2N0cmxfY29sLmNwdSkKPj4gK8KgwqDCoMKgwqDCoMKgIGdvdG8gYnVmZmVy X2FsbG9jYXRpb25fZXJyb3I7Cj4+ICvCoMKgwqAgYXYxX2RlYy0+ZGJfY3RybF9jb2wuc2l6ZSA9 IHNpemU7Cj4+ICsKPj4gK8KgwqDCoCBzaXplID0gQUxJR04oaGVpZ2h0X2luX3NiICogNDQgKiBj dHgtPmJpdF9kZXB0aCAqIDE2IC8gOCwgMTI4KSAqIAo+PiBudW1fdGlsZV9jb2xzOwo+PiArwqDC oMKgIGF2MV9kZWMtPmNkZWZfY29sLmNwdSA9IGRtYV9hbGxvY19jb2hlcmVudCh2cHUtPmRldiwg c2l6ZSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgJmF2MV9kZWMtPmNkZWZfY29sLmRtYSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgR0ZQX0tFUk5FTCk7Cj4+ICvCoMKgwqAgaWYg KCFhdjFfZGVjLT5jZGVmX2NvbC5jcHUpCj4+ICvCoMKgwqDCoMKgwqDCoCBnb3RvIGJ1ZmZlcl9h bGxvY2F0aW9uX2Vycm9yOwo+PiArwqDCoMKgIGF2MV9kZWMtPmNkZWZfY29sLnNpemUgPSBzaXpl Owo+PiArCj4+ICvCoMKgwqAgc2l6ZSA9IEFMSUdOKGhlaWdodF9pbl9zYiAqICgzMDQwICsgMTI4 MCksIDEyOCkgKiBudW1fdGlsZV9jb2xzOwo+PiArwqDCoMKgIGF2MV9kZWMtPnNyX2NvbC5jcHUg PSBkbWFfYWxsb2NfY29oZXJlbnQodnB1LT5kZXYsIHNpemUsCj4+ICvCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgJmF2MV9kZWMtPnNyX2NvbC5kbWEsCj4+ ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgR0ZQX0tF Uk5FTCk7Cj4+ICvCoMKgwqAgaWYgKCFhdjFfZGVjLT5zcl9jb2wuY3B1KQo+PiArwqDCoMKgwqDC oMKgwqAgZ290byBidWZmZXJfYWxsb2NhdGlvbl9lcnJvcjsKPj4gK8KgwqDCoCBhdjFfZGVjLT5z cl9jb2wuc2l6ZSA9IHNpemU7Cj4+ICsKPj4gK8KgwqDCoCBzaXplID0gQUxJR04oc3RyaXBlX251 bSAqIDE1MzYgKiBjdHgtPmJpdF9kZXB0aCAvIDgsIDEyOCkgKiAKPj4gbnVtX3RpbGVfY29sczsK Pj4gK8KgwqDCoCBhdjFfZGVjLT5scl9jb2wuY3B1ID0gZG1hX2FsbG9jX2NvaGVyZW50KHZwdS0+ ZGV2LCBzaXplLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgICZhdjFfZGVjLT5scl9jb2wuZG1hLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEdGUF9LRVJORUwpOwo+PiArwqDCoMKgIGlmICghYXYx X2RlYy0+bHJfY29sLmNwdSkKPj4gK8KgwqDCoMKgwqDCoMKgIGdvdG8gYnVmZmVyX2FsbG9jYXRp b25fZXJyb3I7Cj4+ICvCoMKgwqAgYXYxX2RlYy0+bHJfY29sLnNpemUgPSBzaXplOwo+PiArCj4+ ICvCoMKgwqAgYXYxX2RlYy0+bnVtX3RpbGVfY29sc19hbGxvY2F0ZWQgPSBudW1fdGlsZV9jb2xz Owo+PiArwqDCoMKgIHJldHVybiAwOwo+PiArCj4+ICtidWZmZXJfYWxsb2NhdGlvbl9lcnJvcjoK Pj4gK8KgwqDCoCBoYW50cm9fYXYxX3RpbGVzX2ZyZWUoY3R4KTsKPj4gK8KgwqDCoCByZXR1cm4g LUVOT01FTTsKPj4gK30KPj4gKwo+PiArdm9pZCBoYW50cm9fYXYxX2V4aXQoc3RydWN0IGhhbnRy b19jdHggKmN0eCkKPj4gK3sKPj4gK8KgwqDCoCBzdHJ1Y3QgaGFudHJvX2RldiAqdnB1ID0gY3R4 LT5kZXY7Cj4+ICvCoMKgwqAgc3RydWN0IGhhbnRyb19hdjFfZGVjX2h3X2N0eCAqYXYxX2RlYyA9 ICZjdHgtPmF2MV9kZWM7Cj4+ICsKPj4gK8KgwqDCoCBpZiAoYXYxX2RlYy0+Z2xvYmFsX21vZGVs LmNwdSkKPj4gK8KgwqDCoMKgwqDCoMKgIGRtYV9mcmVlX2NvaGVyZW50KHZwdS0+ZGV2LCBhdjFf ZGVjLT5nbG9iYWxfbW9kZWwuc2l6ZSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgYXYxX2RlYy0+Z2xvYmFsX21vZGVsLmNwdSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+Z2xvYmFsX21vZGVsLmRtYSk7Cj4+ICvCoMKgwqAgYXYx X2RlYy0+Z2xvYmFsX21vZGVsLmNwdSA9IE5VTEw7Cj4+ICsKPj4gK8KgwqDCoCBpZiAoYXYxX2Rl Yy0+dGlsZV9pbmZvLmNwdSkKPj4gK8KgwqDCoMKgwqDCoMKgIGRtYV9mcmVlX2NvaGVyZW50KHZw dS0+ZGV2LCBhdjFfZGVjLT50aWxlX2luZm8uc2l6ZSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+dGlsZV9pbmZvLmNwdSwKPj4gK8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+dGlsZV9pbmZvLmRtYSk7Cj4+ICvCoMKgwqAg YXYxX2RlYy0+dGlsZV9pbmZvLmNwdSA9IE5VTEw7Cj4+ICsKPj4gK8KgwqDCoCBpZiAoYXYxX2Rl Yy0+ZmlsbV9ncmFpbi5jcHUpCj4+ICvCoMKgwqDCoMKgwqDCoCBkbWFfZnJlZV9jb2hlcmVudCh2 cHUtPmRldiwgYXYxX2RlYy0+ZmlsbV9ncmFpbi5zaXplLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5maWxtX2dyYWluLmNwdSwKPj4gK8KgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+ZmlsbV9ncmFpbi5kbWEpOwo+PiArwqDC oMKgIGF2MV9kZWMtPmZpbG1fZ3JhaW4uY3B1ID0gTlVMTDsKPj4gKwo+PiArwqDCoMKgIGlmIChh djFfZGVjLT5wcm9iX3RibC5jcHUpCj4+ICvCoMKgwqDCoMKgwqDCoCBkbWFfZnJlZV9jb2hlcmVu dCh2cHUtPmRldiwgYXYxX2RlYy0+cHJvYl90Ymwuc2l6ZSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+cHJvYl90YmwuY3B1LCBhdjFfZGVjLT5wcm9iX3Ri bC5kbWEpOwo+PiArwqDCoMKgIGF2MV9kZWMtPnByb2JfdGJsLmNwdSA9IE5VTEw7Cj4+ICsKPj4g K8KgwqDCoCBpZiAoYXYxX2RlYy0+cHJvYl90Ymxfb3V0LmNwdSkKPj4gK8KgwqDCoMKgwqDCoMKg IGRtYV9mcmVlX2NvaGVyZW50KHZwdS0+ZGV2LCBhdjFfZGVjLT5wcm9iX3RibF9vdXQuc2l6ZSwK Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+cHJvYl90Ymxf b3V0LmNwdSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+ cHJvYl90Ymxfb3V0LmRtYSk7Cj4+ICvCoMKgwqAgYXYxX2RlYy0+cHJvYl90Ymxfb3V0LmNwdSA9 IE5VTEw7Cj4+ICsKPj4gK8KgwqDCoCBpZiAoYXYxX2RlYy0+dGlsZV9idWYuY3B1KQo+PiArwqDC oMKgwqDCoMKgwqAgZG1hX2ZyZWVfY29oZXJlbnQodnB1LT5kZXYsIGF2MV9kZWMtPnRpbGVfYnVm LnNpemUsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGF2MV9kZWMtPnRp bGVfYnVmLmNwdSwgYXYxX2RlYy0+dGlsZV9idWYuZG1hKTsKPj4gK8KgwqDCoCBhdjFfZGVjLT50 aWxlX2J1Zi5jcHUgPSBOVUxMOwo+PiArCj4+ICvCoMKgwqAgaGFudHJvX2F2MV90aWxlc19mcmVl KGN0eCk7Cj4+ICt9Cj4+ICsKPj4gK2ludCBoYW50cm9fYXYxX2luaXQoc3RydWN0IGhhbnRyb19j dHggKmN0eCkKPj4gK3sKPj4gK8KgwqDCoCBzdHJ1Y3QgaGFudHJvX2RldiAqdnB1ID0gY3R4LT5k ZXY7Cj4+ICvCoMKgwqAgc3RydWN0IGhhbnRyb19hdjFfZGVjX2h3X2N0eCAqYXYxX2RlYyA9ICZj dHgtPmF2MV9kZWM7Cj4+ICsKPj4gK8KgwqDCoCBtZW1zZXQoYXYxX2RlYywgMCwgc2l6ZW9mKCph djFfZGVjKSk7Cj4+ICsKPj4gK8KgwqDCoCBhdjFfZGVjLT5nbG9iYWxfbW9kZWwuY3B1ID0gZG1h X2FsbG9jX2NvaGVyZW50KHZwdS0+ZGV2LCAKPj4gR0xPQkFMX01PREVMX1NJWkUsCj4+ICsgJmF2 MV9kZWMtPmdsb2JhbF9tb2RlbC5kbWEsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgR0ZQX0tFUk5FTCk7Cj4+ICvCoMKgwqAg aWYgKCFhdjFfZGVjLT5nbG9iYWxfbW9kZWwuY3B1KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJu IC1FTk9NRU07Cj4+ICvCoMKgwqAgYXYxX2RlYy0+Z2xvYmFsX21vZGVsLnNpemUgPSBHTE9CQUxf TU9ERUxfU0laRTsKPj4gKwo+PiArwqDCoMKgIGF2MV9kZWMtPnRpbGVfaW5mby5jcHUgPSBkbWFf YWxsb2NfY29oZXJlbnQodnB1LT5kZXYsIAo+PiBBVjFfVElMRV9JTkZPX1NJWkUsCj4+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgJmF2MV9k ZWMtPnRpbGVfaW5mby5kbWEsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgR0ZQX0tFUk5FTCk7Cj4+ICvCoMKgwqAgaWYgKCFhdjFfZGVj LT50aWxlX2luZm8uY3B1KQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FTk9NRU07Cj4+ICvC oMKgwqAgYXYxX2RlYy0+dGlsZV9pbmZvLnNpemUgPSBBVjFfVElMRV9JTkZPX1NJWkU7Cj4+ICsK Pj4gK8KgwqDCoCBhdjFfZGVjLT5maWxtX2dyYWluLmNwdSA9IGRtYV9hbGxvY19jb2hlcmVudCh2 cHUtPmRldiwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIEFMSUdOKHNpemVvZihzdHJ1Y3QgCj4+IGhhbnRyb19hdjFfZmlsbV9ncmFp biksCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgMjA0OCksCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAmYXYxX2RlYy0+ZmlsbV9ncmFpbi5kbWEsCj4+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBHRlBf S0VSTkVMKTsKPj4gK8KgwqDCoCBpZiAoIWF2MV9kZWMtPmZpbG1fZ3JhaW4uY3B1KQo+PiArwqDC oMKgwqDCoMKgwqAgcmV0dXJuIC1FTk9NRU07Cj4+ICvCoMKgwqAgYXYxX2RlYy0+ZmlsbV9ncmFp bi5zaXplID0gQUxJR04oc2l6ZW9mKHN0cnVjdCAKPj4gaGFudHJvX2F2MV9maWxtX2dyYWluKSwg MjA0OCk7Cj4+ICsKPj4gK8KgwqDCoCBhdjFfZGVjLT5wcm9iX3RibC5jcHUgPSBkbWFfYWxsb2Nf Y29oZXJlbnQodnB1LT5kZXYsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIEFMSUdOKHNpemVvZihzdHJ1Y3QgYXYxY2RmcyksIDIwNDgpLAo+ PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAm YXYxX2RlYy0+cHJvYl90YmwuZG1hLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBHRlBfS0VSTkVMKTsKPj4gK8KgwqDCoCBpZiAoIWF2MV9k ZWMtPnByb2JfdGJsLmNwdSkKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybiAtRU5PTUVNOwo+PiAr wqDCoMKgIGF2MV9kZWMtPnByb2JfdGJsLnNpemUgPSBBTElHTihzaXplb2Yoc3RydWN0IGF2MWNk ZnMpLCAyMDQ4KTsKPj4gKwo+PiArwqDCoMKgIGF2MV9kZWMtPnByb2JfdGJsX291dC5jcHUgPSBk bWFfYWxsb2NfY29oZXJlbnQodnB1LT5kZXYsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgQUxJR04oc2l6ZW9mKHN0cnVjdCBh djFjZGZzKSwgMjA0OCksCj4+ICsgJmF2MV9kZWMtPnByb2JfdGJsX291dC5kbWEsCj4+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg R0ZQX0tFUk5FTCk7Cj4+ICvCoMKgwqAgaWYgKCFhdjFfZGVjLT5wcm9iX3RibF9vdXQuY3B1KQo+ PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FTk9NRU07Cj4+ICvCoMKgwqAgYXYxX2RlYy0+cHJv Yl90Ymxfb3V0LnNpemUgPSBBTElHTihzaXplb2Yoc3RydWN0IGF2MWNkZnMpLCAyMDQ4KTsKPj4g K8KgwqDCoCBhdjFfZGVjLT5jZGZzID0gJmF2MV9kZWMtPmRlZmF1bHRfY2RmczsKPj4gK8KgwqDC oCBhdjFfZGVjLT5jZGZzX25kdmMgPSAmYXYxX2RlYy0+ZGVmYXVsdF9jZGZzX25kdmM7Cj4+ICsK Pj4gK8KgwqDCoCBoYW50cm9fYXYxX3NldF9kZWZhdWx0X2NkZnMoYXYxX2RlYy0+Y2RmcywgYXYx X2RlYy0+Y2Rmc19uZHZjKTsKPj4gKwo+PiArwqDCoMKgIGF2MV9kZWMtPnRpbGVfYnVmLmNwdSA9 IGRtYV9hbGxvY19jb2hlcmVudCh2cHUtPmRldiwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgQVYxX1RJTEVfU0laRSwKPj4gK8KgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgJmF2MV9kZWMtPnRp bGVfYnVmLmRtYSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgR0ZQX0tFUk5FTCk7Cj4+ICvCoMKgwqAgaWYgKCFhdjFfZGVjLT50aWxlX2J1 Zi5jcHUpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVOT01FTTsKPj4gK8KgwqDCoCBhdjFf ZGVjLT50aWxlX2J1Zi5zaXplID0gQVYxX1RJTEVfU0laRTsKPj4gKwo+PiArwqDCoMKgIHJldHVy biAwOwo+PiArfQo+PiArCj4+ICtpbnQgaGFudHJvX2F2MV9wcmVwYXJlX3J1bihzdHJ1Y3QgaGFu dHJvX2N0eCAqY3R4KQo+PiArewo+PiArwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19od19j dHggKmF2MV9kZWMgPSAmY3R4LT5hdjFfZGVjOwo+PiArwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYx X2RlY19jdHJscyAqY3RybHMgPSAmYXYxX2RlYy0+Y3RybHM7Cj4+ICsKPj4gK8KgwqDCoCBjdHJs cy0+c2VxdWVuY2UgPSBoYW50cm9fZ2V0X2N0cmwoY3R4LCAKPj4gVjRMMl9DSURfU1RBVEVMRVNT X0FWMV9TRVFVRU5DRSk7Cj4+ICvCoMKgwqAgaWYgKFdBUk5fT04oIWN0cmxzLT5zZXF1ZW5jZSkp Cj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVJTlZBTDsKPj4gKwo+PiArwqDCoMKgIGN0cmxz LT50aWxlX2dyb3VwX2VudHJ5ID0KPj4gK8KgwqDCoMKgwqDCoMKgIGhhbnRyb19nZXRfY3RybChj dHgsIFY0TDJfQ0lEX1NUQVRFTEVTU19BVjFfVElMRV9HUk9VUF9FTlRSWSk7Cj4+ICvCoMKgwqAg aWYgKFdBUk5fT04oIWN0cmxzLT50aWxlX2dyb3VwX2VudHJ5KSkKPj4gK8KgwqDCoMKgwqDCoMKg IHJldHVybiAtRUlOVkFMOwo+PiArCj4+ICvCoMKgwqAgY3RybHMtPmZyYW1lID0gaGFudHJvX2dl dF9jdHJsKGN0eCwgVjRMMl9DSURfU1RBVEVMRVNTX0FWMV9GUkFNRSk7Cj4+ICvCoMKgwqAgaWYg KFdBUk5fT04oIWN0cmxzLT5mcmFtZSkpCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVJTlZB TDsKPj4gKwo+PiArwqDCoMKgIGN0cmxzLT5maWxtX2dyYWluID0KPj4gK8KgwqDCoMKgwqDCoMKg IGhhbnRyb19nZXRfY3RybChjdHgsIFY0TDJfQ0lEX1NUQVRFTEVTU19BVjFfRklMTV9HUkFJTik7 Cj4+ICsKPj4gK8KgwqDCoCByZXR1cm4gaGFudHJvX2F2MV90aWxlc19yZWFsbG9jYXRlKGN0eCk7 Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgaGFudHJvX2F2MV9nZXRfbXNiKHUzMiBuKQo+PiAr ewo+PiArwqDCoMKgIGlmIChuID09IDApCj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gMDsKPj4g K8KgwqDCoCByZXR1cm4gMzEgXiBfX2J1aWx0aW5fY2x6KG4pOwo+PiArfQo+PiArCj4+ICtzdGF0 aWMgc2hvcnQgaGFudHJvX2F2MV9yZXNvbHZlX2Rpdmlzb3JfMzIodTMyIGQsIHNob3J0ICpzaGlm dCkKPj4gK3sKPj4gK8KgwqDCoCBpbnQgZjsKPj4gK8KgwqDCoCB1NjQgZTsKPj4gKwo+PiArwqDC oMKgICpzaGlmdCA9IGhhbnRyb19hdjFfZ2V0X21zYihkKTsKPj4gK8KgwqDCoCAvKiBlIGlzIG9i dGFpbmVkIGZyb20gRCBhZnRlciByZXNldHRpbmcgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgMSAKPj4g Yml0LiAqLwo+PiArwqDCoMKgIGUgPSBkIC0gKCh1MzIpMSA8PCAqc2hpZnQpOwo+PiArwqDCoMKg IC8qIEdldCB0aGUgbW9zdCBzaWduaWZpY2FudCBESVZfTFVUX0JJVFMgKDgpIGJpdHMgb2YgZSBp bnRvIGYgKi8KPj4gK8KgwqDCoCBpZiAoKnNoaWZ0ID4gRElWX0xVVF9CSVRTKQo+PiArwqDCoMKg wqDCoMKgwqAgZiA9IEFWMV9ESVZfUk9VTkRfVVBfUE9XMihlLCAqc2hpZnQgLSBESVZfTFVUX0JJ VFMpOwo+PiArwqDCoMKgIGVsc2UKPj4gK8KgwqDCoMKgwqDCoMKgIGYgPSBlIDw8IChESVZfTFVU X0JJVFMgLSAqc2hpZnQpOwo+PiArwqDCoMKgIGlmIChmID4gRElWX0xVVF9OVU0pCj4+ICvCoMKg wqDCoMKgwqDCoCByZXR1cm4gLTE7Cj4+ICvCoMKgwqAgKnNoaWZ0ICs9IERJVl9MVVRfUFJFQ19C SVRTOwo+PiArwqDCoMKgIC8qIFVzZSBmIGFzIGxvb2t1cCBpbnRvIHRoZSBwcmVjb21wdXRlZCB0 YWJsZSBvZiBtdWx0aXBsaWVycyAqLwo+PiArwqDCoMKgIHJldHVybiBkaXZfbHV0W2ZdOwo+PiAr fQo+PiArCj4+ICtzdGF0aWMgdm9pZCBoYW50cm9fYXYxX2dldF9zaGVhcl9wYXJhbXMoY29uc3Qg dTMyICpwYXJhbXMsIHM2NCAqYWxwaGEsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCBzNjQgKmJldGEsIHM2NCAqZ2FtbWEsIHM2NCAqZGVsdGEpCj4+ICt7Cj4+ICvC oMKgwqAgY29uc3QgaW50ICptYXQgPSBwYXJhbXM7Cj4+ICvCoMKgwqAgc2hvcnQgc2hpZnQ7Cj4+ ICvCoMKgwqAgc2hvcnQgeTsKPj4gK8KgwqDCoCBsb25nIGxvbmcgZ3YsIGR2Owo+PiArCj4+ICvC oMKgwqAgaWYgKG1hdFsyXSA8PSAwKQo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuOwo+PiArCj4+ ICvCoMKgwqAgKmFscGhhID0gY2xhbXBfdmFsKG1hdFsyXSAtICgxIDw8IFdBUlBFRE1PREVMX1BS RUNfQklUUyksIAo+PiBTMTZfTUlOLCBTMTZfTUFYKTsKPj4gK8KgwqDCoCAqYmV0YSA9IGNsYW1w X3ZhbChtYXRbM10sIFMxNl9NSU4sIFMxNl9NQVgpOwo+PiArCj4+ICvCoMKgwqAgeSA9IGhhbnRy b19hdjFfcmVzb2x2ZV9kaXZpc29yXzMyKGFicyhtYXRbMl0pLCAmc2hpZnQpICogKG1hdFsyXSAK Pj4gPCAwID8gLTEgOiAxKTsKPj4gKwo+PiArwqDCoMKgIGd2ID0gKChsb25nIGxvbmcpbWF0WzRd ICogKDEgPDwgV0FSUEVETU9ERUxfUFJFQ19CSVRTKSkgKiB5Owo+PiArCj4+ICvCoMKgwqAgKmdh bW1hID0gY2xhbXBfdmFsKChpbnQpQVYxX0RJVl9ST1VORF9VUF9QT1cyX1NJR05FRChndiwgc2hp ZnQpLCAKPj4gUzE2X01JTiwgUzE2X01BWCk7Cj4+ICsKPj4gK8KgwqDCoCBkdiA9ICgobG9uZyBs b25nKW1hdFszXSAqIG1hdFs0XSkgKiB5Owo+PiArwqDCoMKgICpkZWx0YSA9IGNsYW1wX3ZhbCht YXRbNV0gLQo+PiArwqDCoMKgwqDCoMKgwqAgKGludClBVjFfRElWX1JPVU5EX1VQX1BPVzJfU0lH TkVEKGR2LCBzaGlmdCkgLSAoMSA8PCAKPj4gV0FSUEVETU9ERUxfUFJFQ19CSVRTKSwKPj4gK8Kg wqDCoMKgwqDCoMKgIFMxNl9NSU4sIFMxNl9NQVgpOwo+PiArCj4+ICvCoMKgwqAgKmFscGhhID0g QVYxX0RJVl9ST1VORF9VUF9QT1cyX1NJR05FRCgqYWxwaGEsIAo+PiBXQVJQX1BBUkFNX1JFRFVD RV9CSVRTKQo+PiArwqDCoMKgwqDCoMKgwqDCoCAqICgxIDw8IFdBUlBfUEFSQU1fUkVEVUNFX0JJ VFMpOwo+PiArwqDCoMKgICpiZXRhID0gQVYxX0RJVl9ST1VORF9VUF9QT1cyX1NJR05FRCgqYmV0 YSwgV0FSUF9QQVJBTV9SRURVQ0VfQklUUykKPj4gK8KgwqDCoMKgwqDCoMKgICogKDEgPDwgV0FS UF9QQVJBTV9SRURVQ0VfQklUUyk7Cj4+ICvCoMKgwqAgKmdhbW1hID0gQVYxX0RJVl9ST1VORF9V UF9QT1cyX1NJR05FRCgqZ2FtbWEsIAo+PiBXQVJQX1BBUkFNX1JFRFVDRV9CSVRTKQo+PiArwqDC oMKgwqDCoMKgwqDCoCAqICgxIDw8IFdBUlBfUEFSQU1fUkVEVUNFX0JJVFMpOwo+PiArwqDCoMKg ICpkZWx0YSA9IEFWMV9ESVZfUk9VTkRfVVBfUE9XMl9TSUdORUQoKmRlbHRhLCAKPj4gV0FSUF9Q QVJBTV9SRURVQ0VfQklUUykKPj4gK8KgwqDCoMKgwqDCoMKgICogKDEgPDwgV0FSUF9QQVJBTV9S RURVQ0VfQklUUyk7Cj4+ICt9Cj4+ICsKPj4gK3ZvaWQgaGFudHJvX2F2MV9zZXRfZ2xvYmFsX21v ZGVsKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpCj4+ICt7Cj4+ICvCoMKgwqAgc3RydWN0IGhhbnRy b19hdjFfZGVjX2h3X2N0eCAqYXYxX2RlYyA9ICZjdHgtPmF2MV9kZWM7Cj4+ICvCoMKgwqAgc3Ry dWN0IGhhbnRyb19hdjFfZGVjX2N0cmxzICpjdHJscyA9ICZhdjFfZGVjLT5jdHJsczsKPj4gK8Kg wqDCoCBjb25zdCBzdHJ1Y3QgdjRsMl9jdHJsX2F2MV9mcmFtZSAqZnJhbWUgPSBjdHJscy0+ZnJh bWU7Cj4+ICvCoMKgwqAgY29uc3Qgc3RydWN0IHY0bDJfYXYxX2dsb2JhbF9tb3Rpb24gKmdtID0g JmZyYW1lLT5nbG9iYWxfbW90aW9uOwo+PiArwqDCoMKgIHU4ICpkc3QgPSBhdjFfZGVjLT5nbG9i YWxfbW9kZWwuY3B1Owo+PiArwqDCoMKgIGludCByZWZfZnJhbWUsIGk7Cj4+ICsKPj4gK8KgwqDC oCBtZW1zZXQoZHN0LCAwLCBHTE9CQUxfTU9ERUxfU0laRSk7Cj4+ICvCoMKgwqAgZm9yIChyZWZf ZnJhbWUgPSAwOyByZWZfZnJhbWUgPCBWNEwyX0FWMV9SRUZTX1BFUl9GUkFNRTsgCj4+ICsrcmVm X2ZyYW1lKSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCBzNjQgYWxwaGEgPSAwLCBiZXRhID0gMCwgZ2Ft bWEgPSAwLCBkZWx0YSA9IDA7Cj4+ICsKPj4gK8KgwqDCoMKgwqDCoMKgIGZvciAoaSA9IDA7IGkg PCA2OyArK2kpIHsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKGkgPT0gMikKPj4gK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAqKHMzMiAqKWRzdCA9Cj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBnbS0+cGFyYW1zW1Y0TDJfQVYxX1JFRl9MQVNU X0ZSQU1FICsgcmVmX2ZyYW1lXVszXTsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZWxzZSBp ZiAoaSA9PSAzKQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICooczMyICopZHN0 ID0KPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGdtLT5wYXJhbXNb VjRMMl9BVjFfUkVGX0xBU1RfRlJBTUUgKyByZWZfZnJhbWVdWzJdOwo+PiArwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCBlbHNlCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKihzMzIg Kilkc3QgPQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZ20tPnBh cmFtc1tWNEwyX0FWMV9SRUZfTEFTVF9GUkFNRSArIHJlZl9mcmFtZV1baV07Cj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIGRzdCArPSA0Owo+PiArwqDCoMKgwqDCoMKgwqAgfQo+PiArCj4+ICvC oMKgwqDCoMKgwqDCoCBpZiAoZ20tPnR5cGVbVjRMMl9BVjFfUkVGX0xBU1RfRlJBTUUgKyByZWZf ZnJhbWVdIDw9IAo+PiBWNEwyX0FWMV9XQVJQX01PREVMX0FGRklORSkKPj4gKyBoYW50cm9fYXYx X2dldF9zaGVhcl9wYXJhbXMoJmdtLT5wYXJhbXNbVjRMMl9BVjFfUkVGX0xBU1RfRlJBTUUgKyAK Pj4gcmVmX2ZyYW1lXVswXSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCAmYWxwaGEsICZiZXRhLCAmZ2FtbWEsICZkZWx0YSk7Cj4+ICsK Pj4gK8KgwqDCoMKgwqDCoMKgICooczE2ICopZHN0ID0gYWxwaGE7Cj4+ICvCoMKgwqDCoMKgwqDC oCBkc3QgKz0gMjsKPj4gK8KgwqDCoMKgwqDCoMKgICooczE2ICopZHN0ID0gYmV0YTsKPj4gK8Kg wqDCoMKgwqDCoMKgIGRzdCArPSAyOwo+PiArwqDCoMKgwqDCoMKgwqAgKihzMTYgKilkc3QgPSBn YW1tYTsKPj4gK8KgwqDCoMKgwqDCoMKgIGRzdCArPSAyOwo+PiArwqDCoMKgwqDCoMKgwqAgKihz MTYgKilkc3QgPSBkZWx0YTsKPj4gK8KgwqDCoMKgwqDCoMKgIGRzdCArPSAyOwo+PiArwqDCoMKg IH0KPj4gK30KPj4gKwo+PiAraW50IGhhbnRyb19hdjFfdGlsZV9sb2cyKGludCB0YXJnZXQpCj4+ ICt7Cj4+ICvCoMKgwqAgaW50IGs7Cj4+ICsKPj4gK8KgwqDCoCAvKgo+PiArwqDCoMKgwqAgKiBy ZXR1cm5zIHRoZSBzbWFsbGVzdCB2YWx1ZSBmb3IgayBzdWNoIHRoYXQgMSA8PCBrIGlzIGdyZWF0 ZXIKPj4gK8KgwqDCoMKgICogdGhhbiBvciBlcXVhbCB0byB0YXJnZXQKPj4gK8KgwqDCoMKgICov Cj4+ICvCoMKgwqAgZm9yIChrID0gMDsgKDEgPDwgaykgPCB0YXJnZXQ7IGsrKykKPj4gK8KgwqDC oMKgwqDCoMKgIDsKPj4gKwo+PiArwqDCoMKgIHJldHVybiBrOwo+PiArfQo+PiArCj4+ICtpbnQg aGFudHJvX2F2MV9nZXRfZGlzdChzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4LCBpbnQgYSwgaW50IGIp Cj4+ICt7Cj4+ICvCoMKgwqAgc3RydWN0IGhhbnRyb19hdjFfZGVjX2h3X2N0eCAqYXYxX2RlYyA9 ICZjdHgtPmF2MV9kZWM7Cj4+ICvCoMKgwqAgc3RydWN0IGhhbnRyb19hdjFfZGVjX2N0cmxzICpj dHJscyA9ICZhdjFfZGVjLT5jdHJsczsKPj4gK8KgwqDCoCBpbnQgYml0cyA9IGN0cmxzLT5zZXF1 ZW5jZS0+b3JkZXJfaGludF9iaXRzIC0gMTsKPj4gK8KgwqDCoCBpbnQgZGlmZiwgbTsKPj4gKwo+ PiArwqDCoMKgIGlmICghY3RybHMtPnNlcXVlbmNlLT5vcmRlcl9oaW50X2JpdHMpCj4+ICvCoMKg wqDCoMKgwqDCoCByZXR1cm4gMDsKPj4gKwo+PiArwqDCoMKgIGRpZmYgPSBhIC0gYjsKPj4gK8Kg wqDCoCBtID0gMSA8PCBiaXRzOwo+PiArwqDCoMKgIGRpZmYgPSAoZGlmZiAmIChtIC0gMSkpIC0g KGRpZmYgJiBtKTsKPj4gKwo+PiArwqDCoMKgIHJldHVybiBkaWZmOwo+PiArfQo+PiArCj4+ICt2 b2lkIGhhbnRyb19hdjFfc2V0X2ZyYW1lX3NpZ25fYmlhcyhzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4 KQo+PiArewo+PiArwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19od19jdHggKmF2MV9kZWMg PSAmY3R4LT5hdjFfZGVjOwo+PiArwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19jdHJscyAq Y3RybHMgPSAmYXYxX2RlYy0+Y3RybHM7Cj4+ICvCoMKgwqAgY29uc3Qgc3RydWN0IHY0bDJfY3Ry bF9hdjFfZnJhbWUgKmZyYW1lID0gY3RybHMtPmZyYW1lOwo+PiArwqDCoMKgIGNvbnN0IHN0cnVj dCB2NGwyX2N0cmxfYXYxX3NlcXVlbmNlICpzZXF1ZW5jZSA9IGN0cmxzLT5zZXF1ZW5jZTsKPj4g K8KgwqDCoCBpbnQgaTsKPj4gKwo+PiArwqDCoMKgIGlmICghc2VxdWVuY2UtPm9yZGVyX2hpbnRf Yml0cyB8fCBJU19JTlRSQShmcmFtZS0+ZnJhbWVfdHlwZSkpIHsKPj4gK8KgwqDCoMKgwqDCoMKg IGZvciAoaSA9IDA7IGkgPCBWNEwyX0FWMV9UT1RBTF9SRUZTX1BFUl9GUkFNRTsgaSsrKQo+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5yZWZfZnJhbWVfc2lnbl9iaWFzW2ldID0g MDsKPj4gKwo+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuOwo+PiArwqDCoMKgIH0KPj4gK8KgwqDC oCAvLyBJZGVudGlmeSB0aGUgbmVhcmVzdCBmb3J3YXJkIGFuZCBiYWNrd2FyZCByZWZlcmVuY2Vz Lgo+PiArwqDCoMKgIGZvciAoaSA9IDA7IGkgPCBWNEwyX0FWMV9UT1RBTF9SRUZTX1BFUl9GUkFN RSAtIDE7IGkrKykgewo+PiArwqDCoMKgwqDCoMKgwqAgaWYgKGhhbnRyb19hdjFfZ2V0X2ZyYW1l X2luZGV4KGN0eCwgaSkgPj0gMCkgewo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBpbnQgcmVs X29mZiA9Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaGFudHJvX2F2MV9nZXRf ZGlzdChjdHgsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIGhhbnRyb19hdjFfZ2V0X29yZGVyX2hpbnQoY3R4LCBpKSwKPj4gK8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZnJhbWUtPm9yZGVyX2hpbnQpOwo+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5yZWZfZnJhbWVfc2lnbl9iaWFzW2kgKyAx XSA9IChyZWxfb2ZmIDw9IDApID8gMCAKPj4gOiAxOwo+PiArwqDCoMKgwqDCoMKgwqAgfQo+PiAr wqDCoMKgIH0KPj4gK30KPj4gKwo+PiArdm9pZCBoYW50cm9fYXYxX2luaXRfc2NhbGluZ19mdW5j dGlvbihjb25zdCB1OCAqdmFsdWVzLCBjb25zdCB1OCAKPj4gKnNjYWxpbmcsCj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdTggbnVtX3BvaW50cywgdTggKnNj YWxpbmdfbHV0KQo+PiArewo+PiArwqDCoMKgIGludCBpLCBwb2ludDsKPj4gKwo+PiArwqDCoMKg IGlmIChudW1fcG9pbnRzID09IDApIHsKPj4gK8KgwqDCoMKgwqDCoMKgIG1lbXNldChzY2FsaW5n X2x1dCwgMCwgMjU2KTsKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybjsKPj4gK8KgwqDCoCB9Cj4+ ICsKPj4gK8KgwqDCoCBmb3IgKHBvaW50ID0gMDsgcG9pbnQgPCBudW1fcG9pbnRzIC0gMTsgcG9p bnQrKykgewo+PiArwqDCoMKgwqDCoMKgwqAgaW50IHg7Cj4+ICvCoMKgwqDCoMKgwqDCoCBzMzIg ZGVsdGFfeSA9IHNjYWxpbmdbcG9pbnQgKyAxXSAtIHNjYWxpbmdbcG9pbnRdOwo+PiArwqDCoMKg wqDCoMKgwqAgczMyIGRlbHRhX3ggPSB2YWx1ZXNbcG9pbnQgKyAxXSAtIHZhbHVlc1twb2ludF07 Cj4+ICvCoMKgwqDCoMKgwqDCoCBzNjQgZGVsdGEgPQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBkZWx0YV94ID8gZGVsdGFfeSAqICgoNjU1MzYgKyAoZGVsdGFfeCA+PiAxKSkgLwo+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBkZWx0YV94KSA6IDA7Cj4+ICsK Pj4gK8KgwqDCoMKgwqDCoMKgIGZvciAoeCA9IDA7IHggPCBkZWx0YV94OyB4KyspIHsKPj4gK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqAgc2NhbGluZ19sdXRbdmFsdWVzW3BvaW50XSArIHhdID0KPj4g K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzY2FsaW5nW3BvaW50XSArCj4+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKHMzMikoKHggKiBkZWx0YSArIDMyNzY4KSA+PiAx Nik7Cj4+ICvCoMKgwqDCoMKgwqDCoCB9Cj4+ICvCoMKgwqAgfQo+PiArCj4+ICvCoMKgwqAgZm9y IChpID0gdmFsdWVzW251bV9wb2ludHMgLSAxXTsgaSA8IDI1NjsgaSsrKQo+PiArwqDCoMKgwqDC oMKgwqAgc2NhbGluZ19sdXRbaV0gPSBzY2FsaW5nW251bV9wb2ludHMgLSAxXTsKPj4gK30KPj4g Kwo+PiArdm9pZCBoYW50cm9fYXYxX3NldF90aWxlX2luZm8oc3RydWN0IGhhbnRyb19jdHggKmN0 eCkKPj4gK3sKPj4gK8KgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfaHdfY3R4ICphdjFfZGVj ID0gJmN0eC0+YXYxX2RlYzsKPj4gK8KgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfY3RybHMg KmN0cmxzID0gJmF2MV9kZWMtPmN0cmxzOwo+PiArwqDCoMKgIGNvbnN0IHN0cnVjdCB2NGwyX2F2 MV90aWxlX2luZm8gKnRpbGVfaW5mbyA9IAo+PiAmY3RybHMtPmZyYW1lLT50aWxlX2luZm87Cj4+ ICvCoMKgwqAgY29uc3Qgc3RydWN0IHY0bDJfY3RybF9hdjFfdGlsZV9ncm91cF9lbnRyeSAqZ3Jv dXBfZW50cnkgPQo+PiArwqDCoMKgwqDCoMKgwqAgY3RybHMtPnRpbGVfZ3JvdXBfZW50cnk7Cj4+ ICvCoMKgwqAgdTggKmRzdCA9IGF2MV9kZWMtPnRpbGVfaW5mby5jcHU7Cj4+ICvCoMKgwqAgaW50 IHRpbGUwLCB0aWxlMTsKPj4gKwo+PiArwqDCoMKgIG1lbXNldChkc3QsIDAsIGF2MV9kZWMtPnRp bGVfaW5mby5zaXplKTsKPj4gKwo+PiArwqDCoMKgIGZvciAodGlsZTAgPSAwOyB0aWxlMCA8IHRp bGVfaW5mby0+dGlsZV9jb2xzOyB0aWxlMCsrKSB7Cj4+ICvCoMKgwqDCoMKgwqDCoCBmb3IgKHRp bGUxID0gMDsgdGlsZTEgPCB0aWxlX2luZm8tPnRpbGVfcm93czsgdGlsZTErKykgewo+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBpbnQgdGlsZV9pZCA9IHRpbGUxICogdGlsZV9pbmZvLT50aWxl X2NvbHMgKyB0aWxlMDsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdTMyIHN0YXJ0LCBlbmQ7 Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHUzMiB5MCA9Cj4+ICvCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgdGlsZV9pbmZvLT5oZWlnaHRfaW5fc2JzX21pbnVzXzFbdGlsZTFdICsg MTsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdTMyIHgwID0gdGlsZV9pbmZvLT53aWR0aF9p bl9zYnNfbWludXNfMVt0aWxlMF0gKyAxOwo+PiArCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IC8qIHRpbGUgc2l6ZSBpbiBTQiB1bml0cyAod2lkdGgsaGVpZ2h0KSAqLwo+PiArwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCAqZHN0KysgPSB4MDsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKmRz dCsrID0gMDsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKmRzdCsrID0gMDsKPj4gK8KgwqDC oMKgwqDCoMKgwqDCoMKgwqAgKmRzdCsrID0gMDsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAg KmRzdCsrID0geTA7Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICpkc3QrKyA9IDA7Cj4+ICvC oMKgwqDCoMKgwqDCoMKgwqDCoMKgICpkc3QrKyA9IDA7Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDC oMKgICpkc3QrKyA9IDA7Cj4+ICsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgLyogdGlsZSBz dGFydCBwb3NpdGlvbiAqLwo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzdGFydCA9IGdyb3Vw X2VudHJ5W3RpbGVfaWRdLnRpbGVfb2Zmc2V0IC0gCj4+IGdyb3VwX2VudHJ5WzBdLnRpbGVfb2Zm c2V0Owo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAqZHN0KysgPSBzdGFydCAmIDI1NTsKPj4g K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKmRzdCsrID0gKHN0YXJ0ID4+IDgpICYgMjU1Owo+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAqZHN0KysgPSAoc3RhcnQgPj4gMTYpICYgMjU1Owo+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAqZHN0KysgPSAoc3RhcnQgPj4gMjQpICYgMjU1Owo+PiAr Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIC8qIG51bWJlciBvZiBieXRlcyBpbiB0aWxlIGRh dGEgKi8KPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZW5kID0gc3RhcnQgKyBncm91cF9lbnRy eVt0aWxlX2lkXS50aWxlX3NpemU7Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICpkc3QrKyA9 IGVuZCAmIDI1NTsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKmRzdCsrID0gKGVuZCA+PiA4 KSAmIDI1NTsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKmRzdCsrID0gKGVuZCA+PiAxNikg JiAyNTU7Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICpkc3QrKyA9IChlbmQgPj4gMjQpICYg MjU1Owo+PiArwqDCoMKgwqDCoMKgwqAgfQo+PiArwqDCoMKgIH0KPj4gK30KPj4gKwo+PiArYm9v bCBoYW50cm9fYXYxX2lzX2xvc3NsZXNzKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpCj4+ICt7Cj4+ ICvCoMKgwqAgc3RydWN0IGhhbnRyb19hdjFfZGVjX2h3X2N0eCAqYXYxX2RlYyA9ICZjdHgtPmF2 MV9kZWM7Cj4+ICvCoMKgwqAgc3RydWN0IGhhbnRyb19hdjFfZGVjX2N0cmxzICpjdHJscyA9ICZh djFfZGVjLT5jdHJsczsKPj4gK8KgwqDCoCBjb25zdCBzdHJ1Y3QgdjRsMl9jdHJsX2F2MV9mcmFt ZSAqZnJhbWUgPSBjdHJscy0+ZnJhbWU7Cj4+ICvCoMKgwqAgY29uc3Qgc3RydWN0IHY0bDJfYXYx X3NlZ21lbnRhdGlvbiAqc2VnbWVudGF0aW9uID0gCj4+ICZmcmFtZS0+c2VnbWVudGF0aW9uOwo+ PiArwqDCoMKgIGNvbnN0IHN0cnVjdCB2NGwyX2F2MV9xdWFudGl6YXRpb24gKnF1YW50aXphdGlv biA9IAo+PiAmZnJhbWUtPnF1YW50aXphdGlvbjsKPj4gK8KgwqDCoCBpbnQgaTsKPj4gKwo+PiAr wqDCoMKgIGZvciAoaSA9IDA7IGkgPCBWNEwyX0FWMV9NQVhfU0VHTUVOVFM7IGkrKykgewo+PiAr wqDCoMKgwqDCoMKgwqAgaW50IHFpbmRleCA9IHF1YW50aXphdGlvbi0+YmFzZV9xX2lkeDsKPj4g Kwo+PiArwqDCoMKgwqDCoMKgwqAgaWYgKHNlZ21lbnRhdGlvbi0+ZmVhdHVyZV9lbmFibGVkW2ld ICYKPj4gKyBWNEwyX0FWMV9TRUdNRU5UX0ZFQVRVUkVfRU5BQkxFRChWNEwyX0FWMV9TRUdfTFZM X0FMVF9RKSkgewo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBxaW5kZXggKz0gCj4+IHNlZ21l bnRhdGlvbi0+ZmVhdHVyZV9kYXRhW2ldW1Y0TDJfQVYxX1NFR19MVkxfQUxUX1FdOwo+PiArwqDC oMKgwqDCoMKgwqAgfQo+PiArwqDCoMKgwqDCoMKgwqAgcWluZGV4ID0gY2xhbXAocWluZGV4LCAw LCAyNTUpOwo+PiArCj4+ICvCoMKgwqDCoMKgwqDCoCBpZiAocWluZGV4IHx8Cj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIHF1YW50aXphdGlvbi0+ZGVsdGFfcV95X2RjIHx8Cj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIHF1YW50aXphdGlvbi0+ZGVsdGFfcV91X2RjIHx8Cj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIHF1YW50aXphdGlvbi0+ZGVsdGFfcV91X2FjIHx8Cj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIHF1YW50aXphdGlvbi0+ZGVsdGFfcV92X2RjIHx8Cj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIHF1YW50aXphdGlvbi0+ZGVsdGFfcV92X2FjKQo+PiArwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCByZXR1cm4gZmFsc2U7Cj4+ICvCoMKgwqAgfQo+PiArCj4+ICvCoMKgwqAg cmV0dXJuIHRydWU7Cj4+ICt9Cj4+ICsKPj4gK3ZvaWQgaGFudHJvX2F2MV91cGRhdGVfcHJvYihz dHJ1Y3QgaGFudHJvX2N0eCAqY3R4KQo+PiArewo+PiArwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYx X2RlY19od19jdHggKmF2MV9kZWMgPSAmY3R4LT5hdjFfZGVjOwo+PiArwqDCoMKgIHN0cnVjdCBo YW50cm9fYXYxX2RlY19jdHJscyAqY3RybHMgPSAmYXYxX2RlYy0+Y3RybHM7Cj4+ICvCoMKgwqAg Y29uc3Qgc3RydWN0IHY0bDJfY3RybF9hdjFfZnJhbWUgKmZyYW1lID0gY3RybHMtPmZyYW1lOwo+ PiArwqDCoMKgIGJvb2wgZnJhbWVfaXNfaW50cmEgPSBJU19JTlRSQShmcmFtZS0+ZnJhbWVfdHlw ZSk7Cj4+ICvCoMKgwqAgc3RydWN0IGF2MWNkZnMgKm91dF9jZGZzID0gKHN0cnVjdCBhdjFjZGZz IAo+PiAqKWF2MV9kZWMtPnByb2JfdGJsX291dC5jcHU7Cj4+ICvCoMKgwqAgaW50IGk7Cj4+ICsK Pj4gK8KgwqDCoCBpZiAoZnJhbWUtPmZsYWdzICYgCj4+IFY0TDJfQVYxX0ZSQU1FX0ZMQUdfRElT QUJMRV9GUkFNRV9FTkRfVVBEQVRFX0NERikKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybjsKPj4g Kwo+PiArwqDCoMKgIGZvciAoaSA9IDA7IGkgPCBOVU1fUkVGX0ZSQU1FUzsgaSsrKSB7Cj4+ICvC oMKgwqDCoMKgwqDCoCBpZiAoZnJhbWUtPnJlZnJlc2hfZnJhbWVfZmxhZ3MgJiBCSVQoaSkpIHsK Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgc3RydWN0IG12Y2RmcyBzdG9yZWRfbXZfY2RmOwo+ PiArCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGhhbnRyb19hdjFfZ2V0X2NkZnMoY3R4LCBp KTsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgc3RvcmVkX212X2NkZiA9IGF2MV9kZWMtPmNk ZnMtPm12X2NkZjsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKmF2MV9kZWMtPmNkZnMgPSAq b3V0X2NkZnM7Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGlmIChmcmFtZV9pc19pbnRyYSkg ewo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGF2MV9kZWMtPmNkZnMtPm12X2Nk ZiA9IHN0b3JlZF9tdl9jZGY7Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKmF2 MV9kZWMtPmNkZnNfbmR2YyA9IG91dF9jZGZzLT5tdl9jZGY7Cj4+ICvCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIH0KPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaGFudHJvX2F2MV9zdG9yZV9jZGZz KGN0eCwgZnJhbWUtPnJlZnJlc2hfZnJhbWVfZmxhZ3MpOwo+PiArwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCBicmVhazsKPj4gK8KgwqDCoMKgwqDCoMKgIH0KPj4gK8KgwqDCoCB9Cj4+ICt9Cj4+ICsK Pj4gK3ZvaWQgaGFudHJvX2F2MV9zZXRfcHJvYihzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4KQo+PiAr ewo+PiArwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19od19jdHggKmF2MV9kZWMgPSAmY3R4 LT5hdjFfZGVjOwo+PiArwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19jdHJscyAqY3RybHMg PSAmYXYxX2RlYy0+Y3RybHM7Cj4+ICvCoMKgwqAgY29uc3Qgc3RydWN0IHY0bDJfY3RybF9hdjFf ZnJhbWUgKmZyYW1lID0gY3RybHMtPmZyYW1lOwo+PiArwqDCoMKgIGNvbnN0IHN0cnVjdCB2NGwy X2F2MV9xdWFudGl6YXRpb24gKnF1YW50aXphdGlvbiA9IAo+PiAmZnJhbWUtPnF1YW50aXphdGlv bjsKPj4gK8KgwqDCoCBib29sIGVycm9yX3Jlc2lsaWVudF9tb2RlID0KPj4gK8KgwqDCoMKgwqDC oMKgICEhKGZyYW1lLT5mbGFncyAmIFY0TDJfQVYxX0ZSQU1FX0ZMQUdfRVJST1JfUkVTSUxJRU5U X01PREUpOwo+PiArwqDCoMKgIGJvb2wgZnJhbWVfaXNfaW50cmEgPSBJU19JTlRSQShmcmFtZS0+ ZnJhbWVfdHlwZSk7Cj4+ICsKPj4gK8KgwqDCoCBpZiAoZXJyb3JfcmVzaWxpZW50X21vZGUgfHwg ZnJhbWVfaXNfaW50cmEgfHwKPj4gK8KgwqDCoMKgwqDCoMKgIGZyYW1lLT5wcmltYXJ5X3JlZl9m cmFtZSA9PSBBVjFfUFJJTUFSWV9SRUZfTk9ORSkgewo+PiArwqDCoMKgwqDCoMKgwqAgYXYxX2Rl Yy0+Y2RmcyA9ICZhdjFfZGVjLT5kZWZhdWx0X2NkZnM7Cj4+ICvCoMKgwqDCoMKgwqDCoCBhdjFf ZGVjLT5jZGZzX25kdmMgPSAmYXYxX2RlYy0+ZGVmYXVsdF9jZGZzX25kdmM7Cj4+ICsgaGFudHJv X2F2MV9kZWZhdWx0X2NvZWZmX3Byb2JzKHF1YW50aXphdGlvbi0+YmFzZV9xX2lkeCwKPj4gK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYXYxX2Rl Yy0+Y2Rmcyk7Cj4+ICvCoMKgwqAgfSBlbHNlIHsKPj4gK8KgwqDCoMKgwqDCoMKgIGlmIChmcmFt ZS0+cHJpbWFyeV9yZWZfZnJhbWUgPCAwIHx8Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGZy YW1lLT5wcmltYXJ5X3JlZl9mcmFtZSA+PSBWNEwyX0FWMV9SRUZTX1BFUl9GUkFNRSkKPj4gK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuOwo+PiArCj4+ICvCoMKgwqDCoMKgwqDCoCBoYW50 cm9fYXYxX2dldF9jZGZzKGN0eCwgCj4+IGZyYW1lLT5yZWZfZnJhbWVfaWR4W2ZyYW1lLT5wcmlt YXJ5X3JlZl9mcmFtZV0pOwo+PiArwqDCoMKgIH0KPj4gK8KgwqDCoCBoYW50cm9fYXYxX3N0b3Jl X2NkZnMoY3R4LCBmcmFtZS0+cmVmcmVzaF9mcmFtZV9mbGFncyk7Cj4+ICsKPj4gK8KgwqDCoCBt ZW1jcHkoYXYxX2RlYy0+cHJvYl90YmwuY3B1LCBhdjFfZGVjLT5jZGZzLCBzaXplb2Yoc3RydWN0 IAo+PiBhdjFjZGZzKSk7Cj4+ICsKPj4gK8KgwqDCoCBpZiAoZnJhbWVfaXNfaW50cmEpIHsKPj4g K8KgwqDCoMKgwqDCoMKgIGludCBtdl9vZmZzZXQgPSBvZmZzZXRvZihzdHJ1Y3QgYXYxY2Rmcywg bXZfY2RmKTsKPj4gK8KgwqDCoMKgwqDCoMKgIC8qIE92ZXJ3cml0ZSBNViBjb250ZXh0IGFyZWEg d2l0aCBpbnRyYWJjIE1WIGNvbnRleHQgKi8KPj4gK8KgwqDCoMKgwqDCoMKgIG1lbWNweShhdjFf ZGVjLT5wcm9iX3RibC5jcHUgKyBtdl9vZmZzZXQsIGF2MV9kZWMtPmNkZnNfbmR2YywKPj4gK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgc2l6ZW9mKHN0cnVjdCBtdmNkZnMpKTsKPj4gK8Kg wqDCoCB9Cj4+ICt9Cj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3Zlcmlz aWxpY29uL2hhbnRyb19hdjEuaCAKPj4gYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxp Y29uL2hhbnRyb19hdjEuaAo+PiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRleCAwMDAwMDAw MDAwMDAuLmQ5MWM4MTRlZWZjYgo+PiAtLS0gL2Rldi9udWxsCj4+ICsrKyBiL2RyaXZlcnMvbWVk aWEvcGxhdGZvcm0vdmVyaXNpbGljb24vaGFudHJvX2F2MS5oCj4+IEBAIC0wLDAgKzEsNjQgQEAK Pj4gKy8qIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkgKi8KPj4gKwo+PiAr I2lmbmRlZiBfSEFOVFJPX0FWMV9IXwo+PiArI2RlZmluZSBfSEFOVFJPX0FWMV9IXwo+PiArCj4+ ICsjZGVmaW5lIEFWMV9QUklNQVJZX1JFRl9OT05FwqDCoMKgIDcKPj4gKyNkZWZpbmUgQVYxX1JF Rl9TQ0FMRV9TSElGVMKgwqDCoCAxNAo+PiArI2RlZmluZSBNQVhfRlJBTUVfRElTVEFOQ0XCoMKg wqAgMzEKPj4gKyNkZWZpbmUgQVYxREVDX01BWF9QSUNfQlVGRkVSU8KgwqDCoCAyNAo+PiArCj4+ ICsjZGVmaW5lIFNDQUxFX05VTUVSQVRPUiA4Cj4+ICsjZGVmaW5lIFNVUEVSUkVTX1NDQUxFX0RF Tk9NSU5BVE9SX01JTiAoU0NBTEVfTlVNRVJBVE9SICsgMSkKPj4gKwo+PiArI2RlZmluZSBSU19T Q0FMRV9TVUJQRUxfQklUUyAxNAo+PiArI2RlZmluZSBSU19TQ0FMRV9TVUJQRUxfTUFTSyAoKDEg PDwgUlNfU0NBTEVfU1VCUEVMX0JJVFMpIC0gMSkKPj4gKyNkZWZpbmUgUlNfU1VCUEVMX0JJVFMg Ngo+PiArI2RlZmluZSBSU19TVUJQRUxfTUFTSyAoKDEgPDwgUlNfU1VCUEVMX0JJVFMpIC0gMSkK Pj4gKyNkZWZpbmUgUlNfU0NBTEVfRVhUUkFfQklUUyAoUlNfU0NBTEVfU1VCUEVMX0JJVFMgLSBS U19TVUJQRUxfQklUUykKPj4gKyNkZWZpbmUgUlNfU0NBTEVfRVhUUkFfT0ZGICgxIDw8IChSU19T Q0FMRV9FWFRSQV9CSVRTIC0gMSkpCj4+ICsKPj4gKy8qCj4+ICsgKiBUaGVzZSAzIHZhbHVlcyBh cmVuJ3QgZGVmaW5lZCBlbnVtIHY0bDJfYXYxX3NlZ21lbnRfZmVhdHVyZSBiZWNhdXNlCj4+ICsg KiB0aGV5IGFyZSBub3QgcGFydCBvZiB0aGUgc3BlY2lmaWNhdGlvbgo+PiArICovCj4+ICsjZGVm aW5lIFY0TDJfQVYxX1NFR19MVkxfQUxUX0xGX1lfSMKgwqDCoCAyCj4+ICsjZGVmaW5lIFY0TDJf QVYxX1NFR19MVkxfQUxUX0xGX1XCoMKgwqAgMwo+PiArI2RlZmluZSBWNEwyX0FWMV9TRUdfTFZM X0FMVF9MRl9WwqDCoMKgIDQKPj4gKwo+PiArI2RlZmluZSBJU19JTlRSQSh0eXBlKSAoKHR5cGUg PT0gVjRMMl9BVjFfS0VZX0ZSQU1FKSB8fCAodHlwZSA9PSAKPj4gVjRMMl9BVjFfSU5UUkFfT05M WV9GUkFNRSkpCj4+ICsKPj4gKyNkZWZpbmUgTFNUX0JVRl9JRFggKFY0TDJfQVYxX1JFRl9MQVNU X0ZSQU1FIC0gVjRMMl9BVjFfUkVGX0xBU1RfRlJBTUUpCj4+ICsjZGVmaW5lIExTVDJfQlVGX0lE WCAoVjRMMl9BVjFfUkVGX0xBU1QyX0ZSQU1FIC0gCj4+IFY0TDJfQVYxX1JFRl9MQVNUX0ZSQU1F KQo+PiArI2RlZmluZSBMU1QzX0JVRl9JRFggKFY0TDJfQVYxX1JFRl9MQVNUM19GUkFNRSAtIAo+ PiBWNEwyX0FWMV9SRUZfTEFTVF9GUkFNRSkKPj4gKyNkZWZpbmUgR0xEX0JVRl9JRFggKFY0TDJf QVYxX1JFRl9HT0xERU5fRlJBTUUgLSAKPj4gVjRMMl9BVjFfUkVGX0xBU1RfRlJBTUUpCj4+ICsj ZGVmaW5lIEJXRF9CVUZfSURYIChWNEwyX0FWMV9SRUZfQldEUkVGX0ZSQU1FIC0gCj4+IFY0TDJf QVYxX1JFRl9MQVNUX0ZSQU1FKQo+PiArI2RlZmluZSBBTFQyX0JVRl9JRFggKFY0TDJfQVYxX1JF Rl9BTFRSRUYyX0ZSQU1FIC0gCj4+IFY0TDJfQVYxX1JFRl9MQVNUX0ZSQU1FKQo+PiArI2RlZmlu ZSBBTFRfQlVGX0lEWCAoVjRMMl9BVjFfUkVGX0FMVFJFRl9GUkFNRSAtIAo+PiBWNEwyX0FWMV9S RUZfTEFTVF9GUkFNRSkKPj4gKwo+PiArI2RlZmluZSBBVjFfSU5WQUxJRF9JRFjCoMKgwqDCoMKg wqDCoCAtMQo+PiArCj4+ICtpbnQgaGFudHJvX2F2MV9nZXRfZnJhbWVfaW5kZXgoc3RydWN0IGhh bnRyb19jdHggKmN0eCwgaW50IHJlZik7Cj4+ICtpbnQgaGFudHJvX2F2MV9nZXRfb3JkZXJfaGlu dChzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4LCBpbnQgcmVmKTsKPj4gK2ludCBoYW50cm9fYXYxX2Zy YW1lX3JlZihzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4LCB1NjQgdGltZXN0YW1wKTsKPj4gK3ZvaWQg aGFudHJvX2F2MV9jbGVhbl9yZWZzKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpOwo+PiArc2l6ZV90 IGhhbnRyb19hdjFfbHVtYV9zaXplKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpOwo+PiArc2l6ZV90 IGhhbnRyb19hdjFfY2hyb21hX3NpemUoc3RydWN0IGhhbnRyb19jdHggKmN0eCk7Cj4+ICt2b2lk IGhhbnRyb19hdjFfZXhpdChzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4KTsKPj4gK2ludCBoYW50cm9f YXYxX2luaXQoc3RydWN0IGhhbnRyb19jdHggKmN0eCk7Cj4+ICtpbnQgaGFudHJvX2F2MV9wcmVw YXJlX3J1bihzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4KTsKPj4gK3ZvaWQgaGFudHJvX2F2MV9zZXRf Z2xvYmFsX21vZGVsKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpOwo+PiAraW50IGhhbnRyb19hdjFf dGlsZV9sb2cyKGludCB0YXJnZXQpOwo+PiAraW50IGhhbnRyb19hdjFfZ2V0X2Rpc3Qoc3RydWN0 IGhhbnRyb19jdHggKmN0eCwgaW50IGEsIGludCBiKTsKPj4gK3ZvaWQgaGFudHJvX2F2MV9zZXRf ZnJhbWVfc2lnbl9iaWFzKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpOwo+PiArdm9pZCBoYW50cm9f YXYxX2luaXRfc2NhbGluZ19mdW5jdGlvbihjb25zdCB1OCAqdmFsdWVzLCBjb25zdCB1OCAKPj4g KnNjYWxpbmcsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg dTggbnVtX3BvaW50cywgdTggKnNjYWxpbmdfbHV0KTsKPj4gK3ZvaWQgaGFudHJvX2F2MV9zZXRf dGlsZV9pbmZvKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpOwo+PiArYm9vbCBoYW50cm9fYXYxX2lz X2xvc3NsZXNzKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpOwo+PiArdm9pZCBoYW50cm9fYXYxX3Vw ZGF0ZV9wcm9iKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpOwo+PiArdm9pZCBoYW50cm9fYXYxX3Nl dF9wcm9iKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpOwo+PiArCj4+ICtpbnQgaGFudHJvX2F2MV9n ZXRfaGFyZHdhcmVfbWNvbXBfZmlsdF90eXBlKGludCBpbnRlcnBvbGF0aW9uX2ZpbHRlcik7Cj4+ ICtpbnQgaGFudHJvX2F2MV9nZXRfaGFyZHdhcmVfdHhfbW9kZShlbnVtIHY0bDJfYXYxX3R4X21v ZGUgdHhfbW9kZSk7Cj4+ICsKPj4gKyNlbmRpZgo+PiBkaWZmIC0tZ2l0IAo+PiBhL2RyaXZlcnMv bWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24vcm9ja2NoaXBfYXYxX2VudHJvcHltb2RlLmMgCj4+ IGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS92ZXJpc2lsaWNvbi9oYW50cm9fYXYxX2VudHJvcHlt b2RlLmMKPj4gc2ltaWxhcml0eSBpbmRleCA5OSUKPj4gcmVuYW1lIGZyb20gCj4+IGRyaXZlcnMv bWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24vcm9ja2NoaXBfYXYxX2VudHJvcHltb2RlLmMKPj4g cmVuYW1lIHRvIGRyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24vaGFudHJvX2F2MV9l bnRyb3B5bW9kZS5jCj4+IGluZGV4IGIxYWU3MmFkNjc1ZS4uNGY3YmZlYzczNjY4IDEwMDY0NAo+ PiAtLS0gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL3JvY2tjaGlwX2F2MV9l bnRyb3B5bW9kZS5jCj4+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24v aGFudHJvX2F2MV9lbnRyb3B5bW9kZS5jCj4+IEBAIC0xMSw3ICsxMSw3IEBACj4+IMKgwqAgKi8K Pj4gwqAgwqAgI2luY2x1ZGUgImhhbnRyby5oIgo+PiAtI2luY2x1ZGUgInJvY2tjaGlwX2F2MV9l bnRyb3B5bW9kZS5oIgo+PiArI2luY2x1ZGUgImhhbnRyb19hdjFfZW50cm9weW1vZGUuaCIKPj4g wqAgwqAgI2RlZmluZSBBT01fSUNERiBJQ0RGCj4+IMKgICNkZWZpbmUgQU9NX0NERjIoYTApIEFP TV9JQ0RGKGEwKQo+PiBAQCAtNDE5NSw3ICs0MTk1LDcgQEAgc3RhdGljIGNvbnN0IHUxNiBkZWZh dWx0X2JpdHNfY2RmW11bMTBdID0gewo+PiDCoMKgwqDCoMKgIH0KPj4gwqAgfTsKPj4gwqAgLXN0 YXRpYyBpbnQgcm9ja2NoaXBfYXYxX2dldF9xX2N0eChpbnQgcSkKPj4gK3N0YXRpYyBpbnQgaGFu dHJvX2F2MV9nZXRfcV9jdHgoaW50IHEpCj4+IMKgIHsKPj4gwqDCoMKgwqDCoCBpZiAocSA8PSAy MCkKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiAwOwo+PiBAQCAtNDIwNiwxMCArNDIwNiwx MCBAQCBzdGF0aWMgaW50IHJvY2tjaGlwX2F2MV9nZXRfcV9jdHgoaW50IHEpCj4+IMKgwqDCoMKg wqAgcmV0dXJuIDM7Cj4+IMKgIH0KPj4gwqAgLXZvaWQgcm9ja2NoaXBfYXYxX2RlZmF1bHRfY29l ZmZfcHJvYnModTMyIGJhc2VfcWluZGV4LCB2b2lkICpwdHIpCj4+ICt2b2lkIGhhbnRyb19hdjFf ZGVmYXVsdF9jb2VmZl9wcm9icyh1MzIgYmFzZV9xaW5kZXgsIHZvaWQgKnB0cikKPj4gwqAgewo+ PiDCoMKgwqDCoMKgIHN0cnVjdCBhdjFjZGZzICpjZGZzID0gKHN0cnVjdCBhdjFjZGZzICopcHRy Owo+PiAtwqDCoMKgIGNvbnN0IGludCBpbmRleCA9IHJvY2tjaGlwX2F2MV9nZXRfcV9jdHgoYmFz ZV9xaW5kZXgpOwo+PiArwqDCoMKgIGNvbnN0IGludCBpbmRleCA9IGhhbnRyb19hdjFfZ2V0X3Ff Y3R4KGJhc2VfcWluZGV4KTsKPj4gwqAgwqDCoMKgwqDCoCBtZW1jcHkoY2Rmcy0+dHhiX3NraXBf Y2RmLCBhdjFfZGVmYXVsdF90eGJfc2tpcF9jZGZzW2luZGV4XSwKPj4gwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIHNpemVvZihhdjFfZGVmYXVsdF90eGJfc2tpcF9jZGZzWzBdKSk7Cj4+IEBAIC00 MjQwLDggKzQyNDAsOCBAQCB2b2lkIHJvY2tjaGlwX2F2MV9kZWZhdWx0X2NvZWZmX3Byb2JzKHUz MiAKPj4gYmFzZV9xaW5kZXgsIHZvaWQgKnB0cikKPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IHNpemVvZihhdjFfZGVmYXVsdF9lb2JfbXVsdGkxMDI0X2NkZnNbMF0pKTsKPj4gwqAgfQo+PiDC oCAtdm9pZCByb2NrY2hpcF9hdjFfc2V0X2RlZmF1bHRfY2RmcyhzdHJ1Y3QgYXYxY2RmcyAqY2Rm cywKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzdHJ1Y3QgbXZjZGZz ICpjZGZzX25kdmMpCj4+ICt2b2lkIGhhbnRyb19hdjFfc2V0X2RlZmF1bHRfY2RmcyhzdHJ1Y3Qg YXYxY2RmcyAqY2RmcywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHN0cnVj dCBtdmNkZnMgKmNkZnNfbmR2YykKPj4gwqAgewo+PiDCoMKgwqDCoMKgIG1lbWNweShjZGZzLT5w YXJ0aXRpb25fY2RmLCBkZWZhdWx0X3BhcnRpdGlvbl9jZGYsCj4+IMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBzaXplb2YoY2Rmcy0+cGFydGl0aW9uX2NkZikpOwo+PiBAQCAtNDM5OCw3ICs0Mzk4 LDcgQEAgdm9pZCByb2NrY2hpcF9hdjFfc2V0X2RlZmF1bHRfY2RmcyhzdHJ1Y3QgCj4+IGF2MWNk ZnMgKmNkZnMsCj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzaXplb2YoY2Rmcy0+Y29tcG91 bmRfaWR4X2NkZikpOwo+PiDCoCB9Cj4+IMKgIC12b2lkIHJvY2tjaGlwX2F2MV9nZXRfY2Rmcyhz dHJ1Y3QgaGFudHJvX2N0eCAqY3R4LCB1MzIgcmVmX2lkeCkKPj4gK3ZvaWQgaGFudHJvX2F2MV9n ZXRfY2RmcyhzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4LCB1MzIgcmVmX2lkeCkKPj4gwqAgewo+PiDC oMKgwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19od19jdHggKmF2MV9kZWMgPSAmY3R4LT5h djFfZGVjOwo+PiDCoCBAQCAtNDQwNiw4ICs0NDA2LDggQEAgdm9pZCByb2NrY2hpcF9hdjFfZ2V0 X2NkZnMoc3RydWN0IGhhbnRyb19jdHggCj4+ICpjdHgsIHUzMiByZWZfaWR4KQo+PiDCoMKgwqDC oMKgIGF2MV9kZWMtPmNkZnNfbmR2YyA9ICZhdjFfZGVjLT5jZGZzX2xhc3RfbmR2Y1tyZWZfaWR4 XTsKPj4gwqAgfQo+PiDCoCAtdm9pZCByb2NrY2hpcF9hdjFfc3RvcmVfY2RmcyhzdHJ1Y3QgaGFu dHJvX2N0eCAqY3R4LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdTMyIHJl ZnJlc2hfZnJhbWVfZmxhZ3MpCj4+ICt2b2lkIGhhbnRyb19hdjFfc3RvcmVfY2RmcyhzdHJ1Y3Qg aGFudHJvX2N0eCAqY3R4LAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB1MzIgcmVm cmVzaF9mcmFtZV9mbGFncykKPj4gwqAgewo+PiDCoMKgwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYx X2RlY19od19jdHggKmF2MV9kZWMgPSAmY3R4LT5hdjFfZGVjOwo+PiDCoMKgwqDCoMKgIGludCBp Owo+PiBkaWZmIC0tZ2l0IAo+PiBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24v cm9ja2NoaXBfYXYxX2VudHJvcHltb2RlLmggCj4+IGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS92 ZXJpc2lsaWNvbi9oYW50cm9fYXYxX2VudHJvcHltb2RlLmgKPj4gc2ltaWxhcml0eSBpbmRleCA5 NSUKPj4gcmVuYW1lIGZyb20gCj4+IGRyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24v cm9ja2NoaXBfYXYxX2VudHJvcHltb2RlLmgKPj4gcmVuYW1lIHRvIGRyaXZlcnMvbWVkaWEvcGxh dGZvcm0vdmVyaXNpbGljb24vaGFudHJvX2F2MV9lbnRyb3B5bW9kZS5oCj4+IGluZGV4IGJiZjg0 MjRjN2QyYy4uYWJiYzY2MGVjY2UzIDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL21lZGlhL3BsYXRm b3JtL3ZlcmlzaWxpY29uL3JvY2tjaGlwX2F2MV9lbnRyb3B5bW9kZS5oCj4+ICsrKyBiL2RyaXZl cnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24vaGFudHJvX2F2MV9lbnRyb3B5bW9kZS5oCj4+ IEBAIC0xLDcgKzEsNyBAQAo+PiDCoCAvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIu MC1vbmx5ICovCj4+IMKgIC0jaWZuZGVmIF9ST0NLQ0hJUF9BVjFfRU5UUk9QWU1PREVfSF8KPj4g LSNkZWZpbmUgX1JPQ0tDSElQX0FWMV9FTlRST1BZTU9ERV9IXwo+PiArI2lmbmRlZiBfSEFOVFJP X0FWMV9FTlRST1BZTU9ERV9IXwo+PiArI2RlZmluZSBfSEFOVFJPX0FWMV9FTlRST1BZTU9ERV9I Xwo+PiDCoCDCoCAjaW5jbHVkZSA8bGludXgvdHlwZXMuaD4KPj4gwqAgQEAgLTI2MiwxMSArMjYy LDExIEBAIHN0cnVjdCBhdjFjZGZzIHsKPj4gwqDCoMKgwqDCoCB1MTYgZHVtbXkzWzE2XTsKPj4g wqAgfTsKPj4gwqAgLXZvaWQgcm9ja2NoaXBfYXYxX3N0b3JlX2NkZnMoc3RydWN0IGhhbnRyb19j dHggKmN0eCwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHUzMiByZWZyZXNo X2ZyYW1lX2ZsYWdzKTsKPj4gLXZvaWQgcm9ja2NoaXBfYXYxX2dldF9jZGZzKHN0cnVjdCBoYW50 cm9fY3R4ICpjdHgsIHUzMiByZWZfaWR4KTsKPj4gLXZvaWQgcm9ja2NoaXBfYXYxX3NldF9kZWZh dWx0X2NkZnMoc3RydWN0IGF2MWNkZnMgKmNkZnMsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgc3RydWN0IG12Y2RmcyAqY2Rmc19uZHZjKTsKPj4gLXZvaWQgcm9ja2No aXBfYXYxX2RlZmF1bHRfY29lZmZfcHJvYnModTMyIGJhc2VfcWluZGV4LCB2b2lkICpwdHIpOwo+ PiArdm9pZCBoYW50cm9fYXYxX3N0b3JlX2NkZnMoc3RydWN0IGhhbnRyb19jdHggKmN0eCwKPj4g K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdTMyIHJlZnJlc2hfZnJhbWVfZmxhZ3MpOwo+ PiArdm9pZCBoYW50cm9fYXYxX2dldF9jZGZzKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgsIHUzMiBy ZWZfaWR4KTsKPj4gK3ZvaWQgaGFudHJvX2F2MV9zZXRfZGVmYXVsdF9jZGZzKHN0cnVjdCBhdjFj ZGZzICpjZGZzLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgc3RydWN0IG12 Y2RmcyAqY2Rmc19uZHZjKTsKPj4gK3ZvaWQgaGFudHJvX2F2MV9kZWZhdWx0X2NvZWZmX3Byb2Jz KHUzMiBiYXNlX3FpbmRleCwgdm9pZCAqcHRyKTsKPj4gwqAgLSNlbmRpZiAvKiBfUk9DS0NISVBf QVYxX0VOVFJPUFlNT0RFX0hfICovCj4+ICsjZW5kaWYgLyogX0hBTlRST19BVjFfRU5UUk9QWU1P REVfSF8gKi8KPj4gZGlmZiAtLWdpdCAKPj4gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3Zlcmlz aWxpY29uL3JvY2tjaGlwX2F2MV9maWxtZ3JhaW4uYyAKPj4gYi9kcml2ZXJzL21lZGlhL3BsYXRm b3JtL3ZlcmlzaWxpY29uL2hhbnRyb19hdjFfZmlsbWdyYWluLmMKPj4gc2ltaWxhcml0eSBpbmRl eCA4NSUKPj4gcmVuYW1lIGZyb20gZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS92ZXJpc2lsaWNvbi9y b2NrY2hpcF9hdjFfZmlsbWdyYWluLmMKPj4gcmVuYW1lIHRvIGRyaXZlcnMvbWVkaWEvcGxhdGZv cm0vdmVyaXNpbGljb24vaGFudHJvX2F2MV9maWxtZ3JhaW4uYwo+PiBpbmRleCBmNjRkZWE3OTdl ZmYuLmExZmM0MGUwMjE4YSAxMDA2NDQKPj4gLS0tIGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS92 ZXJpc2lsaWNvbi9yb2NrY2hpcF9hdjFfZmlsbWdyYWluLmMKPj4gKysrIGIvZHJpdmVycy9tZWRp YS9wbGF0Zm9ybS92ZXJpc2lsaWNvbi9oYW50cm9fYXYxX2ZpbG1ncmFpbi5jCj4+IEBAIC0xLDYg KzEsNiBAQAo+PiDCoCAvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMC1vbmx5IE9S IEFwYWNoZS0yLjAKPj4gwqAgLSNpbmNsdWRlICJyb2NrY2hpcF9hdjFfZmlsbWdyYWluLmgiCj4+ ICsjaW5jbHVkZSAiaGFudHJvX2F2MV9maWxtZ3JhaW4uaCIKPj4gwqAgwqAgc3RhdGljIGNvbnN0 IHMzMiBnYXVzc2lhbl9zZXF1ZW5jZVsyMDQ4XSA9IHsKPj4gwqDCoMKgwqDCoCA1NiwgNTY4LCAt MTgwLCAxNzIsIDEyNCwgLTg0LCAxNzIsIC02NCwgLTkwMCwgMjQsIDgyMCwKPj4gQEAgLTIwNCw4 ICsyMDQsOCBAQCBzdGF0aWMgaW5saW5lIHMzMiByb3VuZF9wb3dlcl9vZl90d28oY29uc3QgczMy IAo+PiB2YWwsIHMzMiBuKQo+PiDCoMKgwqDCoMKgIHJldHVybiAodmFsICsgYSkgPj4gbjsKPj4g wqAgfQo+PiDCoCAtc3RhdGljIHZvaWQgcm9ja2NoaXBfYXYxX2luaXRfcmFuZG9tX2dlbmVyYXRv cih1OCBsdW1hX251bSwgdTE2IHNlZWQsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHUxNiAqcmFuZG9tX3JlZ2lzdGVyKQo+PiArc3RhdGlj IHZvaWQgaGFudHJvX2F2MV9pbml0X3JhbmRvbV9nZW5lcmF0b3IodTggbHVtYV9udW0sIHUxNiBz ZWVkLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IHUxNiAqcmFuZG9tX3JlZ2lzdGVyKQo+PiDCoCB7Cj4+IMKgwqDCoMKgwqAgdTE2IHJhbmRvbV9y ZWcgPSBzZWVkOwo+PiDCoCBAQCAtMjE0LDcgKzIxNCw3IEBAIHN0YXRpYyB2b2lkIAo+PiByb2Nr Y2hpcF9hdjFfaW5pdF9yYW5kb21fZ2VuZXJhdG9yKHU4IGx1bWFfbnVtLCB1MTYgc2VlZCwKPj4g wqDCoMKgwqDCoCAqcmFuZG9tX3JlZ2lzdGVyID0gcmFuZG9tX3JlZzsKPj4gwqAgfQo+PiDCoCAt c3RhdGljIGlubGluZSB2b2lkIHJvY2tjaGlwX2F2MV91cGRhdGVfcmFuZG9tX3JlZ2lzdGVyKHUx NiAKPj4gKnJhbmRvbV9yZWdpc3RlcikKPj4gK3N0YXRpYyBpbmxpbmUgdm9pZCBoYW50cm9fYXYx X3VwZGF0ZV9yYW5kb21fcmVnaXN0ZXIodTE2IAo+PiAqcmFuZG9tX3JlZ2lzdGVyKQo+PiDCoCB7 Cj4+IMKgwqDCoMKgwqAgdTE2IGJpdDsKPj4gwqDCoMKgwqDCoCB1MTYgcmFuZG9tX3JlZyA9ICpy YW5kb21fcmVnaXN0ZXI7Cj4+IEBAIC0yMjQsMjEgKzIyNCwyMCBAQCBzdGF0aWMgaW5saW5lIHZv aWQgCj4+IHJvY2tjaGlwX2F2MV91cGRhdGVfcmFuZG9tX3JlZ2lzdGVyKHUxNiAqcmFuZG9tX3Jl Z2lzdGVyKQo+PiDCoMKgwqDCoMKgICpyYW5kb21fcmVnaXN0ZXIgPSAocmFuZG9tX3JlZyA+PiAx KSB8IChiaXQgPDwgMTUpOwo+PiDCoCB9Cj4+IMKgIC1zdGF0aWMgaW5saW5lIHMzMiByb2NrY2hp cF9hdjFfZ2V0X3JhbmRvbV9udW1iZXIodTE2IHJhbmRvbV9yZWdpc3RlcikKPj4gK3N0YXRpYyBp bmxpbmUgczMyIGhhbnRyb19hdjFfZ2V0X3JhbmRvbV9udW1iZXIodTE2IHJhbmRvbV9yZWdpc3Rl cikKPj4gwqAgewo+PiDCoMKgwqDCoMKgIHJldHVybiAocmFuZG9tX3JlZ2lzdGVyID4+IDUpICYg KCgxIDw8IDExKSAtIDEpOwo+PiDCoCB9Cj4+IMKgIC12b2lkIHJvY2tjaGlwX2F2MV9nZW5lcmF0 ZV9sdW1hX2dyYWluX2Jsb2NrKHMzMiAKPj4gKCpsdW1hX2dyYWluX2Jsb2NrKVs3M11bODJdLAo+ PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgYml0 ZGVwdGgsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IHU4IG51bV95X3BvaW50cywKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgczMyIGdyYWluX3NjYWxlX3NoaWZ0LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgYXJfY29lZmZfbGFnLAo+PiAtwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgKCphcl9jb2VmZnNf eSlbMjRdLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBzMzIgYXJfY29lZmZfc2hpZnQsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIHMzMiBncmFpbl9taW4sCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHMzMiBncmFpbl9tYXgsCj4+IC3CoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHUxNiByYW5kb21fc2VlZCkKPj4gK3Zv aWQgaGFudHJvX2F2MV9nZW5lcmF0ZV9sdW1hX2dyYWluX2Jsb2NrKHN0cnVjdCAKPj4gaGFudHJv X2F2MV9jb2VmZnNfZ3JhaW5fYmxvY2sgKmNvZWZmcywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgYml0ZGVwdGgsCj4+ICvCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdTggbnVtX3lfcG9pbnRzLAo+PiArwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHMzMiBncmFpbl9zY2FsZV9zaGlmdCwK Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgYXJfY29l ZmZfbGFnLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHMz MiBhcl9jb2VmZl9zaGlmdCwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBzMzIgZ3JhaW5fbWluLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIHMzMiBncmFpbl9tYXgsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgdTE2IHJhbmRvbV9zZWVkKQo+PiDCoCB7Cj4+IMKgwqDCoMKgwqAg czMyIGdhdXNzX3NlY19zaGlmdCA9IDEyIC0gYml0ZGVwdGggKyBncmFpbl9zY2FsZV9zaGlmdDsK Pj4gwqDCoMKgwqDCoCB1MTYgZ3JhaW5fcmFuZG9tX3JlZ2lzdGVyID0gcmFuZG9tX3NlZWQ7Cj4+ IEBAIC0yNDcsMTUgKzI0NiwxNSBAQCB2b2lkIHJvY2tjaGlwX2F2MV9nZW5lcmF0ZV9sdW1hX2dy YWluX2Jsb2NrKHMzMiAKPj4gKCpsdW1hX2dyYWluX2Jsb2NrKVs3M11bODJdLAo+PiDCoMKgwqDC oMKgIGZvciAoaSA9IDA7IGkgPCA3MzsgaSsrKSB7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBmb3Ig KGogPSAwOyBqIDwgODI7IGorKykgewo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBpZiAo bnVtX3lfcG9pbnRzID4gMCkgewo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJv Y2tjaGlwX2F2MV91cGRhdGVfcmFuZG9tX3JlZ2lzdGVyCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgaGFudHJvX2F2MV91cGRhdGVfcmFuZG9tX3JlZ2lzdGVyCj4+IMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoJmdyYWluX3JhbmRvbV9yZWdpc3Rl cik7Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKCpsdW1hX2dyYWluX2Jsb2Nr KVtpXVtqXSA9Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgY29lZmZzLT5sdW1h X2dyYWluX2Jsb2NrW2ldW2pdID0KPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIHJvdW5kX3Bvd2VyX29mX3R3byhnYXVzc2lhbl9zZXF1ZW5jZQo+PiAtwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFtyb2NrY2hpcF9hdjFf Z2V0X3JhbmRvbV9udW1iZXIKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCBbaGFudHJvX2F2MV9nZXRfcmFuZG9tX251bWJlcgo+PiDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGdyYWluX3JhbmRv bV9yZWdpc3RlcildLAo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIGdhdXNzX3NlY19zaGlmdCk7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIH0gZWxzZSB7Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKCpsdW1hX2dy YWluX2Jsb2NrKVtpXVtqXSA9IDA7Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg Y29lZmZzLT5sdW1hX2dyYWluX2Jsb2NrW2ldW2pdID0gMDsKPj4gwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgfQo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgfQo+PiDCoMKgwqDCoMKgIH0KPj4gQEAg LTI3Miw3MiArMjcxLDY4IEBAIHZvaWQgcm9ja2NoaXBfYXYxX2dlbmVyYXRlX2x1bWFfZ3JhaW5f YmxvY2soczMyIAo+PiAoKmx1bWFfZ3JhaW5fYmxvY2spWzczXVs4Ml0sCj4+IMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGRlbHRhY29sIDw9IGFyX2NvZWZmX2xh ZzsgZGVsdGFjb2wrKykgewo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgaWYgKGRlbHRhcm93ID09IDAgJiYgZGVsdGFjb2wgPT0gMCkKPj4gwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYnJlYWs7Cj4+IC3CoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB3c3VtID0gd3N1bSArICgqYXJfY29lZmZz X3kpW3Bvc10gKgo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCAoKmx1bWFfZ3JhaW5fYmxvY2spW2kgKyBkZWx0YXJvd11baiArIAo+PiBkZWx0YWNvbF07 Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB3c3VtID0gd3N1bSAr IGNvZWZmcy0+YXJfY29lZmZzX3lbcG9zXSAqCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIGNvZWZmcy0+bHVtYV9ncmFpbl9ibG9ja1tpICsgZGVsdGFy b3ddW2ogKyAKPj4gZGVsdGFjb2xdOwo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgKytwb3M7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg fQo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB9Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDC oMKgICgqbHVtYV9ncmFpbl9ibG9jaylbaV1bal0gPQo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIGNsYW1wKCgqbHVtYV9ncmFpbl9ibG9jaylbaV1bal0gKwo+PiArwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCBjb2VmZnMtPmx1bWFfZ3JhaW5fYmxvY2tbaV1bal0gPQo+PiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGNsYW1wKGNvZWZmcy0+bHVtYV9ncmFpbl9ibG9ja1tp XVtqXSArCj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg cm91bmRfcG93ZXJfb2ZfdHdvKHdzdW0sIGFyX2NvZWZmX3NoaWZ0KSwKPj4gwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBncmFpbl9taW4sIGdyYWluX21heCk7 Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCB9Cj4+IMKgIH0KPj4gwqAgwqAgLy8gQ2FsY3VsYXRlIGNo cm9tYSBncmFpbiBub2lzZSBvbmNlIHBlciBmcmFtZQo+PiAtdm9pZCByb2NrY2hpcF9hdjFfZ2Vu ZXJhdGVfY2hyb21hX2dyYWluX2Jsb2NrKHMzMiAKPj4gKCpsdW1hX2dyYWluX2Jsb2NrKVs3M11b ODJdLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgczMyICgqY2JfZ3JhaW5fYmxvY2spWzM4XVs0NF0sCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgKCpjcl9ncmFpbl9ibG9jaylbMzhd WzQ0XSwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIHMzMiBiaXRkZXB0aCwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIHU4IG51bV95X3BvaW50cywKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHU4IG51bV9jYl9wb2ludHMsCj4+IC3CoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB1OCBudW1fY3Jf cG9pbnRzLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgczMyIGdyYWluX3NjYWxlX3NoaWZ0LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgczMyIGFyX2NvZWZmX2xhZywKPj4gLcKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHMzMiAoKmFyX2NvZWZm c19jYilbMjVdLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgczMyICgqYXJfY29lZmZzX2NyKVsyNV0sCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgYXJfY29lZmZfc2hpZnQsCj4+IC3C oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgZ3Jh aW5fbWluLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgczMyIGdyYWluX21heCwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIHU4IGNocm9tYV9zY2FsaW5nX2Zyb21fbHVtYSwKPj4gLcKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHUxNiByYW5kb21f c2VlZCkKPj4gK3ZvaWQgaGFudHJvX2F2MV9nZW5lcmF0ZV9jaHJvbWFfZ3JhaW5fYmxvY2soc3Ry dWN0IAo+PiBoYW50cm9fYXYxX2NvZWZmc19ncmFpbl9ibG9jayAqY29lZmZzLAo+PiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgYml0ZGVwdGgsCj4+ ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHU4IG51bV95 X3BvaW50cywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgdTggbnVtX2NiX3BvaW50cywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgdTggbnVtX2NyX3BvaW50cywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgczMyIGdyYWluX3NjYWxlX3NoaWZ0LAo+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgYXJfY29lZmZf bGFnLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBz MzIgYXJfY29lZmZfc2hpZnQsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIHMzMiBncmFpbl9taW4sCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIHMzMiBncmFpbl9tYXgsCj4+ICvCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHU4IGNocm9tYV9zY2FsaW5nX2Zyb21fbHVt YSwKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdTE2 IHJhbmRvbV9zZWVkKQo+PiDCoCB7Cj4+IMKgwqDCoMKgwqAgczMyIGdhdXNzX3NlY19zaGlmdCA9 IDEyIC0gYml0ZGVwdGggKyBncmFpbl9zY2FsZV9zaGlmdDsKPj4gwqDCoMKgwqDCoCB1MTYgZ3Jh aW5fcmFuZG9tX3JlZ2lzdGVyID0gMDsKPj4gwqDCoMKgwqDCoCBzMzIgaSwgajsKPj4gwqAgLcKg wqDCoCByb2NrY2hpcF9hdjFfaW5pdF9yYW5kb21fZ2VuZXJhdG9yKDcsIHJhbmRvbV9zZWVkLAo+ PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgJmdyYWluX3Jh bmRvbV9yZWdpc3Rlcik7Cj4+ICvCoMKgwqAgaGFudHJvX2F2MV9pbml0X3JhbmRvbV9nZW5lcmF0 b3IoNywgcmFuZG9tX3NlZWQsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgICZncmFpbl9yYW5kb21fcmVnaXN0ZXIpOwo+PiDCoMKgwqDCoMKgIGZvciAoaSA9IDA7 IGkgPCAzODsgaSsrKSB7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBmb3IgKGogPSAwOyBqIDwgNDQ7 IGorKykgewo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBpZiAobnVtX2NiX3BvaW50cyB8 fCBjaHJvbWFfc2NhbGluZ19mcm9tX2x1bWEpIHsKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCByb2NrY2hpcF9hdjFfdXBkYXRlX3JhbmRvbV9yZWdpc3Rlcgo+PiArwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIGhhbnRyb19hdjFfdXBkYXRlX3JhbmRvbV9yZWdpc3Rlcgo+ PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKCZncmFpbl9yYW5k b21fcmVnaXN0ZXIpOwo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICgqY2JfZ3Jh aW5fYmxvY2spW2ldW2pdID0KPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBjb2Vm ZnMtPmNiX2dyYWluX2Jsb2NrW2ldW2pdID0KPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIHJvdW5kX3Bvd2VyX29mX3R3byhnYXVzc2lhbl9zZXF1ZW5jZQo+PiAt wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFtyb2NrY2hp cF9hdjFfZ2V0X3JhbmRvbV9udW1iZXIKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBbaGFudHJvX2F2MV9nZXRfcmFuZG9tX251bWJlcgo+PiDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGdyYWlu X3JhbmRvbV9yZWdpc3RlcildLAo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIGdhdXNzX3NlY19zaGlmdCk7Cj4+IMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIH0gZWxzZSB7Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKCpj Yl9ncmFpbl9ibG9jaylbaV1bal0gPSAwOwo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIGNvZWZmcy0+Y2JfZ3JhaW5fYmxvY2tbaV1bal0gPSAwOwo+PiDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCB9Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCB9Cj4+IMKgwqDCoMKgwqAgfQo+PiDC oCAtwqDCoMKgIHJvY2tjaGlwX2F2MV9pbml0X3JhbmRvbV9nZW5lcmF0b3IoMTEsIHJhbmRvbV9z ZWVkLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgJmdy YWluX3JhbmRvbV9yZWdpc3Rlcik7Cj4+ICvCoMKgwqAgaGFudHJvX2F2MV9pbml0X3JhbmRvbV9n ZW5lcmF0b3IoMTEsIHJhbmRvbV9zZWVkLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCAmZ3JhaW5fcmFuZG9tX3JlZ2lzdGVyKTsKPj4gwqDCoMKgwqDCoCBmb3Ig KGkgPSAwOyBpIDwgMzg7IGkrKykgewo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgZm9yIChqID0gMDsg aiA8IDQ0OyBqKyspIHsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKG51bV9jcl9w b2ludHMgfHwgY2hyb21hX3NjYWxpbmdfZnJvbV9sdW1hKSB7Cj4+IC3CoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgcm9ja2NoaXBfYXYxX3VwZGF0ZV9yYW5kb21fcmVnaXN0ZXIKPj4gK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBoYW50cm9fYXYxX3VwZGF0ZV9yYW5kb21fcmVn aXN0ZXIKPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICgmZ3Jh aW5fcmFuZG9tX3JlZ2lzdGVyKTsKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAo KmNyX2dyYWluX2Jsb2NrKVtpXVtqXSA9Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgY29lZmZzLT5jcl9ncmFpbl9ibG9ja1tpXVtqXSA9Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByb3VuZF9wb3dlcl9vZl90d28oZ2F1c3NpYW5fc2VxdWVu Y2UKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBb cm9ja2NoaXBfYXYxX2dldF9yYW5kb21fbnVtYmVyCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgW2hhbnRyb19hdjFfZ2V0X3JhbmRvbV9udW1iZXIK Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IChncmFpbl9yYW5kb21fcmVnaXN0ZXIpXSwKPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBnYXVzc19zZWNfc2hpZnQpOwo+PiDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCB9IGVsc2Ugewo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgICgqY3JfZ3JhaW5fYmxvY2spW2ldW2pdID0gMDsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCBjb2VmZnMtPmNyX2dyYWluX2Jsb2NrW2ldW2pdID0gMDsKPj4gwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgfQo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgfQo+PiDCoMKgwqDCoMKg IH0KPj4gQEAgLTM1NSwxMiArMzUwLDEyIEBAIHZvaWQgCj4+IHJvY2tjaGlwX2F2MV9nZW5lcmF0 ZV9jaHJvbWFfZ3JhaW5fYmxvY2soczMyIAo+PiAoKmx1bWFfZ3JhaW5fYmxvY2spWzczXVs4Ml0s Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGRlbHRhY29s IDw9IGFyX2NvZWZmX2xhZzsgZGVsdGFjb2wrKykgewo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKGRlbHRhcm93ID09IDAgJiYgZGVsdGFjb2wgPT0gMCkK Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYnJl YWs7Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB3c3VtX2NiID0g d3N1bV9jYiArICgqYXJfY29lZmZzX2NiKVtwb3NdICoKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKCpjYl9ncmFpbl9ibG9jaylbaSArIGRlbHRhcm93 XVtqICsgZGVsdGFjb2xdOwo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgd3N1bV9jYiA9IHdzdW1fY2IgKyBjb2VmZnMtPmFyX2NvZWZmc19jYltwb3NdICoKPj4gK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgY29lZmZzLT5jYl9n cmFpbl9ibG9ja1tpICsgZGVsdGFyb3ddW2ogKyAKPj4gZGVsdGFjb2xdOwo+PiDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgd3N1bV9jciA9Cj4+IMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHdzdW1fY3IgKwo+PiAtwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoKmFyX2NvZWZmc19j cilbcG9zXSAqCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgICgqY3JfZ3JhaW5fYmxvY2spW2kgKyBkZWx0YXJvd11baiArIGRlbHRhY29sXTsKPj4gK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgY29lZmZzLT5hcl9j b2VmZnNfY3JbcG9zXSAqCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIGNvZWZmcy0+Y3JfZ3JhaW5fYmxvY2tbaSArIGRlbHRhcm93XVtqICsgCj4+IGRl bHRhY29sXTsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICsr cG9zOwo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIH0KPj4gwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgfQo+PiBAQCAtMzcxLDI4ICszNjYsMjggQEAgdm9pZCAKPj4gcm9j a2NoaXBfYXYxX2dlbmVyYXRlX2Nocm9tYV9ncmFpbl9ibG9jayhzMzIgCj4+ICgqbHVtYV9ncmFp bl9ibG9jaylbNzNdWzgyXSwKPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBz MzIgbHVtYV9jb29yZF94ID0gKGogPDwgMSkgLSAzOwo+PiDCoCDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIGF2X2x1bWEgKz0KPj4gLSAoKmx1bWFfZ3JhaW5fYmxvY2spW2x1bWFf Y29vcmRfeV1bbHVtYV9jb29yZF94XTsKPj4gKyBjb2VmZnMtPmx1bWFfZ3JhaW5fYmxvY2tbbHVt YV9jb29yZF95XVtsdW1hX2Nvb3JkX3hdOwo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIGF2X2x1bWEgKz0KPj4gLSAoKmx1bWFfZ3JhaW5fYmxvY2spW2x1bWFfY29vcmRfeV1b bHVtYV9jb29yZF94ICsgMV07Cj4+ICsgY29lZmZzLT5sdW1hX2dyYWluX2Jsb2NrW2x1bWFfY29v cmRfeV1bbHVtYV9jb29yZF94ICsgMV07Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgYXZfbHVtYSArPQo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgKCpsdW1hX2dyYWluX2Jsb2NrKVtsdW1hX2Nvb3JkX3kgKyAKPj4gMV1bbHVtYV9jb29yZF94 XTsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGNvZWZmcy0+bHVt YV9ncmFpbl9ibG9ja1tsdW1hX2Nvb3JkX3kgKyAKPj4gMV1bbHVtYV9jb29yZF94XTsKPj4gwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdl9sdW1hICs9Cj4+IC3CoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoKmx1bWFfZ3JhaW5fYmxvY2spWyhsdW1hX2Nv b3JkX3kgKyAKPj4gMSldW2x1bWFfY29vcmRfeCArIDFdOwo+PiArwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgY29lZmZzLT5sdW1hX2dyYWluX2Jsb2NrWyhsdW1hX2Nvb3Jk X3kgKyAKPj4gMSldW2x1bWFfY29vcmRfeCArIDFdOwo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIGF2X2x1bWEgPSByb3VuZF9wb3dlcl9vZl90d28oYXZfbHVtYSwgMik7Cj4+ IMKgIC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgd3N1bV9jYiA9IHdzdW1fY2IgKyAo KmFyX2NvZWZmc19jYilbcG9zXSAqIGF2X2x1bWE7Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgd3N1bV9jciA9IHdzdW1fY3IgKyAoKmFyX2NvZWZmc19jcilbcG9zXSAqIGF2X2x1 bWE7Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgd3N1bV9jYiA9IHdzdW1fY2Ig KyBjb2VmZnMtPmFyX2NvZWZmc19jYltwb3NdICogCj4+IGF2X2x1bWE7Cj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgd3N1bV9jciA9IHdzdW1fY3IgKyBjb2VmZnMtPmFyX2NvZWZm c19jcltwb3NdICogCj4+IGF2X2x1bWE7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIH0K Pj4gwqAgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKG51bV9jYl9wb2ludHMgfHwgY2hy b21hX3NjYWxpbmdfZnJvbV9sdW1hKSB7Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgKCpjYl9ncmFpbl9ibG9jaylbaV1bal0gPQo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgY2xhbXAoKCpjYl9ncmFpbl9ibG9jaylbaV1bal0gKwo+PiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGNvZWZmcy0+Y2JfZ3JhaW5fYmxvY2tbaV1bal0gPQo+ PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgY2xhbXAoY29lZmZzLT5j Yl9ncmFpbl9ibG9ja1tpXVtqXSArCj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgcm91bmRfcG93ZXJfb2ZfdHdvKHdzdW1fY2IsIGFyX2NvZWZmX3NoaWZ0 KSwKPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBncmFp bl9taW4sIGdyYWluX21heCk7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIH0KPj4gwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKG51bV9jcl9wb2ludHMgfHwgY2hyb21hX3NjYWxp bmdfZnJvbV9sdW1hKSB7Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKCpjcl9n cmFpbl9ibG9jaylbaV1bal0gPQo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgY2xhbXAoKCpjcl9ncmFpbl9ibG9jaylbaV1bal0gKwo+PiArwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIGNvZWZmcy0+Y3JfZ3JhaW5fYmxvY2tbaV1bal0gPQo+PiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgY2xhbXAoY29lZmZzLT5jcl9ncmFpbl9i bG9ja1tpXVtqXSArCj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgcm91bmRfcG93ZXJfb2ZfdHdvKHdzdW1fY3IsIGFyX2NvZWZmX3NoaWZ0KSwKPj4gwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBncmFpbl9taW4sIGdy YWluX21heCk7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIH0KPj4gZGlmZiAtLWdpdCAK Pj4gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL2hhbnRyb19hdjFfZmlsbWdy YWluLmggCj4+IGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS92ZXJpc2lsaWNvbi9oYW50cm9fYXYx X2ZpbG1ncmFpbi5oCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGluZGV4IDAwMDAwMDAwMDAw MC4uZDgwYmU3YzAxMWEwCj4+IC0tLSAvZGV2L251bGwKPj4gKysrIGIvZHJpdmVycy9tZWRpYS9w bGF0Zm9ybS92ZXJpc2lsaWNvbi9oYW50cm9fYXYxX2ZpbG1ncmFpbi5oCj4+IEBAIC0wLDAgKzEs NDggQEAKPj4gKy8qIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkgKi8KPj4g Kwo+PiArI2lmbmRlZiBfSEFOVFJPX0FWMV9GSUxNR1JBSU5fSF8KPj4gKyNkZWZpbmUgX0hBTlRS T19BVjFfRklMTUdSQUlOX0hfCj4+ICsKPj4gKyNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgo+PiAr Cj4+ICtzdHJ1Y3QgaGFudHJvX2F2MV9maWxtX2dyYWluIHsKPj4gK8KgwqDCoCB1OCBzY2FsaW5n X2x1dF95WzI1Nl07Cj4+ICvCoMKgwqAgdTggc2NhbGluZ19sdXRfY2JbMjU2XTsKPj4gK8KgwqDC oCB1OCBzY2FsaW5nX2x1dF9jclsyNTZdOwo+PiArwqDCoMKgIHMxNiBjcm9wcGVkX2x1bWFfZ3Jh aW5fYmxvY2tbNDA5Nl07Cj4+ICvCoMKgwqAgczE2IGNyb3BwZWRfY2hyb21hX2dyYWluX2Jsb2Nr WzEwMjQgKiAyXTsKPj4gK307Cj4+ICsKPj4gK3N0cnVjdCBoYW50cm9fYXYxX2NvZWZmc19ncmFp bl9ibG9jayB7Cj4+ICvCoMKgwqAgczMyIGFyX2NvZWZmc195WzI0XTsKPj4gK8KgwqDCoCBzMzIg YXJfY29lZmZzX2NiWzI1XTsKPj4gK8KgwqDCoCBzMzIgYXJfY29lZmZzX2NyWzI1XTsKPj4gK8Kg wqDCoCBzMzIgbHVtYV9ncmFpbl9ibG9ja1s3M11bODJdOwo+PiArwqDCoMKgIHMzMiBjYl9ncmFp bl9ibG9ja1szOF1bNDRdOwo+PiArwqDCoMKgIHMzMiBjcl9ncmFpbl9ibG9ja1szOF1bNDRdOwo+ PiArfTsKPj4gKwo+PiArdm9pZCBoYW50cm9fYXYxX2dlbmVyYXRlX2x1bWFfZ3JhaW5fYmxvY2so c3RydWN0IAo+PiBoYW50cm9fYXYxX2NvZWZmc19ncmFpbl9ibG9jayAqY29lZmZzLAo+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHMzMiBiaXRkZXB0aCwKPj4g K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB1OCBudW1feV9wb2lu dHMsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgczMyIGdy YWluX3NjYWxlX3NoaWZ0LAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIHMzMiBhcl9jb2VmZl9sYWcsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgczMyIGFyX2NvZWZmX3NoaWZ0LAo+PiArwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHMzMiBncmFpbl9taW4sCj4+ICvCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgczMyIGdyYWluX21heCwKPj4gK8KgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB1MTYgcmFuZG9tX3NlZWQpOwo+PiAr Cj4+ICt2b2lkIGhhbnRyb19hdjFfZ2VuZXJhdGVfY2hyb21hX2dyYWluX2Jsb2NrKHN0cnVjdCAK Pj4gaGFudHJvX2F2MV9jb2VmZnNfZ3JhaW5fYmxvY2sgKmNvZWZmcywKPj4gK8KgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgczMyIGJpdGRlcHRoLAo+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB1OCBudW1feV9wb2lu dHMsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHU4 IG51bV9jYl9wb2ludHMsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIHU4IG51bV9jcl9wb2ludHMsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIHMzMiBncmFpbl9zY2FsZV9zaGlmdCwKPj4gK8KgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgczMyIGFyX2NvZWZmX2xhZywK Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgczMyIGFy X2NvZWZmX3NoaWZ0LAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBzMzIgZ3JhaW5fbWluLAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCBzMzIgZ3JhaW5fbWF4LAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB1OCBjaHJvbWFfc2NhbGluZ19mcm9tX2x1bWEsCj4+ ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHUxNiByYW5k b21fc2VlZCk7Cj4+ICsKPj4gKyNlbmRpZgo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9tZWRpYS9w bGF0Zm9ybS92ZXJpc2lsaWNvbi9oYW50cm9faHcuaCAKPj4gYi9kcml2ZXJzL21lZGlhL3BsYXRm b3JtL3ZlcmlzaWxpY29uL2hhbnRyb19ody5oCj4+IGluZGV4IDVmMjAxMTUyOWYwMi4uZDFkMzlk MWRmNWQyIDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29u L2hhbnRyb19ody5oCj4+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24v aGFudHJvX2h3LmgKPj4gQEAgLTE1LDggKzE1LDggQEAKPj4gwqAgI2luY2x1ZGUgPG1lZGlhL3Y0 bDItdnA5Lmg+Cj4+IMKgICNpbmNsdWRlIDxtZWRpYS92aWRlb2J1ZjItY29yZS5oPgo+PiDCoCAt I2luY2x1ZGUgInJvY2tjaGlwX2F2MV9lbnRyb3B5bW9kZS5oIgo+PiAtI2luY2x1ZGUgInJvY2tj aGlwX2F2MV9maWxtZ3JhaW4uaCIKPj4gKyNpbmNsdWRlICJoYW50cm9fYXYxX2VudHJvcHltb2Rl LmgiCj4+ICsjaW5jbHVkZSAiaGFudHJvX2F2MV9maWxtZ3JhaW4uaCIKPj4gwqAgwqAgI2RlZmlu ZSBERUNfODE5MF9BTElHTl9NQVNLwqDCoMKgIDB4MDdVCj4+IMKgIEBAIC00NTksMTAgKzQ1OSw3 IEBAIHZvaWQgaGFudHJvX2hldmNfcmVmX2luaXQoc3RydWN0IGhhbnRyb19jdHggCj4+ICpjdHgp Owo+PiDCoCBkbWFfYWRkcl90IGhhbnRyb19oZXZjX2dldF9yZWZfYnVmKHN0cnVjdCBoYW50cm9f Y3R4ICpjdHgsIHMzMiBwb2MpOwo+PiDCoCBpbnQgaGFudHJvX2hldmNfYWRkX3JlZl9idWYoc3Ry dWN0IGhhbnRyb19jdHggKmN0eCwgaW50IHBvYywgCj4+IGRtYV9hZGRyX3QgYWRkcik7Cj4+IMKg IC1pbnQgcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfaW5pdChzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4 KTsKPj4gLXZvaWQgcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZXhpdChzdHJ1Y3QgaGFudHJvX2N0 eCAqY3R4KTsKPj4gwqAgaW50IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX3J1bihzdHJ1Y3QgaGFu dHJvX2N0eCAqY3R4KTsKPj4gLXZvaWQgcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZG9uZShzdHJ1 Y3QgaGFudHJvX2N0eCAqY3R4KTsKPj4gwqAgwqAgc3RhdGljIGlubGluZSB1bnNpZ25lZCBzaG9y dCBoYW50cm9fdnA5X251bV9zYnModW5zaWduZWQgc2hvcnQgCj4+IGRpbWVuc2lvbikKPj4gwqAg ewo+PiBkaWZmIC0tZ2l0IAo+PiBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24v cm9ja2NoaXBfYXYxX2ZpbG1ncmFpbi5oIAo+PiBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVy aXNpbGljb24vcm9ja2NoaXBfYXYxX2ZpbG1ncmFpbi5oCj4+IGRlbGV0ZWQgZmlsZSBtb2RlIDEw MDY0NAo+PiBpbmRleCAzMWE4Yjc5MjBjMzEuLjAwMDAwMDAwMDAwMAo+PiAtLS0gYS9kcml2ZXJz L21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL3JvY2tjaGlwX2F2MV9maWxtZ3JhaW4uaAo+PiAr KysgL2Rldi9udWxsCj4+IEBAIC0xLDM2ICswLDAgQEAKPj4gLS8qIFNQRFgtTGljZW5zZS1JZGVu dGlmaWVyOiBHUEwtMi4wLW9ubHkgKi8KPj4gLQo+PiAtI2lmbmRlZiBfUk9DS0NISVBfQVYxX0ZJ TE1HUkFJTl9IXwo+PiAtI2RlZmluZSBfUk9DS0NISVBfQVYxX0ZJTE1HUkFJTl9IXwo+PiAtCj4+ IC0jaW5jbHVkZSA8bGludXgvdHlwZXMuaD4KPj4gLQo+PiAtdm9pZCByb2NrY2hpcF9hdjFfZ2Vu ZXJhdGVfbHVtYV9ncmFpbl9ibG9jayhzMzIgCj4+ICgqbHVtYV9ncmFpbl9ibG9jaylbNzNdWzgy XSwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgczMy IGJpdGRlcHRoLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCB1OCBudW1feV9wb2ludHMsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIHMzMiBncmFpbl9zY2FsZV9zaGlmdCwKPj4gLcKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgczMyIGFyX2NvZWZmX2xhZywKPj4gLcKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgczMyICgqYXJfY29l ZmZzX3kpWzI0XSwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgczMyIGFyX2NvZWZmX3NoaWZ0LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgZ3JhaW5fbWluLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgZ3JhaW5fbWF4LAo+PiAtwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB1MTYgcmFuZG9tX3NlZWQpOwo+ PiAtCj4+IC12b2lkIHJvY2tjaGlwX2F2MV9nZW5lcmF0ZV9jaHJvbWFfZ3JhaW5fYmxvY2soczMy IAo+PiAoKmx1bWFfZ3JhaW5fYmxvY2spWzczXVs4Ml0sCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgKCpjYl9ncmFpbl9ibG9jaylbMzhd WzQ0XSwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIHMzMiAoKmNyX2dyYWluX2Jsb2NrKVszOF1bNDRdLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgczMyIGJpdGRlcHRoLAo+PiAtwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdTggbnVtX3lfcG9p bnRzLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgdTggbnVtX2NiX3BvaW50cywKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIHU4IG51bV9jcl9wb2ludHMsCj4+IC3CoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgZ3JhaW5fc2NhbGVfc2hpZnQs Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBz MzIgYXJfY29lZmZfbGFnLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgczMyICgqYXJfY29lZmZzX2NiKVsyNV0sCj4+IC3CoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgKCphcl9jb2VmZnNfY3Ip WzI1XSwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIHMzMiBhcl9jb2VmZl9zaGlmdCwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIHMzMiBncmFpbl9taW4sCj4+IC3CoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzMzIgZ3JhaW5fbWF4LAo+PiAtwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdTggY2hyb21h X3NjYWxpbmdfZnJvbV9sdW1hLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgdTE2IHJhbmRvbV9zZWVkKTsKPj4gLQo+PiAtI2VuZGlmCj4+IGRp ZmYgLS1naXQgCj4+IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS92ZXJpc2lsaWNvbi9yb2NrY2hp cF92cHU5ODFfaHdfYXYxX2RlYy5jIAo+PiBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNp bGljb24vcm9ja2NoaXBfdnB1OTgxX2h3X2F2MV9kZWMuYwo+PiBpbmRleCBlNGUyMWFkMzczMjMu LjYxZTMwMzM4NDIyZCAxMDA2NDQKPj4gLS0tIGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS92ZXJp c2lsaWNvbi9yb2NrY2hpcF92cHU5ODFfaHdfYXYxX2RlYy5jCj4+ICsrKyBiL2RyaXZlcnMvbWVk aWEvcGxhdGZvcm0vdmVyaXNpbGljb24vcm9ja2NoaXBfdnB1OTgxX2h3X2F2MV9kZWMuYwo+PiBA QCAtNyw2MjIgKzcsMzUgQEAKPj4gwqAgwqAgI2luY2x1ZGUgPG1lZGlhL3Y0bDItbWVtMm1lbS5o Pgo+PiDCoCAjaW5jbHVkZSAiaGFudHJvLmgiCj4+ICsjaW5jbHVkZSAiaGFudHJvX2F2MS5oIgo+ PiDCoCAjaW5jbHVkZSAiaGFudHJvX3Y0bDIuaCIKPj4gwqAgI2luY2x1ZGUgInJvY2tjaGlwX3Zw dTk4MV9yZWdzLmgiCj4+IMKgIMKgICNkZWZpbmUgQVYxX0RFQ19NT0RFwqDCoMKgwqDCoMKgwqAg MTcKPj4gLSNkZWZpbmUgR01fR0xPQkFMX01PREVMU19QRVJfRlJBTUXCoMKgwqAgNwo+PiAtI2Rl ZmluZSBHTE9CQUxfTU9ERUxfVE9UQUxfU0laRcKgwqDCoCAoNiAqIDQgKyA0ICogMikKPj4gLSNk ZWZpbmUgR0xPQkFMX01PREVMX1NJWkXCoMKgwqAgQUxJR04oR01fR0xPQkFMX01PREVMU19QRVJf RlJBTUUgKiAKPj4gR0xPQkFMX01PREVMX1RPVEFMX1NJWkUsIDIwNDgpCj4+IC0jZGVmaW5lIEFW MV9NQVhfVElMRVPCoMKgwqDCoMKgwqDCoCAxMjgKPj4gLSNkZWZpbmUgQVYxX1RJTEVfSU5GT19T SVpFwqDCoMKgIChBVjFfTUFYX1RJTEVTICogMTYpCj4+IC0jZGVmaW5lIEFWMURFQ19NQVhfUElD X0JVRkZFUlPCoMKgwqAgMjQKPj4gLSNkZWZpbmUgQVYxX1JFRl9TQ0FMRV9TSElGVMKgwqDCoCAx NAo+PiAtI2RlZmluZSBBVjFfSU5WQUxJRF9JRFjCoMKgwqDCoMKgwqDCoCAtMQo+PiAtI2RlZmlu ZSBNQVhfRlJBTUVfRElTVEFOQ0XCoMKgwqAgMzEKPj4gLSNkZWZpbmUgQVYxX1BSSU1BUllfUkVG X05PTkXCoMKgwqAgNwo+PiAtI2RlZmluZSBBVjFfVElMRV9TSVpFwqDCoMKgwqDCoMKgwqAgQUxJ R04oMzIgKiAxMjgsIDQwOTYpCj4+IC0vKgo+PiAtICogVGhlc2UgMyB2YWx1ZXMgYXJlbid0IGRl ZmluZWQgZW51bSB2NGwyX2F2MV9zZWdtZW50X2ZlYXR1cmUgYmVjYXVzZQo+PiAtICogdGhleSBh cmUgbm90IHBhcnQgb2YgdGhlIHNwZWNpZmljYXRpb24KPj4gLSAqLwo+PiAtI2RlZmluZSBWNEwy X0FWMV9TRUdfTFZMX0FMVF9MRl9ZX0jCoMKgwqAgMgo+PiAtI2RlZmluZSBWNEwyX0FWMV9TRUdf TFZMX0FMVF9MRl9VwqDCoMKgIDMKPj4gLSNkZWZpbmUgVjRMMl9BVjFfU0VHX0xWTF9BTFRfTEZf VsKgwqDCoCA0Cj4+IC0KPj4gLSNkZWZpbmUgU1VQRVJSRVNfU0NBTEVfQklUUyAzCj4+IC0jZGVm aW5lIFNDQUxFX05VTUVSQVRPUiA4Cj4+IC0jZGVmaW5lIFNVUEVSUkVTX1NDQUxFX0RFTk9NSU5B VE9SX01JTiAoU0NBTEVfTlVNRVJBVE9SICsgMSkKPj4gLQo+PiAtI2RlZmluZSBSU19TVUJQRUxf QklUUyA2Cj4+IC0jZGVmaW5lIFJTX1NVQlBFTF9NQVNLICgoMSA8PCBSU19TVUJQRUxfQklUUykg LSAxKQo+PiAtI2RlZmluZSBSU19TQ0FMRV9TVUJQRUxfQklUUyAxNAo+PiAtI2RlZmluZSBSU19T Q0FMRV9TVUJQRUxfTUFTSyAoKDEgPDwgUlNfU0NBTEVfU1VCUEVMX0JJVFMpIC0gMSkKPj4gLSNk ZWZpbmUgUlNfU0NBTEVfRVhUUkFfQklUUyAoUlNfU0NBTEVfU1VCUEVMX0JJVFMgLSBSU19TVUJQ RUxfQklUUykKPj4gLSNkZWZpbmUgUlNfU0NBTEVfRVhUUkFfT0ZGICgxIDw8IChSU19TQ0FMRV9F WFRSQV9CSVRTIC0gMSkpCj4+IC0KPj4gLSNkZWZpbmUgSVNfSU5UUkEodHlwZSkgKCh0eXBlID09 IFY0TDJfQVYxX0tFWV9GUkFNRSkgfHwgKHR5cGUgPT0gCj4+IFY0TDJfQVYxX0lOVFJBX09OTFlf RlJBTUUpKQo+PiAtCj4+IC0jZGVmaW5lIExTVF9CVUZfSURYIChWNEwyX0FWMV9SRUZfTEFTVF9G UkFNRSAtIFY0TDJfQVYxX1JFRl9MQVNUX0ZSQU1FKQo+PiAtI2RlZmluZSBMU1QyX0JVRl9JRFgg KFY0TDJfQVYxX1JFRl9MQVNUMl9GUkFNRSAtIAo+PiBWNEwyX0FWMV9SRUZfTEFTVF9GUkFNRSkK Pj4gLSNkZWZpbmUgTFNUM19CVUZfSURYIChWNEwyX0FWMV9SRUZfTEFTVDNfRlJBTUUgLSAKPj4g VjRMMl9BVjFfUkVGX0xBU1RfRlJBTUUpCj4+IC0jZGVmaW5lIEdMRF9CVUZfSURYIChWNEwyX0FW MV9SRUZfR09MREVOX0ZSQU1FIC0gCj4+IFY0TDJfQVYxX1JFRl9MQVNUX0ZSQU1FKQo+PiAtI2Rl ZmluZSBCV0RfQlVGX0lEWCAoVjRMMl9BVjFfUkVGX0JXRFJFRl9GUkFNRSAtIAo+PiBWNEwyX0FW MV9SRUZfTEFTVF9GUkFNRSkKPj4gLSNkZWZpbmUgQUxUMl9CVUZfSURYIChWNEwyX0FWMV9SRUZf QUxUUkVGMl9GUkFNRSAtIAo+PiBWNEwyX0FWMV9SRUZfTEFTVF9GUkFNRSkKPj4gLSNkZWZpbmUg QUxUX0JVRl9JRFggKFY0TDJfQVYxX1JFRl9BTFRSRUZfRlJBTUUgLSAKPj4gVjRMMl9BVjFfUkVG X0xBU1RfRlJBTUUpCj4+IC0KPj4gLSNkZWZpbmUgRElWX0xVVF9QUkVDX0JJVFMgMTQKPj4gLSNk ZWZpbmUgRElWX0xVVF9CSVRTIDgKPj4gLSNkZWZpbmUgRElWX0xVVF9OVU0gQklUKERJVl9MVVRf QklUUykKPj4gLSNkZWZpbmUgV0FSUF9QQVJBTV9SRURVQ0VfQklUUyA2Cj4+IC0jZGVmaW5lIFdB UlBFRE1PREVMX1BSRUNfQklUUyAxNgo+PiAtCj4+IC0jZGVmaW5lIEFWMV9ESVZfUk9VTkRfVVBf UE9XMih2YWx1ZSwgbinCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFwKPj4gLSh7wqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFwKPj4gLcKgwqDCoCB0 eXBlb2YobikgX27CoCA9IG47wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFwKPj4gLcKg wqDCoCB0eXBlb2YodmFsdWUpIF92YWx1ZSA9IHZhbHVlO8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAg XAo+PiAtwqDCoMKgIChfdmFsdWUgKyAoQklUKF9uKSA+PiAxKSkgPj4gX247wqDCoMKgwqDCoMKg wqAgXAo+PiAtfSkKPj4gLQo+PiAtI2RlZmluZSBBVjFfRElWX1JPVU5EX1VQX1BPVzJfU0lHTkVE KHZhbHVlLCBuKcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBcCj4+IC0oe8KgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgXAo+PiAtwqDCoMKgIHR5cGVvZihuKSBfbl/CoCA9IG47wqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBcCj4+IC3CoMKgwqAgdHlwZW9mKHZhbHVlKSBf dmFsdWVfID0gdmFsdWU7wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgXAo+ PiAtwqDCoMKgICgoKF92YWx1ZV8pIDwgMCkgPyAtQVYxX0RJVl9ST1VORF9VUF9QT1cyKC0oX3Zh bHVlXyksIChfbl8pKcKgwqDCoCBcCj4+IC3CoMKgwqDCoMKgwqDCoCA6IEFWMV9ESVZfUk9VTkRf VVBfUE9XMigoX3ZhbHVlXyksIChfbl8pKSk7wqDCoMKgwqDCoMKgwqAgXAo+PiAtfSkKPj4gLQo+ PiAtZW51bSByb2NrY2hpcF9hdjFfdHhfbW9kZSB7Cj4+IC3CoMKgwqAgUk9DS0NISVBfQVYxX1RY X01PREVfT05MWV80WDTCoMKgwqAgPSAwLAo+PiAtwqDCoMKgIFJPQ0tDSElQX0FWMV9UWF9NT0RF XzhYOMKgwqDCoCA9IDEsCj4+IC3CoMKgwqAgUk9DS0NISVBfQVYxX1RYX01PREVfMTZ4MTbCoMKg wqAgPSAyLAo+PiAtwqDCoMKgIFJPQ0tDSElQX0FWMV9UWF9NT0RFXzMyeDMywqDCoMKgID0gMywK Pj4gLcKgwqDCoCBST0NLQ0hJUF9BVjFfVFhfTU9ERV9TRUxFQ1TCoMKgwqAgPSA0LAo+PiAtfTsK Pj4gLQo+PiAtc3RydWN0IHJvY2tjaGlwX2F2MV9maWxtX2dyYWluIHsKPj4gLcKgwqDCoCB1OCBz Y2FsaW5nX2x1dF95WzI1Nl07Cj4+IC3CoMKgwqAgdTggc2NhbGluZ19sdXRfY2JbMjU2XTsKPj4g LcKgwqDCoCB1OCBzY2FsaW5nX2x1dF9jclsyNTZdOwo+PiAtwqDCoMKgIHMxNiBjcm9wcGVkX2x1 bWFfZ3JhaW5fYmxvY2tbNDA5Nl07Cj4+IC3CoMKgwqAgczE2IGNyb3BwZWRfY2hyb21hX2dyYWlu X2Jsb2NrWzEwMjQgKiAyXTsKPj4gLX07Cj4+IC0KPj4gLXN0YXRpYyBjb25zdCBzaG9ydCBkaXZf bHV0W0RJVl9MVVRfTlVNICsgMV0gPSB7Cj4+IC3CoMKgwqAgMTYzODQsIDE2MzIwLCAxNjI1Nywg MTYxOTQsIDE2MTMyLCAxNjA3MCwgMTYwMDksIDE1OTQ4LCAxNTg4OCwgCj4+IDE1ODI4LCAxNTc2 OCwKPj4gLcKgwqDCoCAxNTcwOSwgMTU2NTAsIDE1NTkyLCAxNTUzNCwgMTU0NzcsIDE1NDIwLCAx NTM2NCwgMTUzMDgsIDE1MjUyLCAKPj4gMTUxOTcsIDE1MTQyLAo+PiAtwqDCoMKgIDE1MDg3LCAx NTAzMywgMTQ5ODAsIDE0OTI2LCAxNDg3MywgMTQ4MjEsIDE0NzY5LCAxNDcxNywgMTQ2NjUsIAo+ PiAxNDYxNCwgMTQ1NjQsCj4+IC3CoMKgwqAgMTQ1MTMsIDE0NDYzLCAxNDQxMywgMTQzNjQsIDE0 MzE1LCAxNDI2NiwgMTQyMTgsIDE0MTcwLCAxNDEyMiwgCj4+IDE0MDc1LCAxNDAyOCwKPj4gLcKg wqDCoCAxMzk4MSwgMTM5MzUsIDEzODg4LCAxMzg0MywgMTM3OTcsIDEzNzUyLCAxMzcwNywgMTM2 NjIsIDEzNjE4LCAKPj4gMTM1NzQsIDEzNTMwLAo+PiAtwqDCoMKgIDEzNDg3LCAxMzQ0MywgMTM0 MDAsIDEzMzU4LCAxMzMxNSwgMTMyNzMsIDEzMjMxLCAxMzE5MCwgMTMxNDgsIAo+PiAxMzEwNywg MTMwNjYsCj4+IC3CoMKgwqAgMTMwMjYsIDEyOTg1LCAxMjk0NSwgMTI5MDYsIDEyODY2LCAxMjgy NywgMTI3ODgsIDEyNzQ5LCAxMjcxMCwgCj4+IDEyNjcyLCAxMjYzMywKPj4gLcKgwqDCoCAxMjU5 NiwgMTI1NTgsIDEyNTIwLCAxMjQ4MywgMTI0NDYsIDEyNDA5LCAxMjM3MywgMTIzMzYsIDEyMzAw LCAKPj4gMTIyNjQsIDEyMjI4LAo+PiAtwqDCoMKgIDEyMTkzLCAxMjE1NywgMTIxMjIsIDEyMDg3 LCAxMjA1MywgMTIwMTgsIDExOTg0LCAxMTk1MCwgMTE5MTYsIAo+PiAxMTg4MiwgMTE4NDgsCj4+ IC3CoMKgwqAgMTE4MTUsIDExNzgyLCAxMTc0OSwgMTE3MTYsIDExNjgzLCAxMTY1MSwgMTE2MTks IDExNTg2LCAxMTU1NSwgCj4+IDExNTIzLCAxMTQ5MSwKPj4gLcKgwqDCoCAxMTQ2MCwgMTE0Mjks IDExMzk4LCAxMTM2NywgMTEzMzYsIDExMzA1LCAxMTI3NSwgMTEyNDUsIDExMjE1LCAKPj4gMTEx ODUsIDExMTU1LAo+PiAtwqDCoMKgIDExMTI1LCAxMTA5NiwgMTEwNjcsIDExMDM4LCAxMTAwOSwg MTA5ODAsIDEwOTUxLCAxMDkyMywgMTA4OTQsIAo+PiAxMDg2NiwgMTA4MzgsCj4+IC3CoMKgwqAg MTA4MTAsIDEwNzgyLCAxMDc1NSwgMTA3MjcsIDEwNzAwLCAxMDY3MywgMTA2NDUsIDEwNjE4LCAx MDU5MiwgCj4+IDEwNTY1LCAxMDUzOCwKPj4gLcKgwqDCoCAxMDUxMiwgMTA0ODYsIDEwNDYwLCAx MDQzNCwgMTA0MDgsIDEwMzgyLCAxMDM1NiwgMTAzMzEsIDEwMzA1LCAKPj4gMTAyODAsIDEwMjU1 LAo+PiAtwqDCoMKgIDEwMjMwLCAxMDIwNSwgMTAxODAsIDEwMTU2LCAxMDEzMSwgMTAxMDcsIDEw MDgyLCAxMDA1OCwgMTAwMzQsIAo+PiAxMDAxMCwgOTk4NiwKPj4gLcKgwqDCoCA5OTYzLMKgIDk5 MzkswqAgOTkxNizCoCA5ODkyLMKgIDk4NjkswqAgOTg0NizCoCA5ODIzLMKgIDk4MDAsIDk3Nzcs wqAgCj4+IDk3NTQswqAgOTczMiwKPj4gLcKgwqDCoCA5NzA5LMKgIDk2ODcswqAgOTY2NCzCoCA5 NjQyLMKgIDk2MjAswqAgOTU5OCzCoCA5NTc2LMKgIDk1NTQsIDk1MzMswqAgCj4+IDk1MTEswqAg OTQ4OSwKPj4gLcKgwqDCoCA5NDY4LMKgIDk0NDcswqAgOTQyNSzCoCA5NDA0LMKgIDkzODMswqAg OTM2MizCoCA5MzQxLMKgIDkzMjEsIDkzMDAswqAgCj4+IDkyNzkswqAgOTI1OSwKPj4gLcKgwqDC oCA5MjM5LMKgIDkyMTgswqAgOTE5OCzCoCA5MTc4LMKgIDkxNTgswqAgOTEzOCzCoCA5MTE4LMKg IDkwOTgsIDkwNzkswqAgCj4+IDkwNTkswqAgOTAzOSwKPj4gLcKgwqDCoCA5MDIwLMKgIDkwMDEs wqAgODk4MSzCoCA4OTYyLMKgIDg5NDMswqAgODkyNCzCoCA4OTA1LMKgIDg4ODYsIDg4NjcswqAg Cj4+IDg4NDkswqAgODgzMCwKPj4gLcKgwqDCoCA4ODEyLMKgIDg3OTMswqAgODc3NSzCoCA4NzU2 LMKgIDg3MzgswqAgODcyMCzCoCA4NzAyLMKgIDg2ODQsIDg2NjYswqAgCj4+IDg2NDgswqAgODYz MCwKPj4gLcKgwqDCoCA4NjEzLMKgIDg1OTUswqAgODU3NyzCoCA4NTYwLMKgIDg1NDIswqAgODUy NSzCoCA4NTA4LMKgIDg0OTAsIDg0NzMswqAgCj4+IDg0NTYswqAgODQzOSwKPj4gLcKgwqDCoCA4 NDIyLMKgIDg0MDUswqAgODM4OSzCoCA4MzcyLMKgIDgzNTUswqAgODMzOSzCoCA4MzIyLMKgIDgz MDYsIDgyODkswqAgCj4+IDgyNzMswqAgODI1NywKPj4gLcKgwqDCoCA4MjQwLMKgIDgyMjQswqAg ODIwOCzCoCA4MTkyLAo+PiAtfTsKPj4gLQo+PiAtc3RhdGljIGludCByb2NrY2hpcF92cHU5ODFf Z2V0X2ZyYW1lX2luZGV4KHN0cnVjdCBoYW50cm9fY3R4ICpjdHgsIAo+PiBpbnQgcmVmKQo+PiAt ewo+PiAtwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19od19jdHggKmF2MV9kZWMgPSAmY3R4 LT5hdjFfZGVjOwo+PiAtwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19jdHJscyAqY3RybHMg PSAmYXYxX2RlYy0+Y3RybHM7Cj4+IC3CoMKgwqAgY29uc3Qgc3RydWN0IHY0bDJfY3RybF9hdjFf ZnJhbWUgKmZyYW1lID0gY3RybHMtPmZyYW1lOwo+PiAtwqDCoMKgIHU2NCB0aW1lc3RhbXA7Cj4+ IC3CoMKgwqAgaW50IGksIGlkeCA9IGZyYW1lLT5yZWZfZnJhbWVfaWR4W3JlZl07Cj4+IC0KPj4g LcKgwqDCoCBpZiAoaWR4ID49IFY0TDJfQVYxX1RPVEFMX1JFRlNfUEVSX0ZSQU1FIHx8IGlkeCA8 IDApCj4+IC3CoMKgwqDCoMKgwqDCoCByZXR1cm4gQVYxX0lOVkFMSURfSURYOwo+PiAtCj4+IC3C oMKgwqAgdGltZXN0YW1wID0gZnJhbWUtPnJlZmVyZW5jZV9mcmFtZV90c1tpZHhdOwo+PiAtwqDC oMKgIGZvciAoaSA9IDA7IGkgPCBBVjFfTUFYX0ZSQU1FX0JVRl9DT1VOVDsgaSsrKSB7Cj4+IC3C oMKgwqDCoMKgwqDCoCBpZiAoIWF2MV9kZWMtPmZyYW1lX3JlZnNbaV0udXNlZCkKPj4gLcKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgY29udGludWU7Cj4+IC3CoMKgwqDCoMKgwqDCoCBpZiAoYXYxX2Rl Yy0+ZnJhbWVfcmVmc1tpXS50aW1lc3RhbXAgPT0gdGltZXN0YW1wKQo+PiAtwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCByZXR1cm4gaTsKPj4gLcKgwqDCoCB9Cj4+IC0KPj4gLcKgwqDCoCByZXR1cm4g QVYxX0lOVkFMSURfSURYOwo+PiAtfQo+PiAtCj4+IC1zdGF0aWMgaW50IHJvY2tjaGlwX3ZwdTk4 MV9nZXRfb3JkZXJfaGludChzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4LCAKPj4gaW50IHJlZikKPj4g LXsKPj4gLcKgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfaHdfY3R4ICphdjFfZGVjID0gJmN0 eC0+YXYxX2RlYzsKPj4gLcKgwqDCoCBpbnQgaWR4ID0gcm9ja2NoaXBfdnB1OTgxX2dldF9mcmFt ZV9pbmRleChjdHgsIHJlZik7Cj4+IC0KPj4gLcKgwqDCoCBpZiAoaWR4ICE9IEFWMV9JTlZBTElE X0lEWCkKPj4gLcKgwqDCoMKgwqDCoMKgIHJldHVybiBhdjFfZGVjLT5mcmFtZV9yZWZzW2lkeF0u b3JkZXJfaGludDsKPj4gLQo+PiAtwqDCoMKgIHJldHVybiAwOwo+PiAtfQo+PiAtCj4+IC1zdGF0 aWMgaW50IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX2ZyYW1lX3JlZihzdHJ1Y3QgaGFudHJvX2N0 eCAqY3R4LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIHU2NCB0aW1lc3RhbXApCj4+IC17Cj4+IC3CoMKgwqAgc3RydWN0IGhhbnRyb19hdjFfZGVj X2h3X2N0eCAqYXYxX2RlYyA9ICZjdHgtPmF2MV9kZWM7Cj4+IC3CoMKgwqAgc3RydWN0IGhhbnRy b19hdjFfZGVjX2N0cmxzICpjdHJscyA9ICZhdjFfZGVjLT5jdHJsczsKPj4gLcKgwqDCoCBjb25z dCBzdHJ1Y3QgdjRsMl9jdHJsX2F2MV9mcmFtZSAqZnJhbWUgPSBjdHJscy0+ZnJhbWU7Cj4+IC3C oMKgwqAgaW50IGk7Cj4+IC0KPj4gLcKgwqDCoCBmb3IgKGkgPSAwOyBpIDwgQVYxX01BWF9GUkFN RV9CVUZfQ09VTlQ7IGkrKykgewo+PiAtwqDCoMKgwqDCoMKgwqAgaW50IGo7Cj4+IC0KPj4gLcKg wqDCoMKgwqDCoMKgIGlmIChhdjFfZGVjLT5mcmFtZV9yZWZzW2ldLnVzZWQpCj4+IC3CoMKgwqDC oMKgwqDCoMKgwqDCoMKgIGNvbnRpbnVlOwo+PiAtCj4+IC3CoMKgwqDCoMKgwqDCoCBhdjFfZGVj LT5mcmFtZV9yZWZzW2ldLndpZHRoID0gZnJhbWUtPmZyYW1lX3dpZHRoX21pbnVzXzEgKyAxOwo+ PiAtwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+ZnJhbWVfcmVmc1tpXS5oZWlnaHQgPSBmcmFtZS0+ ZnJhbWVfaGVpZ2h0X21pbnVzXzEgCj4+ICsgMTsKPj4gLcKgwqDCoMKgwqDCoMKgIGF2MV9kZWMt PmZyYW1lX3JlZnNbaV0ubWlfY29scyA9IAo+PiBESVZfUk9VTkRfVVAoZnJhbWUtPmZyYW1lX3dp ZHRoX21pbnVzXzEgKyAxLCA4KTsKPj4gLcKgwqDCoMKgwqDCoMKgIGF2MV9kZWMtPmZyYW1lX3Jl ZnNbaV0ubWlfcm93cyA9IAo+PiBESVZfUk9VTkRfVVAoZnJhbWUtPmZyYW1lX2hlaWdodF9taW51 c18xICsgMSwgOCk7Cj4+IC3CoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5mcmFtZV9yZWZzW2ldLnRp bWVzdGFtcCA9IHRpbWVzdGFtcDsKPj4gLcKgwqDCoMKgwqDCoMKgIGF2MV9kZWMtPmZyYW1lX3Jl ZnNbaV0uZnJhbWVfdHlwZSA9IGZyYW1lLT5mcmFtZV90eXBlOwo+PiAtwqDCoMKgwqDCoMKgwqAg YXYxX2RlYy0+ZnJhbWVfcmVmc1tpXS5vcmRlcl9oaW50ID0gZnJhbWUtPm9yZGVyX2hpbnQ7Cj4+ IC3CoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5mcmFtZV9yZWZzW2ldLnZiMl9yZWYgPSBoYW50cm9f Z2V0X2RzdF9idWYoY3R4KTsKPj4gLQo+PiAtwqDCoMKgwqDCoMKgwqAgZm9yIChqID0gMDsgaiA8 IFY0TDJfQVYxX1RPVEFMX1JFRlNfUEVSX0ZSQU1FOyBqKyspCj4+IC3CoMKgwqDCoMKgwqDCoMKg wqDCoMKgIGF2MV9kZWMtPmZyYW1lX3JlZnNbaV0ub3JkZXJfaGludHNbal0gPSAKPj4gZnJhbWUt Pm9yZGVyX2hpbnRzW2pdOwo+PiAtwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+ZnJhbWVfcmVmc1tp XS51c2VkID0gdHJ1ZTsKPj4gLcKgwqDCoMKgwqDCoMKgIGF2MV9kZWMtPmN1cnJlbnRfZnJhbWVf aW5kZXggPSBpOwo+PiAtCj4+IC3CoMKgwqDCoMKgwqDCoCByZXR1cm4gaTsKPj4gLcKgwqDCoCB9 Cj4+IC0KPj4gLcKgwqDCoCByZXR1cm4gQVYxX0lOVkFMSURfSURYOwo+PiAtfQo+PiAtCj4+IC1z dGF0aWMgdm9pZCByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19mcmFtZV91bnJlZihzdHJ1Y3QgaGFu dHJvX2N0eCAKPj4gKmN0eCwgaW50IGlkeCkKPj4gLXsKPj4gLcKgwqDCoCBzdHJ1Y3QgaGFudHJv X2F2MV9kZWNfaHdfY3R4ICphdjFfZGVjID0gJmN0eC0+YXYxX2RlYzsKPj4gLQo+PiAtwqDCoMKg IGlmIChpZHggPj0gMCkKPj4gLcKgwqDCoMKgwqDCoMKgIGF2MV9kZWMtPmZyYW1lX3JlZnNbaWR4 XS51c2VkID0gZmFsc2U7Cj4+IC19Cj4+IC0KPj4gLXN0YXRpYyB2b2lkIHJvY2tjaGlwX3ZwdTk4 MV9hdjFfZGVjX2NsZWFuX3JlZnMoc3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gLXsKPj4gLcKg wqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfaHdfY3R4ICphdjFfZGVjID0gJmN0eC0+YXYxX2Rl YzsKPj4gLcKgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfY3RybHMgKmN0cmxzID0gJmF2MV9k ZWMtPmN0cmxzOwo+PiAtCj4+IC3CoMKgwqAgaW50IHJlZiwgaWR4Owo+PiAtCj4+IC3CoMKgwqAg Zm9yIChpZHggPSAwOyBpZHggPCBBVjFfTUFYX0ZSQU1FX0JVRl9DT1VOVDsgaWR4KyspIHsKPj4g LcKgwqDCoMKgwqDCoMKgIHU2NCB0aW1lc3RhbXAgPSBhdjFfZGVjLT5mcmFtZV9yZWZzW2lkeF0u dGltZXN0YW1wOwo+PiAtwqDCoMKgwqDCoMKgwqAgYm9vbCB1c2VkID0gZmFsc2U7Cj4+IC0KPj4g LcKgwqDCoMKgwqDCoMKgIGlmICghYXYxX2RlYy0+ZnJhbWVfcmVmc1tpZHhdLnVzZWQpCj4+IC3C oMKgwqDCoMKgwqDCoMKgwqDCoMKgIGNvbnRpbnVlOwo+PiAtCj4+IC3CoMKgwqDCoMKgwqDCoCBm b3IgKHJlZiA9IDA7IHJlZiA8IFY0TDJfQVYxX1RPVEFMX1JFRlNfUEVSX0ZSQU1FOyByZWYrKykg ewo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBpZiAoY3RybHMtPmZyYW1lLT5yZWZlcmVuY2Vf ZnJhbWVfdHNbcmVmXSA9PSB0aW1lc3RhbXApCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgdXNlZCA9IHRydWU7Cj4+IC3CoMKgwqDCoMKgwqDCoCB9Cj4+IC0KPj4gLcKgwqDCoMKg wqDCoMKgIGlmICghdXNlZCkKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcm9ja2NoaXBfdnB1 OTgxX2F2MV9kZWNfZnJhbWVfdW5yZWYoY3R4LCBpZHgpOwo+PiAtwqDCoMKgIH0KPj4gLX0KPj4g LQo+PiAtc3RhdGljIHNpemVfdCByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19sdW1hX3NpemUoc3Ry dWN0IGhhbnRyb19jdHggKmN0eCkKPj4gLXsKPj4gLcKgwqDCoCByZXR1cm4gY3R4LT5kc3RfZm10 LndpZHRoICogY3R4LT5kc3RfZm10LmhlaWdodCAqIGN0eC0+Yml0X2RlcHRoIAo+PiAvIDg7Cj4+ IC19Cj4+IC0KPj4gLXN0YXRpYyBzaXplX3Qgcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfY2hyb21h X3NpemUoc3RydWN0IGhhbnRyb19jdHggCj4+ICpjdHgpCj4+IC17Cj4+IC3CoMKgwqAgc2l6ZV90 IGNyX29mZnNldCA9IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX2x1bWFfc2l6ZShjdHgpOwo+PiAt Cj4+IC3CoMKgwqAgcmV0dXJuIEFMSUdOKChjcl9vZmZzZXQgKiAzKSAvIDIsIDY0KTsKPj4gLX0K Pj4gLQo+PiAtc3RhdGljIHZvaWQgcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfdGlsZXNfZnJlZShz dHJ1Y3QgaGFudHJvX2N0eCAqY3R4KQo+PiAtewo+PiAtwqDCoMKgIHN0cnVjdCBoYW50cm9fZGV2 ICp2cHUgPSBjdHgtPmRldjsKPj4gLcKgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfaHdfY3R4 ICphdjFfZGVjID0gJmN0eC0+YXYxX2RlYzsKPj4gLQo+PiAtwqDCoMKgIGlmIChhdjFfZGVjLT5k Yl9kYXRhX2NvbC5jcHUpCj4+IC3CoMKgwqDCoMKgwqDCoCBkbWFfZnJlZV9jb2hlcmVudCh2cHUt PmRldiwgYXYxX2RlYy0+ZGJfZGF0YV9jb2wuc2l6ZSwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+ZGJfZGF0YV9jb2wuY3B1LAo+PiAtwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5kYl9kYXRhX2NvbC5kbWEpOwo+PiAtwqDC oMKgIGF2MV9kZWMtPmRiX2RhdGFfY29sLmNwdSA9IE5VTEw7Cj4+IC0KPj4gLcKgwqDCoCBpZiAo YXYxX2RlYy0+ZGJfY3RybF9jb2wuY3B1KQo+PiAtwqDCoMKgwqDCoMKgwqAgZG1hX2ZyZWVfY29o ZXJlbnQodnB1LT5kZXYsIGF2MV9kZWMtPmRiX2N0cmxfY29sLnNpemUsCj4+IC3CoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGF2MV9kZWMtPmRiX2N0cmxfY29sLmNwdSwKPj4gLcKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+ZGJfY3RybF9jb2wuZG1h KTsKPj4gLcKgwqDCoCBhdjFfZGVjLT5kYl9jdHJsX2NvbC5jcHUgPSBOVUxMOwo+PiAtCj4+IC3C oMKgwqAgaWYgKGF2MV9kZWMtPmNkZWZfY29sLmNwdSkKPj4gLcKgwqDCoMKgwqDCoMKgIGRtYV9m cmVlX2NvaGVyZW50KHZwdS0+ZGV2LCBhdjFfZGVjLT5jZGVmX2NvbC5zaXplLAo+PiAtwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5jZGVmX2NvbC5jcHUsIGF2MV9k ZWMtPmNkZWZfY29sLmRtYSk7Cj4+IC3CoMKgwqAgYXYxX2RlYy0+Y2RlZl9jb2wuY3B1ID0gTlVM TDsKPj4gLQo+PiAtwqDCoMKgIGlmIChhdjFfZGVjLT5zcl9jb2wuY3B1KQo+PiAtwqDCoMKgwqDC oMKgwqAgZG1hX2ZyZWVfY29oZXJlbnQodnB1LT5kZXYsIGF2MV9kZWMtPnNyX2NvbC5zaXplLAo+ PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5zcl9jb2wuY3B1 LCBhdjFfZGVjLT5zcl9jb2wuZG1hKTsKPj4gLcKgwqDCoCBhdjFfZGVjLT5zcl9jb2wuY3B1ID0g TlVMTDsKPj4gLQo+PiAtwqDCoMKgIGlmIChhdjFfZGVjLT5scl9jb2wuY3B1KQo+PiAtwqDCoMKg wqDCoMKgwqAgZG1hX2ZyZWVfY29oZXJlbnQodnB1LT5kZXYsIGF2MV9kZWMtPmxyX2NvbC5zaXpl LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5scl9jb2wu Y3B1LCBhdjFfZGVjLT5scl9jb2wuZG1hKTsKPj4gLcKgwqDCoCBhdjFfZGVjLT5scl9jb2wuY3B1 ID0gTlVMTDsKPj4gLX0KPj4gLQo+PiAtc3RhdGljIGludCByb2NrY2hpcF92cHU5ODFfYXYxX2Rl Y190aWxlc19yZWFsbG9jYXRlKHN0cnVjdCAKPj4gaGFudHJvX2N0eCAqY3R4KQo+PiAtewo+PiAt wqDCoMKgIHN0cnVjdCBoYW50cm9fZGV2ICp2cHUgPSBjdHgtPmRldjsKPj4gLcKgwqDCoCBzdHJ1 Y3QgaGFudHJvX2F2MV9kZWNfaHdfY3R4ICphdjFfZGVjID0gJmN0eC0+YXYxX2RlYzsKPj4gLcKg wqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfY3RybHMgKmN0cmxzID0gJmF2MV9kZWMtPmN0cmxz Owo+PiAtwqDCoMKgIGNvbnN0IHN0cnVjdCB2NGwyX2F2MV90aWxlX2luZm8gKnRpbGVfaW5mbyA9 IAo+PiAmY3RybHMtPmZyYW1lLT50aWxlX2luZm87Cj4+IC3CoMKgwqAgdW5zaWduZWQgaW50IG51 bV90aWxlX2NvbHMgPSB0aWxlX2luZm8tPnRpbGVfY29sczsKPj4gLcKgwqDCoCB1bnNpZ25lZCBp bnQgaGVpZ2h0ID0gQUxJR04oY3RybHMtPmZyYW1lLT5mcmFtZV9oZWlnaHRfbWludXNfMSArIAo+ PiAxLCA2NCk7Cj4+IC3CoMKgwqAgdW5zaWduZWQgaW50IGhlaWdodF9pbl9zYiA9IGhlaWdodCAv IDY0Owo+PiAtwqDCoMKgIHVuc2lnbmVkIGludCBzdHJpcGVfbnVtID0gKChoZWlnaHQgKyA4KSAr IDYzKSAvIDY0Owo+PiAtwqDCoMKgIHNpemVfdCBzaXplOwo+PiAtCj4+IC3CoMKgwqAgaWYgKGF2 MV9kZWMtPmRiX2RhdGFfY29sLnNpemUgPj0KPj4gLcKgwqDCoMKgwqDCoMKgIEFMSUdOKGhlaWdo dCAqIDEyICogY3R4LT5iaXRfZGVwdGggLyA4LCAxMjgpICogbnVtX3RpbGVfY29scykKPj4gLcKg wqDCoMKgwqDCoMKgIHJldHVybiAwOwo+PiAtCj4+IC3CoMKgwqAgcm9ja2NoaXBfdnB1OTgxX2F2 MV9kZWNfdGlsZXNfZnJlZShjdHgpOwo+PiAtCj4+IC3CoMKgwqAgc2l6ZSA9IEFMSUdOKGhlaWdo dCAqIDEyICogY3R4LT5iaXRfZGVwdGggLyA4LCAxMjgpICogCj4+IG51bV90aWxlX2NvbHM7Cj4+ IC3CoMKgwqAgYXYxX2RlYy0+ZGJfZGF0YV9jb2wuY3B1ID0gZG1hX2FsbG9jX2NvaGVyZW50KHZw dS0+ZGV2LCBzaXplLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCAmYXYxX2RlYy0+ZGJfZGF0YV9jb2wuZG1hLAo+PiAtwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBHRlBf S0VSTkVMKTsKPj4gLcKgwqDCoCBpZiAoIWF2MV9kZWMtPmRiX2RhdGFfY29sLmNwdSkKPj4gLcKg wqDCoMKgwqDCoMKgIGdvdG8gYnVmZmVyX2FsbG9jYXRpb25fZXJyb3I7Cj4+IC3CoMKgwqAgYXYx X2RlYy0+ZGJfZGF0YV9jb2wuc2l6ZSA9IHNpemU7Cj4+IC0KPj4gLcKgwqDCoCBzaXplID0gQUxJ R04oaGVpZ2h0ICogMiAqIDE2IC8gNCwgMTI4KSAqIG51bV90aWxlX2NvbHM7Cj4+IC3CoMKgwqAg YXYxX2RlYy0+ZGJfY3RybF9jb2wuY3B1ID0gZG1hX2FsbG9jX2NvaGVyZW50KHZwdS0+ZGV2LCBz aXplLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCAmYXYxX2RlYy0+ZGJfY3RybF9jb2wuZG1hLAo+PiAtwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBHRlBfS0VSTkVMKTsK Pj4gLcKgwqDCoCBpZiAoIWF2MV9kZWMtPmRiX2N0cmxfY29sLmNwdSkKPj4gLcKgwqDCoMKgwqDC oMKgIGdvdG8gYnVmZmVyX2FsbG9jYXRpb25fZXJyb3I7Cj4+IC3CoMKgwqAgYXYxX2RlYy0+ZGJf Y3RybF9jb2wuc2l6ZSA9IHNpemU7Cj4+IC0KPj4gLcKgwqDCoCBzaXplID0gQUxJR04oaGVpZ2h0 X2luX3NiICogNDQgKiBjdHgtPmJpdF9kZXB0aCAqIDE2IC8gOCwgMTI4KSAqIAo+PiBudW1fdGls ZV9jb2xzOwo+PiAtwqDCoMKgIGF2MV9kZWMtPmNkZWZfY29sLmNwdSA9IGRtYV9hbGxvY19jb2hl cmVudCh2cHUtPmRldiwgc2l6ZSwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgJmF2MV9kZWMtPmNkZWZfY29sLmRtYSwKPj4gLcKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgR0ZQX0tFUk5FTCk7 Cj4+IC3CoMKgwqAgaWYgKCFhdjFfZGVjLT5jZGVmX2NvbC5jcHUpCj4+IC3CoMKgwqDCoMKgwqDC oCBnb3RvIGJ1ZmZlcl9hbGxvY2F0aW9uX2Vycm9yOwo+PiAtwqDCoMKgIGF2MV9kZWMtPmNkZWZf Y29sLnNpemUgPSBzaXplOwo+PiAtCj4+IC3CoMKgwqAgc2l6ZSA9IEFMSUdOKGhlaWdodF9pbl9z YiAqICgzMDQwICsgMTI4MCksIDEyOCkgKiBudW1fdGlsZV9jb2xzOwo+PiAtwqDCoMKgIGF2MV9k ZWMtPnNyX2NvbC5jcHUgPSBkbWFfYWxsb2NfY29oZXJlbnQodnB1LT5kZXYsIHNpemUsCj4+IC3C oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgJmF2MV9kZWMt PnNyX2NvbC5kbWEsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgR0ZQX0tFUk5FTCk7Cj4+IC3CoMKgwqAgaWYgKCFhdjFfZGVjLT5zcl9jb2wuY3B1 KQo+PiAtwqDCoMKgwqDCoMKgwqAgZ290byBidWZmZXJfYWxsb2NhdGlvbl9lcnJvcjsKPj4gLcKg wqDCoCBhdjFfZGVjLT5zcl9jb2wuc2l6ZSA9IHNpemU7Cj4+IC0KPj4gLcKgwqDCoCBzaXplID0g QUxJR04oc3RyaXBlX251bSAqIDE1MzYgKiBjdHgtPmJpdF9kZXB0aCAvIDgsIDEyOCkgKiAKPj4g bnVtX3RpbGVfY29sczsKPj4gLcKgwqDCoCBhdjFfZGVjLT5scl9jb2wuY3B1ID0gZG1hX2FsbG9j X2NvaGVyZW50KHZwdS0+ZGV2LCBzaXplLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgICZhdjFfZGVjLT5scl9jb2wuZG1hLAo+PiAtwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEdGUF9LRVJORUwpOwo+PiAt wqDCoMKgIGlmICghYXYxX2RlYy0+bHJfY29sLmNwdSkKPj4gLcKgwqDCoMKgwqDCoMKgIGdvdG8g YnVmZmVyX2FsbG9jYXRpb25fZXJyb3I7Cj4+IC3CoMKgwqAgYXYxX2RlYy0+bHJfY29sLnNpemUg PSBzaXplOwo+PiAtCj4+IC3CoMKgwqAgYXYxX2RlYy0+bnVtX3RpbGVfY29sc19hbGxvY2F0ZWQg PSBudW1fdGlsZV9jb2xzOwo+PiAtwqDCoMKgIHJldHVybiAwOwo+PiAtCj4+IC1idWZmZXJfYWxs b2NhdGlvbl9lcnJvcjoKPj4gLcKgwqDCoCByb2NrY2hpcF92cHU5ODFfYXYxX2RlY190aWxlc19m cmVlKGN0eCk7Cj4+IC3CoMKgwqAgcmV0dXJuIC1FTk9NRU07Cj4+IC19Cj4+IC0KPj4gLXZvaWQg cm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZXhpdChzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4KQo+PiAt ewo+PiAtwqDCoMKgIHN0cnVjdCBoYW50cm9fZGV2ICp2cHUgPSBjdHgtPmRldjsKPj4gLcKgwqDC oCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfaHdfY3R4ICphdjFfZGVjID0gJmN0eC0+YXYxX2RlYzsK Pj4gLQo+PiAtwqDCoMKgIGlmIChhdjFfZGVjLT5nbG9iYWxfbW9kZWwuY3B1KQo+PiAtwqDCoMKg wqDCoMKgwqAgZG1hX2ZyZWVfY29oZXJlbnQodnB1LT5kZXYsIGF2MV9kZWMtPmdsb2JhbF9tb2Rl bC5zaXplLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5n bG9iYWxfbW9kZWwuY3B1LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBh djFfZGVjLT5nbG9iYWxfbW9kZWwuZG1hKTsKPj4gLcKgwqDCoCBhdjFfZGVjLT5nbG9iYWxfbW9k ZWwuY3B1ID0gTlVMTDsKPj4gLQo+PiAtwqDCoMKgIGlmIChhdjFfZGVjLT50aWxlX2luZm8uY3B1 KQo+PiAtwqDCoMKgwqDCoMKgwqAgZG1hX2ZyZWVfY29oZXJlbnQodnB1LT5kZXYsIGF2MV9kZWMt PnRpbGVfaW5mby5zaXplLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBh djFfZGVjLT50aWxlX2luZm8uY3B1LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCBhdjFfZGVjLT50aWxlX2luZm8uZG1hKTsKPj4gLcKgwqDCoCBhdjFfZGVjLT50aWxlX2lu Zm8uY3B1ID0gTlVMTDsKPj4gLQo+PiAtwqDCoMKgIGlmIChhdjFfZGVjLT5maWxtX2dyYWluLmNw dSkKPj4gLcKgwqDCoMKgwqDCoMKgIGRtYV9mcmVlX2NvaGVyZW50KHZwdS0+ZGV2LCBhdjFfZGVj LT5maWxtX2dyYWluLnNpemUsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IGF2MV9kZWMtPmZpbG1fZ3JhaW4uY3B1LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBhdjFfZGVjLT5maWxtX2dyYWluLmRtYSk7Cj4+IC3CoMKgwqAgYXYxX2RlYy0+Zmls bV9ncmFpbi5jcHUgPSBOVUxMOwo+PiAtCj4+IC3CoMKgwqAgaWYgKGF2MV9kZWMtPnByb2JfdGJs LmNwdSkKPj4gLcKgwqDCoMKgwqDCoMKgIGRtYV9mcmVlX2NvaGVyZW50KHZwdS0+ZGV2LCBhdjFf ZGVjLT5wcm9iX3RibC5zaXplLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBhdjFfZGVjLT5wcm9iX3RibC5jcHUsIGF2MV9kZWMtPnByb2JfdGJsLmRtYSk7Cj4+IC3CoMKg wqAgYXYxX2RlYy0+cHJvYl90YmwuY3B1ID0gTlVMTDsKPj4gLQo+PiAtwqDCoMKgIGlmIChhdjFf ZGVjLT5wcm9iX3RibF9vdXQuY3B1KQo+PiAtwqDCoMKgwqDCoMKgwqAgZG1hX2ZyZWVfY29oZXJl bnQodnB1LT5kZXYsIGF2MV9kZWMtPnByb2JfdGJsX291dC5zaXplLAo+PiAtwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5wcm9iX3RibF9vdXQuY3B1LAo+PiAtwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5wcm9iX3RibF9vdXQuZG1h KTsKPj4gLcKgwqDCoCBhdjFfZGVjLT5wcm9iX3RibF9vdXQuY3B1ID0gTlVMTDsKPj4gLQo+PiAt wqDCoMKgIGlmIChhdjFfZGVjLT50aWxlX2J1Zi5jcHUpCj4+IC3CoMKgwqDCoMKgwqDCoCBkbWFf ZnJlZV9jb2hlcmVudCh2cHUtPmRldiwgYXYxX2RlYy0+dGlsZV9idWYuc2l6ZSwKPj4gLcKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+dGlsZV9idWYuY3B1LCBhdjFf ZGVjLT50aWxlX2J1Zi5kbWEpOwo+PiAtwqDCoMKgIGF2MV9kZWMtPnRpbGVfYnVmLmNwdSA9IE5V TEw7Cj4+IC0KPj4gLcKgwqDCoCByb2NrY2hpcF92cHU5ODFfYXYxX2RlY190aWxlc19mcmVlKGN0 eCk7Cj4+IC19Cj4+IC0KPj4gLWludCByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19pbml0KHN0cnVj dCBoYW50cm9fY3R4ICpjdHgpCj4+IC17Cj4+IC3CoMKgwqAgc3RydWN0IGhhbnRyb19kZXYgKnZw dSA9IGN0eC0+ZGV2Owo+PiAtwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19od19jdHggKmF2 MV9kZWMgPSAmY3R4LT5hdjFfZGVjOwo+PiAtCj4+IC3CoMKgwqAgbWVtc2V0KGF2MV9kZWMsIDAs IHNpemVvZigqYXYxX2RlYykpOwo+PiAtCj4+IC3CoMKgwqAgYXYxX2RlYy0+Z2xvYmFsX21vZGVs LmNwdSA9IGRtYV9hbGxvY19jb2hlcmVudCh2cHUtPmRldiwgCj4+IEdMT0JBTF9NT0RFTF9TSVpF LAo+PiAtICZhdjFfZGVjLT5nbG9iYWxfbW9kZWwuZG1hLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEdGUF9LRVJORUwpOwo+ PiAtwqDCoMKgIGlmICghYXYxX2RlYy0+Z2xvYmFsX21vZGVsLmNwdSkKPj4gLcKgwqDCoMKgwqDC oMKgIHJldHVybiAtRU5PTUVNOwo+PiAtwqDCoMKgIGF2MV9kZWMtPmdsb2JhbF9tb2RlbC5zaXpl ID0gR0xPQkFMX01PREVMX1NJWkU7Cj4+IC0KPj4gLcKgwqDCoCBhdjFfZGVjLT50aWxlX2luZm8u Y3B1ID0gZG1hX2FsbG9jX2NvaGVyZW50KHZwdS0+ZGV2LCAKPj4gQVYxX1RJTEVfSU5GT19TSVpF LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgICZhdjFfZGVjLT50aWxlX2luZm8uZG1hLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEdGUF9LRVJORUwpOwo+PiAtwqDCoMKgIGlm ICghYXYxX2RlYy0+dGlsZV9pbmZvLmNwdSkKPj4gLcKgwqDCoMKgwqDCoMKgIHJldHVybiAtRU5P TUVNOwo+PiAtwqDCoMKgIGF2MV9kZWMtPnRpbGVfaW5mby5zaXplID0gQVYxX1RJTEVfSU5GT19T SVpFOwo+PiAtCj4+IC3CoMKgwqAgYXYxX2RlYy0+ZmlsbV9ncmFpbi5jcHUgPSBkbWFfYWxsb2Nf Y29oZXJlbnQodnB1LT5kZXYsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBBTElHTihzaXplb2Yoc3RydWN0IAo+PiByb2NrY2hpcF9h djFfZmlsbV9ncmFpbiksIDIwNDgpLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgJmF2MV9kZWMtPmZpbG1fZ3JhaW4uZG1hLAo+PiAt wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg R0ZQX0tFUk5FTCk7Cj4+IC3CoMKgwqAgaWYgKCFhdjFfZGVjLT5maWxtX2dyYWluLmNwdSkKPj4g LcKgwqDCoMKgwqDCoMKgIHJldHVybiAtRU5PTUVNOwo+PiAtwqDCoMKgIGF2MV9kZWMtPmZpbG1f Z3JhaW4uc2l6ZSA9IEFMSUdOKHNpemVvZihzdHJ1Y3QgCj4+IHJvY2tjaGlwX2F2MV9maWxtX2dy YWluKSwgMjA0OCk7Cj4+IC0KPj4gLcKgwqDCoCBhdjFfZGVjLT5wcm9iX3RibC5jcHUgPSBkbWFf YWxsb2NfY29oZXJlbnQodnB1LT5kZXYsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEFMSUdOKHNpemVvZihzdHJ1Y3QgYXYxY2RmcyksIDIw NDgpLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCAmYXYxX2RlYy0+cHJvYl90YmwuZG1hLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBHRlBfS0VSTkVMKTsKPj4gLcKgwqDCoCBpZiAo IWF2MV9kZWMtPnByb2JfdGJsLmNwdSkKPj4gLcKgwqDCoMKgwqDCoMKgIHJldHVybiAtRU5PTUVN Owo+PiAtwqDCoMKgIGF2MV9kZWMtPnByb2JfdGJsLnNpemUgPSBBTElHTihzaXplb2Yoc3RydWN0 IGF2MWNkZnMpLCAyMDQ4KTsKPj4gLQo+PiAtwqDCoMKgIGF2MV9kZWMtPnByb2JfdGJsX291dC5j cHUgPSBkbWFfYWxsb2NfY29oZXJlbnQodnB1LT5kZXYsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgQUxJR04oc2l6ZW9mKHN0 cnVjdCBhdjFjZGZzKSwgMjA0OCksCj4+IC0gJmF2MV9kZWMtPnByb2JfdGJsX291dC5kbWEsCj4+ IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgR0ZQX0tFUk5FTCk7Cj4+IC3CoMKgwqAgaWYgKCFhdjFfZGVjLT5wcm9iX3RibF9vdXQu Y3B1KQo+PiAtwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FTk9NRU07Cj4+IC3CoMKgwqAgYXYxX2Rl Yy0+cHJvYl90Ymxfb3V0LnNpemUgPSBBTElHTihzaXplb2Yoc3RydWN0IGF2MWNkZnMpLCAyMDQ4 KTsKPj4gLcKgwqDCoCBhdjFfZGVjLT5jZGZzID0gJmF2MV9kZWMtPmRlZmF1bHRfY2RmczsKPj4g LcKgwqDCoCBhdjFfZGVjLT5jZGZzX25kdmMgPSAmYXYxX2RlYy0+ZGVmYXVsdF9jZGZzX25kdmM7 Cj4+IC0KPj4gLcKgwqDCoCByb2NrY2hpcF9hdjFfc2V0X2RlZmF1bHRfY2RmcyhhdjFfZGVjLT5j ZGZzLCBhdjFfZGVjLT5jZGZzX25kdmMpOwo+PiAtCj4+IC3CoMKgwqAgYXYxX2RlYy0+dGlsZV9i dWYuY3B1ID0gZG1hX2FsbG9jX2NvaGVyZW50KHZwdS0+ZGV2LAo+PiAtwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBBVjFfVElMRV9TSVpFLAo+PiAt wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAmYXYx X2RlYy0+dGlsZV9idWYuZG1hLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBHRlBfS0VSTkVMKTsKPj4gLcKgwqDCoCBpZiAoIWF2MV9kZWMt PnRpbGVfYnVmLmNwdSkKPj4gLcKgwqDCoMKgwqDCoMKgIHJldHVybiAtRU5PTUVNOwo+PiAtwqDC oMKgIGF2MV9kZWMtPnRpbGVfYnVmLnNpemUgPSBBVjFfVElMRV9TSVpFOwo+PiAtCj4+IC3CoMKg wqAgcmV0dXJuIDA7Cj4+IC19Cj4+IC0KPj4gLXN0YXRpYyBpbnQgcm9ja2NoaXBfdnB1OTgxX2F2 MV9kZWNfcHJlcGFyZV9ydW4oc3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gLXsKPj4gLcKgwqDC oCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfaHdfY3R4ICphdjFfZGVjID0gJmN0eC0+YXYxX2RlYzsK Pj4gLcKgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfY3RybHMgKmN0cmxzID0gJmF2MV9kZWMt PmN0cmxzOwo+PiAtCj4+IC3CoMKgwqAgY3RybHMtPnNlcXVlbmNlID0gaGFudHJvX2dldF9jdHJs KGN0eCwgCj4+IFY0TDJfQ0lEX1NUQVRFTEVTU19BVjFfU0VRVUVOQ0UpOwo+PiAtwqDCoMKgIGlm IChXQVJOX09OKCFjdHJscy0+c2VxdWVuY2UpKQo+PiAtwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1F SU5WQUw7Cj4+IC0KPj4gLcKgwqDCoCBjdHJscy0+dGlsZV9ncm91cF9lbnRyeSA9Cj4+IC3CoMKg wqDCoMKgwqDCoCBoYW50cm9fZ2V0X2N0cmwoY3R4LCBWNEwyX0NJRF9TVEFURUxFU1NfQVYxX1RJ TEVfR1JPVVBfRU5UUlkpOwo+PiAtwqDCoMKgIGlmIChXQVJOX09OKCFjdHJscy0+dGlsZV9ncm91 cF9lbnRyeSkpCj4+IC3CoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVJTlZBTDsKPj4gLQo+PiAtwqDC oMKgIGN0cmxzLT5mcmFtZSA9IGhhbnRyb19nZXRfY3RybChjdHgsIFY0TDJfQ0lEX1NUQVRFTEVT U19BVjFfRlJBTUUpOwo+PiAtwqDCoMKgIGlmIChXQVJOX09OKCFjdHJscy0+ZnJhbWUpKQo+PiAt wqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FSU5WQUw7Cj4+IC0KPj4gLcKgwqDCoCBjdHJscy0+Zmls bV9ncmFpbiA9Cj4+IC3CoMKgwqDCoMKgwqDCoCBoYW50cm9fZ2V0X2N0cmwoY3R4LCBWNEwyX0NJ RF9TVEFURUxFU1NfQVYxX0ZJTE1fR1JBSU4pOwo+PiAtCj4+IC3CoMKgwqAgcmV0dXJuIHJvY2tj aGlwX3ZwdTk4MV9hdjFfZGVjX3RpbGVzX3JlYWxsb2NhdGUoY3R4KTsKPj4gLX0KPj4gLQo+PiAt c3RhdGljIGlubGluZSBpbnQgcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X21zYih1MzIgbikK Pj4gLXsKPj4gLcKgwqDCoCBpZiAobiA9PSAwKQo+PiAtwqDCoMKgwqDCoMKgwqAgcmV0dXJuIDA7 Cj4+IC3CoMKgwqAgcmV0dXJuIDMxIF4gX19idWlsdGluX2NseihuKTsKPj4gLX0KPj4gLQo+PiAt c3RhdGljIHNob3J0IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX3Jlc29sdmVfZGl2aXNvcl8zMih1 MzIgZCwgc2hvcnQgCj4+ICpzaGlmdCkKPj4gLXsKPj4gLcKgwqDCoCBpbnQgZjsKPj4gLcKgwqDC oCB1NjQgZTsKPj4gLQo+PiAtwqDCoMKgICpzaGlmdCA9IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVj X2dldF9tc2IoZCk7Cj4+IC3CoMKgwqAgLyogZSBpcyBvYnRhaW5lZCBmcm9tIEQgYWZ0ZXIgcmVz ZXR0aW5nIHRoZSBtb3N0IHNpZ25pZmljYW50IDEgCj4+IGJpdC4gKi8KPj4gLcKgwqDCoCBlID0g ZCAtICgodTMyKTEgPDwgKnNoaWZ0KTsKPj4gLcKgwqDCoCAvKiBHZXQgdGhlIG1vc3Qgc2lnbmlm aWNhbnQgRElWX0xVVF9CSVRTICg4KSBiaXRzIG9mIGUgaW50byBmICovCj4+IC3CoMKgwqAgaWYg KCpzaGlmdCA+IERJVl9MVVRfQklUUykKPj4gLcKgwqDCoMKgwqDCoMKgIGYgPSBBVjFfRElWX1JP VU5EX1VQX1BPVzIoZSwgKnNoaWZ0IC0gRElWX0xVVF9CSVRTKTsKPj4gLcKgwqDCoCBlbHNlCj4+ IC3CoMKgwqDCoMKgwqDCoCBmID0gZSA8PCAoRElWX0xVVF9CSVRTIC0gKnNoaWZ0KTsKPj4gLcKg wqDCoCBpZiAoZiA+IERJVl9MVVRfTlVNKQo+PiAtwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC0xOwo+ PiAtwqDCoMKgICpzaGlmdCArPSBESVZfTFVUX1BSRUNfQklUUzsKPj4gLcKgwqDCoCAvKiBVc2Ug ZiBhcyBsb29rdXAgaW50byB0aGUgcHJlY29tcHV0ZWQgdGFibGUgb2YgbXVsdGlwbGllcnMgKi8K Pj4gLcKgwqDCoCByZXR1cm4gZGl2X2x1dFtmXTsKPj4gLX0KPj4gLQo+PiAtc3RhdGljIHZvaWQK Pj4gLXJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX2dldF9zaGVhcl9wYXJhbXMoY29uc3QgdTMyICpw YXJhbXMsIHM2NCAqYWxwaGEsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIHM2NCAqYmV0YSwgczY0ICpnYW1tYSwgczY0ICpkZWx0YSkKPj4gLXsKPj4gLcKgwqDC oCBjb25zdCBpbnQgKm1hdCA9IHBhcmFtczsKPj4gLcKgwqDCoCBzaG9ydCBzaGlmdDsKPj4gLcKg wqDCoCBzaG9ydCB5Owo+PiAtwqDCoMKgIGxvbmcgbG9uZyBndiwgZHY7Cj4+IC0KPj4gLcKgwqDC oCBpZiAobWF0WzJdIDw9IDApCj4+IC3CoMKgwqDCoMKgwqDCoCByZXR1cm47Cj4+IC0KPj4gLcKg wqDCoCAqYWxwaGEgPSBjbGFtcF92YWwobWF0WzJdIC0gKDEgPDwgV0FSUEVETU9ERUxfUFJFQ19C SVRTKSwgCj4+IFMxNl9NSU4sIFMxNl9NQVgpOwo+PiAtwqDCoMKgICpiZXRhID0gY2xhbXBfdmFs KG1hdFszXSwgUzE2X01JTiwgUzE2X01BWCk7Cj4+IC0KPj4gLcKgwqDCoCB5ID0gcm9ja2NoaXBf dnB1OTgxX2F2MV9kZWNfcmVzb2x2ZV9kaXZpc29yXzMyKGFicyhtYXRbMl0pLCAKPj4gJnNoaWZ0 KSAqIChtYXRbMl0gPCAwID8gLTEgOiAxKTsKPj4gLQo+PiAtwqDCoMKgIGd2ID0gKChsb25nIGxv bmcpbWF0WzRdICogKDEgPDwgV0FSUEVETU9ERUxfUFJFQ19CSVRTKSkgKiB5Owo+PiAtCj4+IC3C oMKgwqAgKmdhbW1hID0gY2xhbXBfdmFsKChpbnQpQVYxX0RJVl9ST1VORF9VUF9QT1cyX1NJR05F RChndiwgc2hpZnQpLCAKPj4gUzE2X01JTiwgUzE2X01BWCk7Cj4+IC0KPj4gLcKgwqDCoCBkdiA9 ICgobG9uZyBsb25nKW1hdFszXSAqIG1hdFs0XSkgKiB5Owo+PiAtwqDCoMKgICpkZWx0YSA9IGNs YW1wX3ZhbChtYXRbNV0gLQo+PiAtwqDCoMKgwqDCoMKgwqAgKGludClBVjFfRElWX1JPVU5EX1VQ X1BPVzJfU0lHTkVEKGR2LCBzaGlmdCkgLSAoMSA8PCAKPj4gV0FSUEVETU9ERUxfUFJFQ19CSVRT KSwKPj4gLcKgwqDCoMKgwqDCoMKgIFMxNl9NSU4sIFMxNl9NQVgpOwo+PiAtCj4+IC3CoMKgwqAg KmFscGhhID0gQVYxX0RJVl9ST1VORF9VUF9QT1cyX1NJR05FRCgqYWxwaGEsIAo+PiBXQVJQX1BB UkFNX1JFRFVDRV9CSVRTKQo+PiAtwqDCoMKgwqDCoMKgwqDCoCAqICgxIDw8IFdBUlBfUEFSQU1f UkVEVUNFX0JJVFMpOwo+PiAtwqDCoMKgICpiZXRhID0gQVYxX0RJVl9ST1VORF9VUF9QT1cyX1NJ R05FRCgqYmV0YSwgV0FSUF9QQVJBTV9SRURVQ0VfQklUUykKPj4gLcKgwqDCoMKgwqDCoMKgICog KDEgPDwgV0FSUF9QQVJBTV9SRURVQ0VfQklUUyk7Cj4+IC3CoMKgwqAgKmdhbW1hID0gQVYxX0RJ Vl9ST1VORF9VUF9QT1cyX1NJR05FRCgqZ2FtbWEsIAo+PiBXQVJQX1BBUkFNX1JFRFVDRV9CSVRT KQo+PiAtwqDCoMKgwqDCoMKgwqDCoCAqICgxIDw8IFdBUlBfUEFSQU1fUkVEVUNFX0JJVFMpOwo+ PiAtwqDCoMKgICpkZWx0YSA9IEFWMV9ESVZfUk9VTkRfVVBfUE9XMl9TSUdORUQoKmRlbHRhLCAK Pj4gV0FSUF9QQVJBTV9SRURVQ0VfQklUUykKPj4gLcKgwqDCoMKgwqDCoMKgICogKDEgPDwgV0FS UF9QQVJBTV9SRURVQ0VfQklUUyk7Cj4+IC19Cj4+IMKgIMKgIHN0YXRpYyB2b2lkIHJvY2tjaGlw X3ZwdTk4MV9hdjFfZGVjX3NldF9nbG9iYWxfbW9kZWwoc3RydWN0IAo+PiBoYW50cm9fY3R4ICpj dHgpCj4+IMKgIHsKPj4gwqDCoMKgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfaHdfY3R4ICph djFfZGVjID0gJmN0eC0+YXYxX2RlYzsKPj4gLcKgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNf Y3RybHMgKmN0cmxzID0gJmF2MV9kZWMtPmN0cmxzOwo+PiAtwqDCoMKgIGNvbnN0IHN0cnVjdCB2 NGwyX2N0cmxfYXYxX2ZyYW1lICpmcmFtZSA9IGN0cmxzLT5mcmFtZTsKPj4gLcKgwqDCoCBjb25z dCBzdHJ1Y3QgdjRsMl9hdjFfZ2xvYmFsX21vdGlvbiAqZ20gPSAmZnJhbWUtPmdsb2JhbF9tb3Rp b247Cj4+IC3CoMKgwqAgdTggKmRzdCA9IGF2MV9kZWMtPmdsb2JhbF9tb2RlbC5jcHU7Cj4+IMKg wqDCoMKgwqAgc3RydWN0IGhhbnRyb19kZXYgKnZwdSA9IGN0eC0+ZGV2Owo+PiAtwqDCoMKgIGlu dCByZWZfZnJhbWUsIGk7Cj4+IC0KPj4gLcKgwqDCoCBtZW1zZXQoZHN0LCAwLCBHTE9CQUxfTU9E RUxfU0laRSk7Cj4+IC3CoMKgwqAgZm9yIChyZWZfZnJhbWUgPSAwOyByZWZfZnJhbWUgPCBWNEwy X0FWMV9SRUZTX1BFUl9GUkFNRTsgCj4+ICsrcmVmX2ZyYW1lKSB7Cj4+IC3CoMKgwqDCoMKgwqDC oCBzNjQgYWxwaGEgPSAwLCBiZXRhID0gMCwgZ2FtbWEgPSAwLCBkZWx0YSA9IDA7Cj4+IC0KPj4g LcKgwqDCoMKgwqDCoMKgIGZvciAoaSA9IDA7IGkgPCA2OyArK2kpIHsKPj4gLcKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgaWYgKGkgPT0gMikKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCAqKHMzMiAqKWRzdCA9Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBnbS0+cGFyYW1zW1Y0TDJfQVYxX1JFRl9MQVNUX0ZSQU1FICsgcmVmX2ZyYW1lXVszXTsKPj4g LcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZWxzZSBpZiAoaSA9PSAzKQo+PiAtwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgICooczMyICopZHN0ID0KPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIGdtLT5wYXJhbXNbVjRMMl9BVjFfUkVGX0xBU1RfRlJBTUUgKyBy ZWZfZnJhbWVdWzJdOwo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBlbHNlCj4+IC3CoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKihzMzIgKilkc3QgPQo+PiAtwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZ20tPnBhcmFtc1tWNEwyX0FWMV9SRUZfTEFTVF9GUkFN RSArIHJlZl9mcmFtZV1baV07Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGRzdCArPSA0Owo+ PiAtwqDCoMKgwqDCoMKgwqAgfQo+PiAtCj4+IC3CoMKgwqDCoMKgwqDCoCBpZiAoZ20tPnR5cGVb VjRMMl9BVjFfUkVGX0xBU1RfRlJBTUUgKyByZWZfZnJhbWVdIDw9IAo+PiBWNEwyX0FWMV9XQVJQ X01PREVMX0FGRklORSkKPj4gLSAKPj4gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X3NoZWFy X3BhcmFtcygmZ20tPnBhcmFtc1tWNEwyX0FWMV9SRUZfTEFTVF9GUkFNRSAKPj4gKyByZWZfZnJh bWVdWzBdLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCAmYWxwaGEsICZiZXRhLCAmZ2FtbWEsICZkZWx0YSk7Cj4+IC0K Pj4gLcKgwqDCoMKgwqDCoMKgICooczE2ICopZHN0ID0gYWxwaGE7Cj4+IC3CoMKgwqDCoMKgwqDC oCBkc3QgKz0gMjsKPj4gLcKgwqDCoMKgwqDCoMKgICooczE2ICopZHN0ID0gYmV0YTsKPj4gLcKg wqDCoMKgwqDCoMKgIGRzdCArPSAyOwo+PiAtwqDCoMKgwqDCoMKgwqAgKihzMTYgKilkc3QgPSBn YW1tYTsKPj4gLcKgwqDCoMKgwqDCoMKgIGRzdCArPSAyOwo+PiAtwqDCoMKgwqDCoMKgwqAgKihz MTYgKilkc3QgPSBkZWx0YTsKPj4gLcKgwqDCoMKgwqDCoMKgIGRzdCArPSAyOwo+PiAtwqDCoMKg IH0KPj4gwqAgK8KgwqDCoCBoYW50cm9fYXYxX3NldF9nbG9iYWxfbW9kZWwoY3R4KTsKPj4gwqDC oMKgwqDCoCBoYW50cm9fd3JpdGVfYWRkcih2cHUsIEFWMV9HTE9CQUxfTU9ERUwsIAo+PiBhdjFf ZGVjLT5nbG9iYWxfbW9kZWwuZG1hKTsKPj4gwqAgfQo+PiDCoCAtc3RhdGljIGludCByb2NrY2hp cF92cHU5ODFfYXYxX3RpbGVfbG9nMihpbnQgdGFyZ2V0KQo+PiAtewo+PiAtwqDCoMKgIGludCBr Owo+PiAtCj4+IC3CoMKgwqAgLyoKPj4gLcKgwqDCoMKgICogcmV0dXJucyB0aGUgc21hbGxlc3Qg dmFsdWUgZm9yIGsgc3VjaCB0aGF0IDEgPDwgayBpcyBncmVhdGVyCj4+IC3CoMKgwqDCoCAqIHRo YW4gb3IgZXF1YWwgdG8gdGFyZ2V0Cj4+IC3CoMKgwqDCoCAqLwo+PiAtwqDCoMKgIGZvciAoayA9 IDA7ICgxIDw8IGspIDwgdGFyZ2V0OyBrKyspOwo+PiAtCj4+IC3CoMKgwqAgcmV0dXJuIGs7Cj4+ IC19Cj4+IC0KPj4gwqAgc3RhdGljIHZvaWQgcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfc2V0X3Rp bGVfaW5mbyhzdHJ1Y3QgaGFudHJvX2N0eCAKPj4gKmN0eCkKPj4gwqAgewo+PiDCoMKgwqDCoMKg IHN0cnVjdCBoYW50cm9fYXYxX2RlY19od19jdHggKmF2MV9kZWMgPSAmY3R4LT5hdjFfZGVjOwo+ PiDCoMKgwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19jdHJscyAqY3RybHMgPSAmYXYxX2Rl Yy0+Y3RybHM7Cj4+IMKgwqDCoMKgwqAgY29uc3Qgc3RydWN0IHY0bDJfYXYxX3RpbGVfaW5mbyAq dGlsZV9pbmZvID0gCj4+ICZjdHJscy0+ZnJhbWUtPnRpbGVfaW5mbzsKPj4gLcKgwqDCoCBjb25z dCBzdHJ1Y3QgdjRsMl9jdHJsX2F2MV90aWxlX2dyb3VwX2VudHJ5ICpncm91cF9lbnRyeSA9Cj4+ IC3CoMKgwqDCoMKgwqDCoCBjdHJscy0+dGlsZV9ncm91cF9lbnRyeTsKPj4gwqDCoMKgwqDCoCBp bnQgY29udGV4dF91cGRhdGVfeSA9Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCB0aWxlX2luZm8tPmNv bnRleHRfdXBkYXRlX3RpbGVfaWQgLyB0aWxlX2luZm8tPnRpbGVfY29sczsKPj4gwqDCoMKgwqDC oCBpbnQgY29udGV4dF91cGRhdGVfeCA9Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCB0aWxlX2luZm8t PmNvbnRleHRfdXBkYXRlX3RpbGVfaWQgJSB0aWxlX2luZm8tPnRpbGVfY29sczsKPj4gwqDCoMKg wqDCoCBpbnQgY29udGV4dF91cGRhdGVfdGlsZV9pZCA9Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBj b250ZXh0X3VwZGF0ZV94ICogdGlsZV9pbmZvLT50aWxlX3Jvd3MgKyBjb250ZXh0X3VwZGF0ZV95 Owo+PiAtwqDCoMKgIHU4ICpkc3QgPSBhdjFfZGVjLT50aWxlX2luZm8uY3B1Owo+PiDCoMKgwqDC oMKgIHN0cnVjdCBoYW50cm9fZGV2ICp2cHUgPSBjdHgtPmRldjsKPj4gLcKgwqDCoCBpbnQgdGls ZTAsIHRpbGUxOwo+PiAtCj4+IC3CoMKgwqAgbWVtc2V0KGRzdCwgMCwgYXYxX2RlYy0+dGlsZV9p bmZvLnNpemUpOwo+PiAtCj4+IC3CoMKgwqAgZm9yICh0aWxlMCA9IDA7IHRpbGUwIDwgdGlsZV9p bmZvLT50aWxlX2NvbHM7IHRpbGUwKyspIHsKPj4gLcKgwqDCoMKgwqDCoMKgIGZvciAodGlsZTEg PSAwOyB0aWxlMSA8IHRpbGVfaW5mby0+dGlsZV9yb3dzOyB0aWxlMSsrKSB7Cj4+IC3CoMKgwqDC oMKgwqDCoMKgwqDCoMKgIGludCB0aWxlX2lkID0gdGlsZTEgKiB0aWxlX2luZm8tPnRpbGVfY29s cyArIHRpbGUwOwo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB1MzIgc3RhcnQsIGVuZDsKPj4g LcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdTMyIHkwID0KPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCB0aWxlX2luZm8tPmhlaWdodF9pbl9zYnNfbWludXNfMVt0aWxlMV0gKyAxOwo+ PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB1MzIgeDAgPSB0aWxlX2luZm8tPndpZHRoX2luX3Ni c19taW51c18xW3RpbGUwXSArIDE7Cj4+IC0KPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgLyog dGlsZSBzaXplIGluIFNCIHVuaXRzICh3aWR0aCxoZWlnaHQpICovCj4+IC3CoMKgwqDCoMKgwqDC oMKgwqDCoMKgICpkc3QrKyA9IHgwOwo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAqZHN0Kysg PSAwOwo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAqZHN0KysgPSAwOwo+PiAtwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCAqZHN0KysgPSAwOwo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAqZHN0 KysgPSB5MDsKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKmRzdCsrID0gMDsKPj4gLcKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgKmRzdCsrID0gMDsKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg KmRzdCsrID0gMDsKPj4gLQo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAvKiB0aWxlIHN0YXJ0 IHBvc2l0aW9uICovCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHN0YXJ0ID0gZ3JvdXBfZW50 cnlbdGlsZV9pZF0udGlsZV9vZmZzZXQgLSAKPj4gZ3JvdXBfZW50cnlbMF0udGlsZV9vZmZzZXQ7 Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgICpkc3QrKyA9IHN0YXJ0ICYgMjU1Owo+PiAtwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCAqZHN0KysgPSAoc3RhcnQgPj4gOCkgJiAyNTU7Cj4+IC3CoMKg wqDCoMKgwqDCoMKgwqDCoMKgICpkc3QrKyA9IChzdGFydCA+PiAxNikgJiAyNTU7Cj4+IC3CoMKg wqDCoMKgwqDCoMKgwqDCoMKgICpkc3QrKyA9IChzdGFydCA+PiAyNCkgJiAyNTU7Cj4+IC0KPj4g LcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgLyogbnVtYmVyIG9mIGJ5dGVzIGluIHRpbGUgZGF0YSAq Lwo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBlbmQgPSBzdGFydCArIGdyb3VwX2VudHJ5W3Rp bGVfaWRdLnRpbGVfc2l6ZTsKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKmRzdCsrID0gZW5k ICYgMjU1Owo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAqZHN0KysgPSAoZW5kID4+IDgpICYg MjU1Owo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAqZHN0KysgPSAoZW5kID4+IDE2KSAmIDI1 NTsKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKmRzdCsrID0gKGVuZCA+PiAyNCkgJiAyNTU7 Cj4+IC3CoMKgwqDCoMKgwqDCoCB9Cj4+IC3CoMKgwqAgfQo+PiArCj4+ICvCoMKgwqAgaGFudHJv X2F2MV9zZXRfdGlsZV9pbmZvKGN0eCk7Cj4+IMKgIMKgwqDCoMKgwqAgaGFudHJvX3JlZ193cml0 ZSh2cHUsICZhdjFfbXVsdGljb3JlX2V4cGVjdF9jb250ZXh0X3VwZGF0ZSwgCj4+ICEhKGNvbnRl eHRfdXBkYXRlX3ggPT0gMCkpOwo+PiDCoMKgwqDCoMKgIGhhbnRyb19yZWdfd3JpdGUodnB1LCAm YXYxX3RpbGVfZW5hYmxlLAo+PiBAQCAtNjMxLDggKzQ0LDggQEAgc3RhdGljIHZvaWQgCj4+IHJv Y2tjaGlwX3ZwdTk4MV9hdjFfZGVjX3NldF90aWxlX2luZm8oc3RydWN0IGhhbnRyb19jdHggKmN0 eCkKPj4gwqDCoMKgwqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9udW1fdGlsZV9yb3dz XzhrLCAKPj4gdGlsZV9pbmZvLT50aWxlX3Jvd3MpOwo+PiDCoMKgwqDCoMKgIGhhbnRyb19yZWdf d3JpdGUodnB1LCAmYXYxX2NvbnRleHRfdXBkYXRlX3RpbGVfaWQsIAo+PiBjb250ZXh0X3VwZGF0 ZV90aWxlX2lkKTsKPj4gwqDCoMKgwqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV90aWxl X3RyYW5zcG9zZSwgMSk7Cj4+IC3CoMKgwqAgaWYgKHJvY2tjaGlwX3ZwdTk4MV9hdjFfdGlsZV9s b2cyKHRpbGVfaW5mby0+dGlsZV9jb2xzKSB8fAo+PiAtwqDCoMKgwqDCoMKgwqAgcm9ja2NoaXBf dnB1OTgxX2F2MV90aWxlX2xvZzIodGlsZV9pbmZvLT50aWxlX3Jvd3MpKQo+PiArwqDCoMKgIGlm IChoYW50cm9fYXYxX3RpbGVfbG9nMih0aWxlX2luZm8tPnRpbGVfY29scykgfHwKPj4gK8KgwqDC oMKgwqDCoMKgIGhhbnRyb19hdjFfdGlsZV9sb2cyKHRpbGVfaW5mby0+dGlsZV9yb3dzKSkKPj4g wqDCoMKgwqDCoMKgwqDCoMKgIGhhbnRyb19yZWdfd3JpdGUodnB1LCAmYXYxX2RlY190aWxlX3Np emVfbWFnLCAKPj4gdGlsZV9pbmZvLT50aWxlX3NpemVfYnl0ZXMgLSAxKTsKPj4gwqDCoMKgwqDC oCBlbHNlCj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9k ZWNfdGlsZV9zaXplX21hZywgMyk7Cj4+IEBAIC02NDAsNTAgKzUzLDYgQEAgc3RhdGljIHZvaWQg Cj4+IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX3NldF90aWxlX2luZm8oc3RydWN0IGhhbnRyb19j dHggKmN0eCkKPj4gwqDCoMKgwqDCoCBoYW50cm9fd3JpdGVfYWRkcih2cHUsIEFWMV9USUxFX0JB U0UsIGF2MV9kZWMtPnRpbGVfaW5mby5kbWEpOwo+PiDCoCB9Cj4+IMKgIC1zdGF0aWMgaW50IHJv Y2tjaGlwX3ZwdTk4MV9hdjFfZGVjX2dldF9kaXN0KHN0cnVjdCBoYW50cm9fY3R4ICpjdHgsCj4+ IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGludCBhLCBp bnQgYikKPj4gLXsKPj4gLcKgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfaHdfY3R4ICphdjFf ZGVjID0gJmN0eC0+YXYxX2RlYzsKPj4gLcKgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9kZWNfY3Ry bHMgKmN0cmxzID0gJmF2MV9kZWMtPmN0cmxzOwo+PiAtwqDCoMKgIGludCBiaXRzID0gY3RybHMt PnNlcXVlbmNlLT5vcmRlcl9oaW50X2JpdHMgLSAxOwo+PiAtwqDCoMKgIGludCBkaWZmLCBtOwo+ PiAtCj4+IC3CoMKgwqAgaWYgKCFjdHJscy0+c2VxdWVuY2UtPm9yZGVyX2hpbnRfYml0cykKPj4g LcKgwqDCoMKgwqDCoMKgIHJldHVybiAwOwo+PiAtCj4+IC3CoMKgwqAgZGlmZiA9IGEgLSBiOwo+ PiAtwqDCoMKgIG0gPSAxIDw8IGJpdHM7Cj4+IC3CoMKgwqAgZGlmZiA9IChkaWZmICYgKG0gLSAx KSkgLSAoZGlmZiAmIG0pOwo+PiAtCj4+IC3CoMKgwqAgcmV0dXJuIGRpZmY7Cj4+IC19Cj4+IC0K Pj4gLXN0YXRpYyB2b2lkIHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX3NldF9mcmFtZV9zaWduX2Jp YXMoc3RydWN0IAo+PiBoYW50cm9fY3R4ICpjdHgpCj4+IC17Cj4+IC3CoMKgwqAgc3RydWN0IGhh bnRyb19hdjFfZGVjX2h3X2N0eCAqYXYxX2RlYyA9ICZjdHgtPmF2MV9kZWM7Cj4+IC3CoMKgwqAg c3RydWN0IGhhbnRyb19hdjFfZGVjX2N0cmxzICpjdHJscyA9ICZhdjFfZGVjLT5jdHJsczsKPj4g LcKgwqDCoCBjb25zdCBzdHJ1Y3QgdjRsMl9jdHJsX2F2MV9mcmFtZSAqZnJhbWUgPSBjdHJscy0+ ZnJhbWU7Cj4+IC3CoMKgwqAgY29uc3Qgc3RydWN0IHY0bDJfY3RybF9hdjFfc2VxdWVuY2UgKnNl cXVlbmNlID0gY3RybHMtPnNlcXVlbmNlOwo+PiAtwqDCoMKgIGludCBpOwo+PiAtCj4+IC3CoMKg wqAgaWYgKCFzZXF1ZW5jZS0+b3JkZXJfaGludF9iaXRzIHx8IElTX0lOVFJBKGZyYW1lLT5mcmFt ZV90eXBlKSkgewo+PiAtwqDCoMKgwqDCoMKgwqAgZm9yIChpID0gMDsgaSA8IFY0TDJfQVYxX1RP VEFMX1JFRlNfUEVSX0ZSQU1FOyBpKyspCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGF2MV9k ZWMtPnJlZl9mcmFtZV9zaWduX2JpYXNbaV0gPSAwOwo+PiAtCj4+IC3CoMKgwqDCoMKgwqDCoCBy ZXR1cm47Cj4+IC3CoMKgwqAgfQo+PiAtwqDCoMKgIC8vIElkZW50aWZ5IHRoZSBuZWFyZXN0IGZv cndhcmQgYW5kIGJhY2t3YXJkIHJlZmVyZW5jZXMuCj4+IC3CoMKgwqAgZm9yIChpID0gMDsgaSA8 IFY0TDJfQVYxX1RPVEFMX1JFRlNfUEVSX0ZSQU1FIC0gMTsgaSsrKSB7Cj4+IC3CoMKgwqDCoMKg wqDCoCBpZiAocm9ja2NoaXBfdnB1OTgxX2dldF9mcmFtZV9pbmRleChjdHgsIGkpID49IDApIHsK Pj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaW50IHJlbF9vZmYgPQo+PiAtwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX2dldF9kaXN0KGN0eCwK Pj4gLSByb2NrY2hpcF92cHU5ODFfZ2V0X29yZGVyX2hpbnQoY3R4LCBpKSwKPj4gLcKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg ZnJhbWUtPm9yZGVyX2hpbnQpOwo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5y ZWZfZnJhbWVfc2lnbl9iaWFzW2kgKyAxXSA9IChyZWxfb2ZmIDw9IDApID8gMCAKPj4gOiAxOwo+ PiAtwqDCoMKgwqDCoMKgwqAgfQo+PiAtwqDCoMKgIH0KPj4gLX0KPj4gLQo+PiDCoCBzdGF0aWMg Ym9vbAo+PiDCoCByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19zZXRfcmVmKHN0cnVjdCBoYW50cm9f Y3R4ICpjdHgsIGludCByZWYsIAo+PiBpbnQgaWR4LAo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIGludCB3aWR0aCwgaW50IGhlaWdodCkKPj4gQEAgLTgwNiwxMiArMTc1LDEy IEBAIHN0YXRpYyB2b2lkIAo+PiByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19zZXRfc2VnbWVudGF0 aW9uKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpCj4+IMKgIMKgwqDCoMKgwqAgaWYgKCEhKHNlZy0+ ZmxhZ3MgJiBWNEwyX0FWMV9TRUdNRU5UQVRJT05fRkxBR19FTkFCTEVEKSAmJgo+PiDCoMKgwqDC oMKgwqDCoMKgwqAgZnJhbWUtPnByaW1hcnlfcmVmX2ZyYW1lIDwgVjRMMl9BVjFfUkVGU19QRVJf RlJBTUUpIHsKPj4gLcKgwqDCoMKgwqDCoMKgIGludCBpZHggPSByb2NrY2hpcF92cHU5ODFfZ2V0 X2ZyYW1lX2luZGV4KGN0eCwgCj4+IGZyYW1lLT5wcmltYXJ5X3JlZl9mcmFtZSk7Cj4+ICvCoMKg wqDCoMKgwqDCoCBpbnQgaWR4ID0gaGFudHJvX2F2MV9nZXRfZnJhbWVfaW5kZXgoY3R4LCAKPj4g ZnJhbWUtPnByaW1hcnlfcmVmX2ZyYW1lKTsKPj4gwqAgLcKgwqDCoMKgwqDCoMKgIGlmIChpZHgg Pj0gMCkgewo+PiArwqDCoMKgwqDCoMKgwqAgaWYgKGlkeCAhPSBBVjFfSU5WQUxJRF9JRFgpIHsK Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZG1hX2FkZHJfdCBsdW1hX2FkZHIsIG12X2Fk ZHIgPSAwOwo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzdHJ1Y3QgaGFudHJvX2RlY29k ZWRfYnVmZmVyICpzZWc7Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHNpemVfdCBtdl9vZmZz ZXQgPSAKPj4gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfY2hyb21hX3NpemUoY3R4KTsKPj4gK8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqAgc2l6ZV90IG12X29mZnNldCA9IGhhbnRyb19hdjFfY2hyb21h X3NpemUoY3R4KTsKPj4gwqAgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgc2VnID0gCj4+IHZi Ml90b19oYW50cm9fZGVjb2RlZF9idWYoJmF2MV9kZWMtPmZyYW1lX3JlZnNbaWR4XS52YjJfcmVm LT52YjJfYnVmKTsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgbHVtYV9hZGRyID0gaGFu dHJvX2dldF9kZWNfYnVmX2FkZHIoY3R4LCAKPj4gJnNlZy0+YmFzZS52Yi52YjJfYnVmKTsKPj4g QEAgLTEwNDEsMzUgKzQxMCw2IEBAIHN0YXRpYyB2b2lkIAo+PiByb2NrY2hpcF92cHU5ODFfYXYx X2RlY19zZXRfc2VnbWVudGF0aW9uKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpCj4+IMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgc2VndmFsWzddW1Y0TDJfQVYxX1NFR19MVkxfUkVGX0dMT0JB TE1WXSk7Cj4+IMKgIH0KPj4gwqAgLXN0YXRpYyBib29sIHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVj X2lzX2xvc3NsZXNzKHN0cnVjdCBoYW50cm9fY3R4IAo+PiAqY3R4KQo+PiAtewo+PiAtwqDCoMKg IHN0cnVjdCBoYW50cm9fYXYxX2RlY19od19jdHggKmF2MV9kZWMgPSAmY3R4LT5hdjFfZGVjOwo+ PiAtwqDCoMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19jdHJscyAqY3RybHMgPSAmYXYxX2RlYy0+ Y3RybHM7Cj4+IC3CoMKgwqAgY29uc3Qgc3RydWN0IHY0bDJfY3RybF9hdjFfZnJhbWUgKmZyYW1l ID0gY3RybHMtPmZyYW1lOwo+PiAtwqDCoMKgIGNvbnN0IHN0cnVjdCB2NGwyX2F2MV9zZWdtZW50 YXRpb24gKnNlZ21lbnRhdGlvbiA9IAo+PiAmZnJhbWUtPnNlZ21lbnRhdGlvbjsKPj4gLcKgwqDC oCBjb25zdCBzdHJ1Y3QgdjRsMl9hdjFfcXVhbnRpemF0aW9uICpxdWFudGl6YXRpb24gPSAKPj4g JmZyYW1lLT5xdWFudGl6YXRpb247Cj4+IC3CoMKgwqAgaW50IGk7Cj4+IC0KPj4gLcKgwqDCoCBm b3IgKGkgPSAwOyBpIDwgVjRMMl9BVjFfTUFYX1NFR01FTlRTOyBpKyspIHsKPj4gLcKgwqDCoMKg wqDCoMKgIGludCBxaW5kZXggPSBxdWFudGl6YXRpb24tPmJhc2VfcV9pZHg7Cj4+IC0KPj4gLcKg wqDCoMKgwqDCoMKgIGlmIChzZWdtZW50YXRpb24tPmZlYXR1cmVfZW5hYmxlZFtpXSAmCj4+IC0g VjRMMl9BVjFfU0VHTUVOVF9GRUFUVVJFX0VOQUJMRUQoVjRMMl9BVjFfU0VHX0xWTF9BTFRfUSkp IHsKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcWluZGV4ICs9IAo+PiBzZWdtZW50YXRpb24t PmZlYXR1cmVfZGF0YVtpXVtWNEwyX0FWMV9TRUdfTFZMX0FMVF9RXTsKPj4gLcKgwqDCoMKgwqDC oMKgIH0KPj4gLcKgwqDCoMKgwqDCoMKgIHFpbmRleCA9IGNsYW1wKHFpbmRleCwgMCwgMjU1KTsK Pj4gLQo+PiAtwqDCoMKgwqDCoMKgwqAgaWYgKHFpbmRleCB8fAo+PiAtwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBxdWFudGl6YXRpb24tPmRlbHRhX3FfeV9kYyB8fAo+PiAtwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBxdWFudGl6YXRpb24tPmRlbHRhX3FfdV9kYyB8fAo+PiAtwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBxdWFudGl6YXRpb24tPmRlbHRhX3FfdV9hYyB8fAo+PiAtwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBxdWFudGl6YXRpb24tPmRlbHRhX3Ffdl9kYyB8fAo+PiAtwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBxdWFudGl6YXRpb24tPmRlbHRhX3Ffdl9hYykKPj4gLcKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgcmV0dXJuIGZhbHNlOwo+PiAtwqDCoMKgIH0KPj4gLcKgwqDCoCByZXR1cm4gdHJ1ZTsK Pj4gLX0KPj4gLQo+PiDCoCBzdGF0aWMgdm9pZCByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19zZXRf bG9vcGZpbHRlcihzdHJ1Y3QgCj4+IGhhbnRyb19jdHggKmN0eCkKPj4gwqAgewo+PiDCoMKgwqDC oMKgIHN0cnVjdCBoYW50cm9fYXYxX2RlY19od19jdHggKmF2MV9kZWMgPSAmY3R4LT5hdjFfZGVj Owo+PiBAQCAtMTA4OSw3ICs0MjksNyBAQCBzdGF0aWMgdm9pZCAKPj4gcm9ja2NoaXBfdnB1OTgx X2F2MV9kZWNfc2V0X2xvb3BmaWx0ZXIoc3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gwqDCoMKg wqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9maWx0X2xldmVsMywgbG9vcF9maWx0ZXIt PmxldmVsWzNdKTsKPj4gwqAgwqDCoMKgwqDCoCBpZiAobG9vcF9maWx0ZXItPmZsYWdzICYgCj4+ IFY0TDJfQVYxX0xPT1BfRklMVEVSX0ZMQUdfREVMVEFfRU5BQkxFRCAmJgo+PiAtwqDCoMKgwqDC oMKgwqAgIXJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX2lzX2xvc3NsZXNzKGN0eCkgJiYKPj4gK8Kg wqDCoMKgwqDCoMKgICFoYW50cm9fYXYxX2lzX2xvc3NsZXNzKGN0eCkgJiYKPj4gwqDCoMKgwqDC oMKgwqDCoMKgICEoZnJhbWUtPmZsYWdzICYgVjRMMl9BVjFfRlJBTUVfRkxBR19BTExPV19JTlRS QUJDKSkgewo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgaGFudHJvX3JlZ193cml0ZSh2cHUsICZhdjFf ZmlsdF9yZWZfYWRqXzAsCj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBs b29wX2ZpbHRlci0+cmVmX2RlbHRhc1swXSk7Cj4+IEBAIC0xMTI4LDEyMSArNDY4LDI3IEBAIHN0 YXRpYyB2b2lkIAo+PiByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19zZXRfbG9vcGZpbHRlcihzdHJ1 Y3QgaGFudHJvX2N0eCAqY3R4KQo+PiDCoMKgwqDCoMKgIGhhbnRyb193cml0ZV9hZGRyKHZwdSwg QVYxX0RCX0NUUkxfQ09MLCBhdjFfZGVjLT5kYl9jdHJsX2NvbC5kbWEpOwo+PiDCoCB9Cj4+IMKg IC1zdGF0aWMgdm9pZCByb2NrY2hpcF92cHU5ODFfYXYxX2RlY191cGRhdGVfcHJvYihzdHJ1Y3Qg aGFudHJvX2N0eCAKPj4gKmN0eCkKPj4gLXsKPj4gLcKgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9k ZWNfaHdfY3R4ICphdjFfZGVjID0gJmN0eC0+YXYxX2RlYzsKPj4gLcKgwqDCoCBzdHJ1Y3QgaGFu dHJvX2F2MV9kZWNfY3RybHMgKmN0cmxzID0gJmF2MV9kZWMtPmN0cmxzOwo+PiAtwqDCoMKgIGNv bnN0IHN0cnVjdCB2NGwyX2N0cmxfYXYxX2ZyYW1lICpmcmFtZSA9IGN0cmxzLT5mcmFtZTsKPj4g LcKgwqDCoCBib29sIGZyYW1lX2lzX2ludHJhID0gSVNfSU5UUkEoZnJhbWUtPmZyYW1lX3R5cGUp Owo+PiAtwqDCoMKgIHN0cnVjdCBhdjFjZGZzICpvdXRfY2RmcyA9IChzdHJ1Y3QgYXYxY2RmcyAK Pj4gKilhdjFfZGVjLT5wcm9iX3RibF9vdXQuY3B1Owo+PiAtwqDCoMKgIGludCBpOwo+PiAtCj4+ IC3CoMKgwqAgaWYgKGZyYW1lLT5mbGFncyAmIAo+PiBWNEwyX0FWMV9GUkFNRV9GTEFHX0RJU0FC TEVfRlJBTUVfRU5EX1VQREFURV9DREYpCj4+IC3CoMKgwqDCoMKgwqDCoCByZXR1cm47Cj4+IC0K Pj4gLcKgwqDCoCBmb3IgKGkgPSAwOyBpIDwgTlVNX1JFRl9GUkFNRVM7IGkrKykgewo+PiAtwqDC oMKgwqDCoMKgwqAgaWYgKGZyYW1lLT5yZWZyZXNoX2ZyYW1lX2ZsYWdzICYgQklUKGkpKSB7Cj4+ IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHN0cnVjdCBtdmNkZnMgc3RvcmVkX212X2NkZjsKPj4g LQo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByb2NrY2hpcF9hdjFfZ2V0X2NkZnMoY3R4LCBp KTsKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgc3RvcmVkX212X2NkZiA9IGF2MV9kZWMtPmNk ZnMtPm12X2NkZjsKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKmF2MV9kZWMtPmNkZnMgPSAq b3V0X2NkZnM7Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGlmIChmcmFtZV9pc19pbnRyYSkg ewo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGF2MV9kZWMtPmNkZnMtPm12X2Nk ZiA9IHN0b3JlZF9tdl9jZGY7Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKmF2 MV9kZWMtPmNkZnNfbmR2YyA9IG91dF9jZGZzLT5tdl9jZGY7Cj4+IC3CoMKgwqDCoMKgwqDCoMKg wqDCoMKgIH0KPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcm9ja2NoaXBfYXYxX3N0b3JlX2Nk ZnMoY3R4LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBmcmFtZS0+cmVmcmVzaF9mcmFtZV9mbGFncyk7Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKg IGJyZWFrOwo+PiAtwqDCoMKgwqDCoMKgwqAgfQo+PiAtwqDCoMKgIH0KPj4gLX0KPj4gLQo+PiAt dm9pZCByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19kb25lKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgp Cj4+IC17Cj4+IC3CoMKgwqAgcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfdXBkYXRlX3Byb2IoY3R4 KTsKPj4gLX0KPj4gLQo+PiDCoCBzdGF0aWMgdm9pZCByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19z ZXRfcHJvYihzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4KQo+PiDCoCB7Cj4+IMKgwqDCoMKgwqAgc3Ry dWN0IGhhbnRyb19hdjFfZGVjX2h3X2N0eCAqYXYxX2RlYyA9ICZjdHgtPmF2MV9kZWM7Cj4+IC3C oMKgwqAgc3RydWN0IGhhbnRyb19hdjFfZGVjX2N0cmxzICpjdHJscyA9ICZhdjFfZGVjLT5jdHJs czsKPj4gLcKgwqDCoCBjb25zdCBzdHJ1Y3QgdjRsMl9jdHJsX2F2MV9mcmFtZSAqZnJhbWUgPSBj dHJscy0+ZnJhbWU7Cj4+IC3CoMKgwqAgY29uc3Qgc3RydWN0IHY0bDJfYXYxX3F1YW50aXphdGlv biAqcXVhbnRpemF0aW9uID0gCj4+ICZmcmFtZS0+cXVhbnRpemF0aW9uOwo+PiDCoMKgwqDCoMKg IHN0cnVjdCBoYW50cm9fZGV2ICp2cHUgPSBjdHgtPmRldjsKPj4gLcKgwqDCoCBib29sIGVycm9y X3Jlc2lsaWVudF9tb2RlID0KPj4gLcKgwqDCoMKgwqDCoMKgICEhKGZyYW1lLT5mbGFncyAmIFY0 TDJfQVYxX0ZSQU1FX0ZMQUdfRVJST1JfUkVTSUxJRU5UX01PREUpOwo+PiAtwqDCoMKgIGJvb2wg ZnJhbWVfaXNfaW50cmEgPSBJU19JTlRSQShmcmFtZS0+ZnJhbWVfdHlwZSk7Cj4+IC0KPj4gLcKg wqDCoCBpZiAoZXJyb3JfcmVzaWxpZW50X21vZGUgfHwgZnJhbWVfaXNfaW50cmEgfHwKPj4gLcKg wqDCoMKgwqDCoMKgIGZyYW1lLT5wcmltYXJ5X3JlZl9mcmFtZSA9PSBBVjFfUFJJTUFSWV9SRUZf Tk9ORSkgewo+PiAtwqDCoMKgwqDCoMKgwqAgYXYxX2RlYy0+Y2RmcyA9ICZhdjFfZGVjLT5kZWZh dWx0X2NkZnM7Cj4+IC3CoMKgwqDCoMKgwqDCoCBhdjFfZGVjLT5jZGZzX25kdmMgPSAmYXYxX2Rl Yy0+ZGVmYXVsdF9jZGZzX25kdmM7Cj4+IC0gcm9ja2NoaXBfYXYxX2RlZmF1bHRfY29lZmZfcHJv YnMocXVhbnRpemF0aW9uLT5iYXNlX3FfaWR4LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGF2MV9kZWMtPmNkZnMpOwo+PiAtwqDCoMKgIH0gZWxz ZSB7Cj4+IC3CoMKgwqDCoMKgwqDCoCByb2NrY2hpcF9hdjFfZ2V0X2NkZnMoY3R4LCAKPj4gZnJh bWUtPnJlZl9mcmFtZV9pZHhbZnJhbWUtPnByaW1hcnlfcmVmX2ZyYW1lXSk7Cj4+IC3CoMKgwqAg fQo+PiAtwqDCoMKgIHJvY2tjaGlwX2F2MV9zdG9yZV9jZGZzKGN0eCwgZnJhbWUtPnJlZnJlc2hf ZnJhbWVfZmxhZ3MpOwo+PiAtCj4+IC3CoMKgwqAgbWVtY3B5KGF2MV9kZWMtPnByb2JfdGJsLmNw dSwgYXYxX2RlYy0+Y2Rmcywgc2l6ZW9mKHN0cnVjdCAKPj4gYXYxY2RmcykpOwo+PiAtCj4+IC3C oMKgwqAgaWYgKGZyYW1lX2lzX2ludHJhKSB7Cj4+IC3CoMKgwqDCoMKgwqDCoCBpbnQgbXZfb2Zm c2V0ID0gb2Zmc2V0b2Yoc3RydWN0IGF2MWNkZnMsIG12X2NkZik7Cj4+IC3CoMKgwqDCoMKgwqDC oCAvKiBPdmVyd3JpdGUgTVYgY29udGV4dCBhcmVhIHdpdGggaW50cmFiYyBNViBjb250ZXh0ICov Cj4+IC3CoMKgwqDCoMKgwqDCoCBtZW1jcHkoYXYxX2RlYy0+cHJvYl90YmwuY3B1ICsgbXZfb2Zm c2V0LCBhdjFfZGVjLT5jZGZzX25kdmMsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IHNpemVvZihzdHJ1Y3QgbXZjZGZzKSk7Cj4+IC3CoMKgwqAgfQo+PiDCoCArwqDCoMKgIGhhbnRy b19hdjFfc2V0X3Byb2IoY3R4KTsKPj4gwqDCoMKgwqDCoCBoYW50cm9fd3JpdGVfYWRkcih2cHUs IEFWMV9QUk9QX1RBQkxFX09VVCwgCj4+IGF2MV9kZWMtPnByb2JfdGJsX291dC5kbWEpOwo+PiDC oMKgwqDCoMKgIGhhbnRyb193cml0ZV9hZGRyKHZwdSwgQVYxX1BST1BfVEFCTEUsIGF2MV9kZWMt PnByb2JfdGJsLmRtYSk7Cj4+IMKgIH0KPj4gwqAgLXN0YXRpYyB2b2lkCj4+IC1yb2NrY2hpcF92 cHU5ODFfYXYxX2RlY19pbml0X3NjYWxpbmdfZnVuY3Rpb24oY29uc3QgdTggKnZhbHVlcywgCj4+ IGNvbnN0IHU4ICpzY2FsaW5nLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgdTggbnVtX3BvaW50cywgdTggKnNjYWxpbmdfbHV0KQo+PiAtewo+ PiAtwqDCoMKgIGludCBpLCBwb2ludDsKPj4gLQo+PiAtwqDCoMKgIGlmIChudW1fcG9pbnRzID09 IDApIHsKPj4gLcKgwqDCoMKgwqDCoMKgIG1lbXNldChzY2FsaW5nX2x1dCwgMCwgMjU2KTsKPj4g LcKgwqDCoMKgwqDCoMKgIHJldHVybjsKPj4gLcKgwqDCoCB9Cj4+IC0KPj4gLcKgwqDCoCBmb3Ig KHBvaW50ID0gMDsgcG9pbnQgPCBudW1fcG9pbnRzIC0gMTsgcG9pbnQrKykgewo+PiAtwqDCoMKg wqDCoMKgwqAgaW50IHg7Cj4+IC3CoMKgwqDCoMKgwqDCoCBzMzIgZGVsdGFfeSA9IHNjYWxpbmdb cG9pbnQgKyAxXSAtIHNjYWxpbmdbcG9pbnRdOwo+PiAtwqDCoMKgwqDCoMKgwqAgczMyIGRlbHRh X3ggPSB2YWx1ZXNbcG9pbnQgKyAxXSAtIHZhbHVlc1twb2ludF07Cj4+IC3CoMKgwqDCoMKgwqDC oCBzNjQgZGVsdGEgPQo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBkZWx0YV94ID8gZGVsdGFf eSAqICgoNjU1MzYgKyAoZGVsdGFfeCA+PiAxKSkgLwo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBkZWx0YV94KSA6IDA7Cj4+IC0KPj4gLcKgwqDCoMKgwqDCoMKg IGZvciAoeCA9IDA7IHggPCBkZWx0YV94OyB4KyspIHsKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgc2NhbGluZ19sdXRbdmFsdWVzW3BvaW50XSArIHhdID0KPj4gLcKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCBzY2FsaW5nW3BvaW50XSArCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgKHMzMikoKHggKiBkZWx0YSArIDMyNzY4KSA+PiAxNik7Cj4+IC3CoMKgwqDCoMKg wqDCoCB9Cj4+IC3CoMKgwqAgfQo+PiAtCj4+IC3CoMKgwqAgZm9yIChpID0gdmFsdWVzW251bV9w b2ludHMgLSAxXTsgaSA8IDI1NjsgaSsrKQo+PiAtwqDCoMKgwqDCoMKgwqAgc2NhbGluZ19sdXRb aV0gPSBzY2FsaW5nW251bV9wb2ludHMgLSAxXTsKPj4gLX0KPj4gwqAgwqAgc3RhdGljIHZvaWQg cm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfc2V0X2ZncyhzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4KQo+ PiDCoCB7Cj4+IMKgwqDCoMKgwqAgc3RydWN0IGhhbnRyb19hdjFfZGVjX2h3X2N0eCAqYXYxX2Rl YyA9ICZjdHgtPmF2MV9kZWM7Cj4+IMKgwqDCoMKgwqAgc3RydWN0IGhhbnRyb19hdjFfZGVjX2N0 cmxzICpjdHJscyA9ICZhdjFfZGVjLT5jdHJsczsKPj4gwqDCoMKgwqDCoCBjb25zdCBzdHJ1Y3Qg djRsMl9jdHJsX2F2MV9maWxtX2dyYWluICpmaWxtX2dyYWluID0gCj4+IGN0cmxzLT5maWxtX2dy YWluOwo+PiAtwqDCoMKgIHN0cnVjdCByb2NrY2hpcF9hdjFfZmlsbV9ncmFpbiAqZmdtZW0gPSBh djFfZGVjLT5maWxtX2dyYWluLmNwdTsKPj4gK8KgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9maWxt X2dyYWluICpmZ21lbSA9IGF2MV9kZWMtPmZpbG1fZ3JhaW4uY3B1Owo+PiDCoMKgwqDCoMKgIHN0 cnVjdCBoYW50cm9fZGV2ICp2cHUgPSBjdHgtPmRldjsKPj4gwqDCoMKgwqDCoCBib29sIHNjYWxp bmdfZnJvbV9sdW1hID0KPj4gwqDCoMKgwqDCoMKgwqDCoMKgICEhKGZpbG1fZ3JhaW4tPmZsYWdz ICYgCj4+IFY0TDJfQVYxX0ZJTE1fR1JBSU5fRkxBR19DSFJPTUFfU0NBTElOR19GUk9NX0xVTUEp Owo+PiAtwqDCoMKgIHMzMiAoKmFyX2NvZWZmc195KVsyNF07Cj4+IC3CoMKgwqAgczMyICgqYXJf Y29lZmZzX2NiKVsyNV07Cj4+IC3CoMKgwqAgczMyICgqYXJfY29lZmZzX2NyKVsyNV07Cj4+IC3C oMKgwqAgczMyICgqbHVtYV9ncmFpbl9ibG9jaylbNzNdWzgyXTsKPj4gLcKgwqDCoCBzMzIgKCpj Yl9ncmFpbl9ibG9jaylbMzhdWzQ0XTsKPj4gLcKgwqDCoCBzMzIgKCpjcl9ncmFpbl9ibG9jaylb MzhdWzQ0XTsKPj4gK8KgwqDCoCBzdHJ1Y3QgaGFudHJvX2F2MV9jb2VmZnNfZ3JhaW5fYmxvY2sg KmNvZWZmczsKPj4gwqDCoMKgwqDCoCBzMzIgYXJfY29lZmZfbGFnLCBhcl9jb2VmZl9zaGlmdDsK Pj4gwqDCoMKgwqDCoCBzMzIgZ3JhaW5fc2NhbGVfc2hpZnQsIGJpdGRlcHRoOwo+PiDCoMKgwqDC oMKgIHMzMiBncmFpbl9jZW50ZXIsIGdyYWluX21pbiwgZ3JhaW5fbWF4Owo+PiBAQCAtMTI2OSwx OCArNTE1LDkgQEAgc3RhdGljIHZvaWQgCj4+IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX3NldF9m Z3Moc3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybjsK Pj4gwqDCoMKgwqDCoCB9Cj4+IMKgIC3CoMKgwqAgYXJfY29lZmZzX3kgPSBremFsbG9jKHNpemVv ZihpbnQzMl90KSAqIDI0LCBHRlBfS0VSTkVMKTsKPj4gLcKgwqDCoCBhcl9jb2VmZnNfY2IgPSBr emFsbG9jKHNpemVvZihpbnQzMl90KSAqIDI1LCBHRlBfS0VSTkVMKTsKPj4gLcKgwqDCoCBhcl9j b2VmZnNfY3IgPSBremFsbG9jKHNpemVvZihpbnQzMl90KSAqIDI1LCBHRlBfS0VSTkVMKTsKPj4g LcKgwqDCoCBsdW1hX2dyYWluX2Jsb2NrID0ga3phbGxvYyhzaXplb2YoaW50MzJfdCkgKiA3MyAq IDgyLCBHRlBfS0VSTkVMKTsKPj4gLcKgwqDCoCBjYl9ncmFpbl9ibG9jayA9IGt6YWxsb2Moc2l6 ZW9mKGludDMyX3QpICogMzggKiA0NCwgR0ZQX0tFUk5FTCk7Cj4+IC3CoMKgwqAgY3JfZ3JhaW5f YmxvY2sgPSBremFsbG9jKHNpemVvZihpbnQzMl90KSAqIDM4ICogNDQsIEdGUF9LRVJORUwpOwo+ PiAtCj4+IC3CoMKgwqAgaWYgKCFhcl9jb2VmZnNfeSB8fCAhYXJfY29lZmZzX2NiIHx8ICFhcl9j b2VmZnNfY3IgfHwKPj4gLcKgwqDCoMKgwqDCoMKgICFsdW1hX2dyYWluX2Jsb2NrIHx8ICFjYl9n cmFpbl9ibG9jayB8fCAhY3JfZ3JhaW5fYmxvY2spIHsKPj4gLcKgwqDCoMKgwqDCoMKgIHByX3dh cm4oIkZhaWwgYWxsb2NhdGluZyBtZW1vcnkgZm9yIGZpbG0gZ3JhaW4gcGFyYW1ldGVyc1xuIik7 Cj4+IC3CoMKgwqDCoMKgwqDCoCBnb3RvIGFsbG9jX2ZhaWw7Cj4+IC3CoMKgwqAgfQo+PiArwqDC oMKgIGNvZWZmcyA9IGt6YWxsb2Moc2l6ZW9mKCpjb2VmZnMpLCBHRlBfS0VSTkVMKTsKPj4gK8Kg wqDCoCBpZiAoIWNvZWZmcykKPj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybjsKPj4gwqAgwqDCoMKg wqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9hcHBseV9ncmFpbiwgMSk7Cj4+IMKgIEBA IC0xMzE2LDEwICs1NTMsMTAgQEAgc3RhdGljIHZvaWQgCj4+IHJvY2tjaGlwX3ZwdTk4MV9hdjFf ZGVjX3NldF9mZ3Moc3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gwqDCoMKgwqDCoCBoYW50cm9f cmVnX3dyaXRlKHZwdSwgJmF2MV9jaHJvbWFfc2NhbGluZ19mcm9tX2x1bWEsIAo+PiBzY2FsaW5n X2Zyb21fbHVtYSk7Cj4+IMKgwqDCoMKgwqAgaGFudHJvX3JlZ193cml0ZSh2cHUsICZhdjFfcmFu ZG9tX3NlZWQsIGZpbG1fZ3JhaW4tPmdyYWluX3NlZWQpOwo+PiDCoCAtIAo+PiByb2NrY2hpcF92 cHU5ODFfYXYxX2RlY19pbml0X3NjYWxpbmdfZnVuY3Rpb24oZmlsbV9ncmFpbi0+cG9pbnRfeV92 YWx1ZSwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgZmlsbV9ncmFpbi0+cG9pbnRfeV9zY2FsaW5nLAo+PiAtwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBmaWxtX2dyYWlu LT5udW1feV9wb2ludHMsCj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIGZnbWVtLT5zY2FsaW5nX2x1dF95KTsKPj4gKyBoYW50cm9f YXYxX2luaXRfc2NhbGluZ19mdW5jdGlvbihmaWxtX2dyYWluLT5wb2ludF95X3ZhbHVlLAo+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBmaWxtX2dyYWluLT5wb2lu dF95X3NjYWxpbmcsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IGZpbG1fZ3JhaW4tPm51bV95X3BvaW50cywKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgZmdtZW0tPnNjYWxpbmdfbHV0X3kpOwo+PiDCoCDCoMKgwqDCoMKgIGlm IChmaWxtX2dyYWluLT5mbGFncyAmCj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBWNEwyX0FWMV9GSUxN X0dSQUlOX0ZMQUdfQ0hST01BX1NDQUxJTkdfRlJPTV9MVU1BKSB7Cj4+IEBAIC0xMzI4LDE5ICs1 NjUsMTkgQEAgc3RhdGljIHZvaWQgCj4+IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX3NldF9mZ3Mo c3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIG1lbWNweShmZ21l bS0+c2NhbGluZ19sdXRfY3IsIGZnbWVtLT5zY2FsaW5nX2x1dF95LAo+PiDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBzaXplb2YoKmZnbWVtLT5zY2FsaW5nX2x1dF95KSAqIDI1Nik7 Cj4+IMKgwqDCoMKgwqAgfSBlbHNlIHsKPj4gLcKgwqDCoMKgwqDCoMKgIHJvY2tjaGlwX3ZwdTk4 MV9hdjFfZGVjX2luaXRfc2NhbGluZ19mdW5jdGlvbgo+PiArwqDCoMKgwqDCoMKgwqAgaGFudHJv X2F2MV9pbml0X3NjYWxpbmdfZnVuY3Rpb24KPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg KGZpbG1fZ3JhaW4tPnBvaW50X2NiX3ZhbHVlLCBmaWxtX2dyYWluLT5wb2ludF9jYl9zY2FsaW5n LAo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGZpbG1fZ3JhaW4tPm51bV9jYl9wb2lu dHMsIGZnbWVtLT5zY2FsaW5nX2x1dF9jYik7Cj4+IC3CoMKgwqDCoMKgwqDCoCByb2NrY2hpcF92 cHU5ODFfYXYxX2RlY19pbml0X3NjYWxpbmdfZnVuY3Rpb24KPj4gK8KgwqDCoMKgwqDCoMKgIGhh bnRyb19hdjFfaW5pdF9zY2FsaW5nX2Z1bmN0aW9uCj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIChmaWxtX2dyYWluLT5wb2ludF9jcl92YWx1ZSwgZmlsbV9ncmFpbi0+cG9pbnRfY3Jfc2Nh bGluZywKPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBmaWxtX2dyYWluLT5udW1fY3Jf cG9pbnRzLCBmZ21lbS0+c2NhbGluZ19sdXRfY3IpOwo+PiDCoMKgwqDCoMKgIH0KPj4gwqAgwqDC oMKgwqDCoCBmb3IgKGkgPSAwOyBpIDwgVjRMMl9BVjFfQVJfQ09FRkZTX1NJWkU7IGkrKykgewo+ PiDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKGkgPCAyNCkKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgKCphcl9jb2VmZnNfeSlbaV0gPSBmaWxtX2dyYWluLT5hcl9jb2VmZnNfeV9wbHVzXzEyOFtp XSAKPj4gLSAxMjg7Cj4+IC3CoMKgwqDCoMKgwqDCoCAoKmFyX2NvZWZmc19jYilbaV0gPSBmaWxt X2dyYWluLT5hcl9jb2VmZnNfY2JfcGx1c18xMjhbaV0gLSAKPj4gMTI4Owo+PiAtwqDCoMKgwqDC oMKgwqAgKCphcl9jb2VmZnNfY3IpW2ldID0gZmlsbV9ncmFpbi0+YXJfY29lZmZzX2NyX3BsdXNf MTI4W2ldIC0gCj4+IDEyODsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgY29lZmZzLT5hcl9j b2VmZnNfeVtpXSA9IAo+PiBmaWxtX2dyYWluLT5hcl9jb2VmZnNfeV9wbHVzXzEyOFtpXSAtIDEy ODsKPj4gK8KgwqDCoMKgwqDCoMKgIGNvZWZmcy0+YXJfY29lZmZzX2NiW2ldID0gCj4+IGZpbG1f Z3JhaW4tPmFyX2NvZWZmc19jYl9wbHVzXzEyOFtpXSAtIDEyODsKPj4gK8KgwqDCoMKgwqDCoMKg IGNvZWZmcy0+YXJfY29lZmZzX2NyW2ldID0gCj4+IGZpbG1fZ3JhaW4tPmFyX2NvZWZmc19jcl9w bHVzXzEyOFtpXSAtIDEyODsKPj4gwqDCoMKgwqDCoCB9Cj4+IMKgIMKgwqDCoMKgwqAgYXJfY29l ZmZfbGFnID0gZmlsbV9ncmFpbi0+YXJfY29lZmZfbGFnOwo+PiBAQCAtMTM1MSw0NiArNTg4LDM4 IEBAIHN0YXRpYyB2b2lkIAo+PiByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19zZXRfZmdzKHN0cnVj dCBoYW50cm9fY3R4ICpjdHgpCj4+IMKgwqDCoMKgwqAgZ3JhaW5fbWluID0gMCAtIGdyYWluX2Nl bnRlcjsKPj4gwqDCoMKgwqDCoCBncmFpbl9tYXggPSAoMjU2IDw8IChiaXRkZXB0aCAtIDgpKSAt IDEgLSBncmFpbl9jZW50ZXI7Cj4+IMKgIC3CoMKgwqAgcm9ja2NoaXBfYXYxX2dlbmVyYXRlX2x1 bWFfZ3JhaW5fYmxvY2sobHVtYV9ncmFpbl9ibG9jaywgCj4+IGJpdGRlcHRoLAo+PiAtwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBmaWxtX2dyYWlu LT5udW1feV9wb2ludHMsIGdyYWluX3NjYWxlX3NoaWZ0LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhcl9jb2VmZl9sYWcsIGFyX2NvZWZm c195LCBhcl9jb2VmZl9zaGlmdCwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgZ3JhaW5fbWluLCBncmFpbl9tYXgsIAo+PiBmaWxtX2dyYWlu LT5ncmFpbl9zZWVkKTsKPj4gLQo+PiAtwqDCoMKgIHJvY2tjaGlwX2F2MV9nZW5lcmF0ZV9jaHJv bWFfZ3JhaW5fYmxvY2sobHVtYV9ncmFpbl9ibG9jaywgCj4+IGNiX2dyYWluX2Jsb2NrLAo+PiAt wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGNyX2dyYWlu X2Jsb2NrLCBiaXRkZXB0aCwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCBmaWxtX2dyYWluLT5udW1feV9wb2ludHMsCj4+IC3CoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZmlsbV9ncmFpbi0+bnVtX2NiX3Bv aW50cywKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBmaWxtX2dyYWluLT5udW1fY3JfcG9pbnRzLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGdyYWluX3NjYWxlX3NoaWZ0LCBhcl9jb2VmZl9sYWcs IGFyX2NvZWZmc19jYiwKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCBhcl9jb2VmZnNfY3IsIGFyX2NvZWZmX3NoaWZ0LCBncmFpbl9taW4sCj4+IC3C oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZ3JhaW5fbWF4 LAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHNj YWxpbmdfZnJvbV9sdW1hLAo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIGZpbG1fZ3JhaW4tPmdyYWluX3NlZWQpOwo+PiArwqDCoMKgIGhhbnRyb19h djFfZ2VuZXJhdGVfbHVtYV9ncmFpbl9ibG9jayhjb2VmZnMsIGJpdGRlcHRoLAo+PiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGZpbG1fZ3JhaW4tPm51 bV95X3BvaW50cywgZ3JhaW5fc2NhbGVfc2hpZnQsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYXJfY29lZmZfbGFnLCBhcl9jb2VmZl9zaGlmdCwK Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBncmFp bl9taW4sIGdyYWluX21heCwgZmlsbV9ncmFpbi0+Z3JhaW5fc2VlZCk7Cj4+ICsKPj4gK8KgwqDC oCBoYW50cm9fYXYxX2dlbmVyYXRlX2Nocm9tYV9ncmFpbl9ibG9jayhjb2VmZnMsIGJpdGRlcHRo LAo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBmaWxtX2dyYWluLT5udW1feV9wb2ludHMsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGZpbG1fZ3JhaW4tPm51bV9jYl9wb2ludHMsCj4+ ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGZp bG1fZ3JhaW4tPm51bV9jcl9wb2ludHMsCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGdyYWluX3NjYWxlX3NoaWZ0LCBhcl9jb2VmZl9sYWcs Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IGFyX2NvZWZmX3NoaWZ0LCBncmFpbl9taW4sCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGdyYWluX21heCwKPj4gK8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgc2NhbGluZ19mcm9tX2x1bWEs Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IGZpbG1fZ3JhaW4tPmdyYWluX3NlZWQpOwo+PiDCoCDCoMKgwqDCoMKgIGZvciAoaSA9IDA7IGkg PCA2NDsgaSsrKSB7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBmb3IgKGogPSAwOyBqIDwgNjQ7IGor KykKPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZmdtZW0tPmNyb3BwZWRfbHVtYV9ncmFp bl9ibG9ja1tpICogNjQgKyBqXSA9Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg KCpsdW1hX2dyYWluX2Jsb2NrKVtpICsgOV1baiArIDldOwo+PiArwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIGNvZWZmcy0+bHVtYV9ncmFpbl9ibG9ja1tpICsgOV1baiArIDldOwo+PiDC oMKgwqDCoMKgIH0KPj4gwqAgwqDCoMKgwqDCoCBmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykgewo+ PiDCoMKgwqDCoMKgwqDCoMKgwqAgZm9yIChqID0gMDsgaiA8IDMyOyBqKyspIHsKPj4gwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgZmdtZW0tPmNyb3BwZWRfY2hyb21hX2dyYWluX2Jsb2NrW2kg KiA2NCArIDIgKiBqXSA9Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKCpjYl9n cmFpbl9ibG9jaylbaSArIDZdW2ogKyA2XTsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCBjb2VmZnMtPmNiX2dyYWluX2Jsb2NrW2kgKyA2XVtqICsgNl07Cj4+IMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIGZnbWVtLT5jcm9wcGVkX2Nocm9tYV9ncmFpbl9ibG9ja1tpICogNjQg KyAyICogaiArIDFdID0KPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoKmNyX2dy YWluX2Jsb2NrKVtpICsgNl1baiArIDZdOwo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIGNvZWZmcy0+Y3JfZ3JhaW5fYmxvY2tbaSArIDZdW2ogKyA2XTsKPj4gwqDCoMKgwqDCoMKg wqDCoMKgIH0KPj4gwqDCoMKgwqDCoCB9Cj4+IMKgICvCoMKgwqAga2ZyZWUoY29lZmZzKTsKPj4g wqDCoMKgwqDCoCBoYW50cm9fd3JpdGVfYWRkcih2cHUsIEFWMV9GSUxNX0dSQUlOLCBhdjFfZGVj LT5maWxtX2dyYWluLmRtYSk7Cj4+IC0KPj4gLWFsbG9jX2ZhaWw6Cj4+IC3CoMKgwqAga2ZyZWUo YXJfY29lZmZzX3kpOwo+PiAtwqDCoMKgIGtmcmVlKGFyX2NvZWZmc19jYik7Cj4+IC3CoMKgwqAg a2ZyZWUoYXJfY29lZmZzX2NyKTsKPj4gLcKgwqDCoCBrZnJlZShsdW1hX2dyYWluX2Jsb2NrKTsK Pj4gLcKgwqDCoCBrZnJlZShjYl9ncmFpbl9ibG9jayk7Cj4+IC3CoMKgwqAga2ZyZWUoY3JfZ3Jh aW5fYmxvY2spOwo+PiDCoCB9Cj4+IMKgIMKgIHN0YXRpYyB2b2lkIHJvY2tjaGlwX3ZwdTk4MV9h djFfZGVjX3NldF9jZGVmKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpCj4+IEBAIC0xNjE3LDEzICs4 NDYsMTMgQEAgc3RhdGljIHZvaWQgCj4+IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX3NldF9vdGhl cl9mcmFtZXMoc3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gwqDCoMKgwqDCoCBpbnQgcmVmX2lu ZCA9IDA7Cj4+IMKgwqDCoMKgwqAgaW50IHJmLCBpZHg7Cj4+IMKgIC3CoMKgwqAgYWx0X2ZyYW1l X29mZnNldCA9IHJvY2tjaGlwX3ZwdTk4MV9nZXRfb3JkZXJfaGludChjdHgsIAo+PiBBTFRfQlVG X0lEWCk7Cj4+IC3CoMKgwqAgZ2xkX2ZyYW1lX29mZnNldCA9IHJvY2tjaGlwX3ZwdTk4MV9nZXRf b3JkZXJfaGludChjdHgsIAo+PiBHTERfQlVGX0lEWCk7Cj4+IC3CoMKgwqAgYndkX2ZyYW1lX29m ZnNldCA9IHJvY2tjaGlwX3ZwdTk4MV9nZXRfb3JkZXJfaGludChjdHgsIAo+PiBCV0RfQlVGX0lE WCk7Cj4+IC3CoMKgwqAgYWx0Ml9mcmFtZV9vZmZzZXQgPSByb2NrY2hpcF92cHU5ODFfZ2V0X29y ZGVyX2hpbnQoY3R4LCAKPj4gQUxUMl9CVUZfSURYKTsKPj4gK8KgwqDCoCBhbHRfZnJhbWVfb2Zm c2V0ID0gaGFudHJvX2F2MV9nZXRfb3JkZXJfaGludChjdHgsIEFMVF9CVUZfSURYKTsKPj4gK8Kg wqDCoCBnbGRfZnJhbWVfb2Zmc2V0ID0gaGFudHJvX2F2MV9nZXRfb3JkZXJfaGludChjdHgsIEdM RF9CVUZfSURYKTsKPj4gK8KgwqDCoCBid2RfZnJhbWVfb2Zmc2V0ID0gaGFudHJvX2F2MV9nZXRf b3JkZXJfaGludChjdHgsIEJXRF9CVUZfSURYKTsKPj4gK8KgwqDCoCBhbHQyX2ZyYW1lX29mZnNl dCA9IGhhbnRyb19hdjFfZ2V0X29yZGVyX2hpbnQoY3R4LCBBTFQyX0JVRl9JRFgpOwo+PiDCoCAt wqDCoMKgIGlkeCA9IHJvY2tjaGlwX3ZwdTk4MV9nZXRfZnJhbWVfaW5kZXgoY3R4LCBMU1RfQlVG X0lEWCk7Cj4+IC3CoMKgwqAgaWYgKGlkeCA+PSAwKSB7Cj4+ICvCoMKgwqAgaWR4ID0gaGFudHJv X2F2MV9nZXRfZnJhbWVfaW5kZXgoY3R4LCBMU1RfQlVGX0lEWCk7Cj4+ICvCoMKgwqAgaWYgKGlk eCAhPSBBVjFfSU5WQUxJRF9JRFgpIHsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGludCBhbHRfZnJh bWVfb2Zmc2V0X2luX2xzdCA9Cj4+IGF2MV9kZWMtPmZyYW1lX3JlZnNbaWR4XS5vcmRlcl9oaW50 c1tWNEwyX0FWMV9SRUZfQUxUUkVGX0ZSQU1FXTsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGJvb2wg aXNfbHN0X292ZXJsYXkgPQo+PiBAQCAtMTY0NCw4ICs4NzMsOSBAQCBzdGF0aWMgdm9pZCAKPj4g cm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfc2V0X290aGVyX2ZyYW1lcyhzdHJ1Y3QgaGFudHJvX2N0 eCAqY3R4KQo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgcmVmX3N0YW1wLS07Cj4+IMKgwqDCoMKgwqAg fQo+PiDCoCAtwqDCoMKgIGlkeCA9IHJvY2tjaGlwX3ZwdTk4MV9nZXRfZnJhbWVfaW5kZXgoY3R4 LCBCV0RfQlVGX0lEWCk7Cj4+IC3CoMKgwqAgaWYgKHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX2dl dF9kaXN0KGN0eCwgYndkX2ZyYW1lX29mZnNldCwgCj4+IGN1cl9mcmFtZV9vZmZzZXQpID4gMCkg ewo+PiArwqDCoMKgIGlkeCA9IGhhbnRyb19hdjFfZ2V0X2ZyYW1lX2luZGV4KGN0eCwgQldEX0JV Rl9JRFgpOwo+PiArwqDCoMKgIGlmIChpZHggIT0gQVYxX0lOVkFMSURfSURYICYmCj4+ICvCoMKg wqDCoMKgwqDCoCBoYW50cm9fYXYxX2dldF9kaXN0KGN0eCwgYndkX2ZyYW1lX29mZnNldCwgY3Vy X2ZyYW1lX29mZnNldCkgCj4+ID4gMCkgewo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgaW50IGJ3ZF9t aV9jb2xzID0gYXYxX2RlYy0+ZnJhbWVfcmVmc1tpZHhdLm1pX2NvbHM7Cj4+IMKgwqDCoMKgwqDC oMKgwqDCoCBpbnQgYndkX21pX3Jvd3MgPSBhdjFfZGVjLT5mcmFtZV9yZWZzW2lkeF0ubWlfcm93 czsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGJvb2wgYndkX2ludHJhX29ubHkgPQo+PiBAQCAtMTY1 OSw4ICs4ODksOSBAQCBzdGF0aWMgdm9pZCAKPj4gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfc2V0 X290aGVyX2ZyYW1lcyhzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4KQo+PiDCoMKgwqDCoMKgwqDCoMKg wqAgfQo+PiDCoMKgwqDCoMKgIH0KPj4gwqAgLcKgwqDCoCBpZHggPSByb2NrY2hpcF92cHU5ODFf Z2V0X2ZyYW1lX2luZGV4KGN0eCwgQUxUMl9CVUZfSURYKTsKPj4gLcKgwqDCoCBpZiAocm9ja2No aXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCBhbHQyX2ZyYW1lX29mZnNldCwgCj4+IGN1 cl9mcmFtZV9vZmZzZXQpID4gMCkgewo+PiArwqDCoMKgIGlkeCA9IGhhbnRyb19hdjFfZ2V0X2Zy YW1lX2luZGV4KGN0eCwgQUxUMl9CVUZfSURYKTsKPj4gK8KgwqDCoCBpZiAoaWR4ICE9IEFWMV9J TlZBTElEX0lEWCAmJgo+PiArwqDCoMKgwqDCoMKgwqAgaGFudHJvX2F2MV9nZXRfZGlzdChjdHgs IGFsdDJfZnJhbWVfb2Zmc2V0LCAKPj4gY3VyX2ZyYW1lX29mZnNldCkgPiAwKSB7Cj4+IMKgwqDC oMKgwqDCoMKgwqDCoCBpbnQgYWx0Ml9taV9jb2xzID0gYXYxX2RlYy0+ZnJhbWVfcmVmc1tpZHhd Lm1pX2NvbHM7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBpbnQgYWx0Ml9taV9yb3dzID0gYXYxX2Rl Yy0+ZnJhbWVfcmVmc1tpZHhdLm1pX3Jvd3M7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBib29sIGFs dDJfaW50cmFfb25seSA9Cj4+IEBAIC0xNjc0LDggKzkwNSw5IEBAIHN0YXRpYyB2b2lkIAo+PiBy b2NrY2hpcF92cHU5ODFfYXYxX2RlY19zZXRfb3RoZXJfZnJhbWVzKHN0cnVjdCBoYW50cm9fY3R4 ICpjdHgpCj4+IMKgwqDCoMKgwqDCoMKgwqDCoCB9Cj4+IMKgwqDCoMKgwqAgfQo+PiDCoCAtwqDC oMKgIGlkeCA9IHJvY2tjaGlwX3ZwdTk4MV9nZXRfZnJhbWVfaW5kZXgoY3R4LCBBTFRfQlVGX0lE WCk7Cj4+IC3CoMKgwqAgaWYgKHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX2dldF9kaXN0KGN0eCwg YWx0X2ZyYW1lX29mZnNldCwgCj4+IGN1cl9mcmFtZV9vZmZzZXQpID4gMCAmJgo+PiArwqDCoMKg IGlkeCA9IGhhbnRyb19hdjFfZ2V0X2ZyYW1lX2luZGV4KGN0eCwgQUxUX0JVRl9JRFgpOwo+PiAr wqDCoMKgIGlmIChpZHggIT0gQVYxX0lOVkFMSURfSURYICYmCj4+ICvCoMKgwqDCoMKgwqDCoCBo YW50cm9fYXYxX2dldF9kaXN0KGN0eCwgYWx0X2ZyYW1lX29mZnNldCwgY3VyX2ZyYW1lX29mZnNl dCkgCj4+ID4gMCAmJgo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgcmVmX3N0YW1wID49IDApIHsKPj4g wqDCoMKgwqDCoMKgwqDCoMKgIGludCBhbHRfbWlfY29scyA9IGF2MV9kZWMtPmZyYW1lX3JlZnNb aWR4XS5taV9jb2xzOwo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgaW50IGFsdF9taV9yb3dzID0gYXYx X2RlYy0+ZnJhbWVfcmVmc1tpZHhdLm1pX3Jvd3M7Cj4+IEBAIC0xNjkwLDggKzkyMiw4IEBAIHN0 YXRpYyB2b2lkIAo+PiByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19zZXRfb3RoZXJfZnJhbWVzKHN0 cnVjdCBoYW50cm9fY3R4ICpjdHgpCj4+IMKgwqDCoMKgwqDCoMKgwqDCoCB9Cj4+IMKgwqDCoMKg wqAgfQo+PiDCoCAtwqDCoMKgIGlkeCA9IHJvY2tjaGlwX3ZwdTk4MV9nZXRfZnJhbWVfaW5kZXgo Y3R4LCBMU1QyX0JVRl9JRFgpOwo+PiAtwqDCoMKgIGlmIChpZHggPj0gMCAmJiByZWZfc3RhbXAg Pj0gMCkgewo+PiArwqDCoMKgIGlkeCA9IGhhbnRyb19hdjFfZ2V0X2ZyYW1lX2luZGV4KGN0eCwg TFNUMl9CVUZfSURYKTsKPj4gK8KgwqDCoCBpZiAoaWR4ICE9IEFWMV9JTlZBTElEX0lEWCAmJiBy ZWZfc3RhbXAgPj0gMCkgewo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgaW50IGxzdDJfbWlfY29scyA9 IGF2MV9kZWMtPmZyYW1lX3JlZnNbaWR4XS5taV9jb2xzOwo+PiDCoMKgwqDCoMKgwqDCoMKgwqAg aW50IGxzdDJfbWlfcm93cyA9IGF2MV9kZWMtPmZyYW1lX3JlZnNbaWR4XS5taV9yb3dzOwo+PiDC oMKgwqDCoMKgwqDCoMKgwqAgYm9vbCBsc3QyX2ludHJhX29ubHkgPQo+PiBAQCAtMTcwNiwxNCAr OTM4LDE0IEBAIHN0YXRpYyB2b2lkIAo+PiByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19zZXRfb3Ro ZXJfZnJhbWVzKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpCj4+IMKgwqDCoMKgwqAgfQo+PiDCoCDC oMKgwqDCoMKgIGZvciAocmYgPSAwOyByZiA8IFY0TDJfQVYxX1RPVEFMX1JFRlNfUEVSX0ZSQU1F IC0gMTsgKytyZikgewo+PiAtwqDCoMKgwqDCoMKgwqAgaWR4ID0gcm9ja2NoaXBfdnB1OTgxX2dl dF9mcmFtZV9pbmRleChjdHgsIHJmKTsKPj4gLcKgwqDCoMKgwqDCoMKgIGlmIChpZHggPj0gMCkg ewo+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBpbnQgcmZfb3JkZXJfaGludCA9IHJvY2tjaGlw X3ZwdTk4MV9nZXRfb3JkZXJfaGludChjdHgsIAo+PiByZik7Cj4+ICvCoMKgwqDCoMKgwqDCoCBp ZHggPSBoYW50cm9fYXYxX2dldF9mcmFtZV9pbmRleChjdHgsIHJmKTsKPj4gK8KgwqDCoMKgwqDC oMKgIGlmIChpZHggIT0gQVYxX0lOVkFMSURfSURYKSB7Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIGludCByZl9vcmRlcl9oaW50ID0gaGFudHJvX2F2MV9nZXRfb3JkZXJfaGludChjdHgsIHJm KTsKPj4gwqAgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgY3VyX29mZnNldFtyZl0gPQo+PiAt wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX2dl dF9kaXN0KGN0eCwgCj4+IGN1cl9mcmFtZV9vZmZzZXQsIHJmX29yZGVyX2hpbnQpOwo+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGhhbnRyb19hdjFfZ2V0X2Rpc3QoY3R4LCBjdXJf ZnJhbWVfb2Zmc2V0LCAKPj4gcmZfb3JkZXJfaGludCk7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIGN1cl9yb2Zmc2V0W3JmXSA9Cj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZl9vcmRlcl9oaW50LCAK Pj4gY3VyX2ZyYW1lX29mZnNldCk7Cj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg aGFudHJvX2F2MV9nZXRfZGlzdChjdHgsIHJmX29yZGVyX2hpbnQsIAo+PiBjdXJfZnJhbWVfb2Zm c2V0KTsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIH0gZWxzZSB7Cj4+IMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIGN1cl9vZmZzZXRbcmZdID0gMDsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgY3VyX3JvZmZzZXRbcmZdID0gMDsKPj4gQEAgLTE3MzYsMzUgKzk2OCw0MSBAQCBzdGF0aWMg dm9pZCAKPj4gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfc2V0X290aGVyX2ZyYW1lcyhzdHJ1Y3Qg aGFudHJvX2N0eCAqY3R4KQo+PiDCoMKgwqDCoMKgIGlmICh1c2VfcmVmX2ZyYW1lX212cyAmJiBy ZWZfaW5kID4gMCAmJgo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgY3VyX29mZnNldFttZl90eXBlc1sw XSAtIFY0TDJfQVYxX1JFRl9MQVNUX0ZSQU1FXSA8PSAKPj4gTUFYX0ZSQU1FX0RJU1RBTkNFICYm Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBjdXJfb2Zmc2V0W21mX3R5cGVzWzBdIC0gVjRMMl9BVjFf UkVGX0xBU1RfRlJBTUVdID49IAo+PiAtTUFYX0ZSQU1FX0RJU1RBTkNFKSB7Cj4+IC3CoMKgwqDC oMKgwqDCoCBpbnQgcmYgPSByb2NrY2hpcF92cHU5ODFfZ2V0X29yZGVyX2hpbnQoY3R4LCByZWZz X3NlbGVjdGVkWzBdKTsKPj4gLcKgwqDCoMKgwqDCoMKgIGludCBpZHggPSByb2NrY2hpcF92cHU5 ODFfZ2V0X2ZyYW1lX2luZGV4KGN0eCwgCj4+IHJlZnNfc2VsZWN0ZWRbMF0pOwo+PiAtwqDCoMKg wqDCoMKgwqAgdTMyICpvaCA9IGF2MV9kZWMtPmZyYW1lX3JlZnNbaWR4XS5vcmRlcl9oaW50czsK Pj4gK8KgwqDCoMKgwqDCoMKgIGludCByZiA9IGhhbnRyb19hdjFfZ2V0X29yZGVyX2hpbnQoY3R4 LCByZWZzX3NlbGVjdGVkWzBdKTsKPj4gK8KgwqDCoMKgwqDCoMKgIGludCBpZHggPSBoYW50cm9f YXYxX2dldF9mcmFtZV9pbmRleChjdHgsIHJlZnNfc2VsZWN0ZWRbMF0pOwo+PiArwqDCoMKgwqDC oMKgwqAgdTMyICpvaDsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGludCB2YWw7Cj4+IMKgICvCoMKg wqDCoMKgwqDCoCBpZiAoaWR4ID09IEFWMV9JTlZBTElEX0lEWCkKPj4gK8KgwqDCoMKgwqDCoMKg wqDCoMKgwqAgZ290byBzZWNvbmRfcmVmOwo+PiArCj4+ICvCoMKgwqDCoMKgwqDCoCBvaCA9IGF2 MV9kZWMtPmZyYW1lX3JlZnNbaWR4XS5vcmRlcl9oaW50czsKPj4gKwo+PiDCoMKgwqDCoMKgwqDC oMKgwqAgaGFudHJvX3JlZ193cml0ZSh2cHUsICZhdjFfdXNlX3RlbXBvcmFsMF9tdnMsIDEpOwo+ PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rp c3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9MQVNUX0ZSQU1FXSk7Cj4+ICvCoMKgwqDC oMKgwqDCoCB2YWwgPSBoYW50cm9fYXYxX2dldF9kaXN0KGN0eCwgcmYsIAo+PiBvaFtWNEwyX0FW MV9SRUZfTEFTVF9GUkFNRV0pOwo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgaGFudHJvX3JlZ193cml0 ZSh2cHUsICZhdjFfbWYxX2xhc3Rfb2Zmc2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAg dmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0 TDJfQVYxX1JFRl9MQVNUMl9GUkFNRV0pOwo+PiArwqDCoMKgwqDCoMKgwqAgdmFsID0gaGFudHJv X2F2MV9nZXRfZGlzdChjdHgsIHJmLCAKPj4gb2hbVjRMMl9BVjFfUkVGX0xBU1QyX0ZSQU1FXSk7 Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9tZjFfbGFz dDJfb2Zmc2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1 OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9MQVNUM19G UkFNRV0pOwo+PiArwqDCoMKgwqDCoMKgwqAgdmFsID0gaGFudHJvX2F2MV9nZXRfZGlzdChjdHgs IHJmLCAKPj4gb2hbVjRMMl9BVjFfUkVGX0xBU1QzX0ZSQU1FXSk7Cj4+IMKgwqDCoMKgwqDCoMKg wqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9tZjFfbGFzdDNfb2Zmc2V0LCB2YWwpOwo+ PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rp c3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9HT0xERU5fRlJBTUVdKTsKPj4gK8KgwqDC oMKgwqDCoMKgIHZhbCA9IGhhbnRyb19hdjFfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJf QVYxX1JFRl9HT0xERU5fRlJBTUVdKTsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGhhbnRyb19yZWdf d3JpdGUodnB1LCAmYXYxX21mMV9nb2xkZW5fb2Zmc2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDC oMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+ IG9oW1Y0TDJfQVYxX1JFRl9CV0RSRUZfRlJBTUVdKTsKPj4gK8KgwqDCoMKgwqDCoMKgIHZhbCA9 IGhhbnRyb19hdjFfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9CV0RSRUZf RlJBTUVdKTsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGhhbnRyb19yZWdfd3JpdGUodnB1LCAmYXYx X21mMV9id2RyZWZfb2Zmc2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9j a2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JF Rl9BTFRSRUYyX0ZSQU1FXSk7Cj4+ICvCoMKgwqDCoMKgwqDCoCB2YWwgPSBoYW50cm9fYXYxX2dl dF9kaXN0KGN0eCwgcmYsIAo+PiBvaFtWNEwyX0FWMV9SRUZfQUxUUkVGMl9GUkFNRV0pOwo+PiDC oMKgwqDCoMKgwqDCoMKgwqAgaGFudHJvX3JlZ193cml0ZSh2cHUsICZhdjFfbWYxX2FsdHJlZjJf b2Zmc2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgx X2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9BTFRSRUZfRlJB TUVdKTsKPj4gK8KgwqDCoMKgwqDCoMKgIHZhbCA9IGhhbnRyb19hdjFfZ2V0X2Rpc3QoY3R4LCBy ZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9BTFRSRUZfRlJBTUVdKTsKPj4gwqDCoMKgwqDCoMKgwqDC oMKgIGhhbnRyb19yZWdfd3JpdGUodnB1LCAmYXYxX21mMV9hbHRyZWZfb2Zmc2V0LCB2YWwpOwo+ PiDCoMKgwqDCoMKgIH0KPj4gwqAgK3NlY29uZF9yZWY6Cj4+IMKgwqDCoMKgwqAgaGFudHJvX3Jl Z193cml0ZSh2cHUsICZhdjFfbWYyX2xhc3Rfb2Zmc2V0LCAwKTsKPj4gwqDCoMKgwqDCoCBoYW50 cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9tZjJfbGFzdDJfb2Zmc2V0LCAwKTsKPj4gwqDCoMKgwqDC oCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9tZjJfbGFzdDNfb2Zmc2V0LCAwKTsKPj4gQEAg LTE3NzYsMzUgKzEwMTQsNDEgQEAgc3RhdGljIHZvaWQgCj4+IHJvY2tjaGlwX3ZwdTk4MV9hdjFf ZGVjX3NldF9vdGhlcl9mcmFtZXMoc3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gwqDCoMKgwqDC oCBpZiAodXNlX3JlZl9mcmFtZV9tdnMgJiYgcmVmX2luZCA+IDEgJiYKPj4gwqDCoMKgwqDCoMKg wqDCoMKgIGN1cl9vZmZzZXRbbWZfdHlwZXNbMV0gLSBWNEwyX0FWMV9SRUZfTEFTVF9GUkFNRV0g PD0gCj4+IE1BWF9GUkFNRV9ESVNUQU5DRSAmJgo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgY3VyX29m ZnNldFttZl90eXBlc1sxXSAtIFY0TDJfQVYxX1JFRl9MQVNUX0ZSQU1FXSA+PSAKPj4gLU1BWF9G UkFNRV9ESVNUQU5DRSkgewo+PiAtwqDCoMKgwqDCoMKgwqAgaW50IHJmID0gcm9ja2NoaXBfdnB1 OTgxX2dldF9vcmRlcl9oaW50KGN0eCwgcmVmc19zZWxlY3RlZFsxXSk7Cj4+IC3CoMKgwqDCoMKg wqDCoCBpbnQgaWR4ID0gcm9ja2NoaXBfdnB1OTgxX2dldF9mcmFtZV9pbmRleChjdHgsIAo+PiBy ZWZzX3NlbGVjdGVkWzFdKTsKPj4gLcKgwqDCoMKgwqDCoMKgIHUzMiAqb2ggPSBhdjFfZGVjLT5m cmFtZV9yZWZzW2lkeF0ub3JkZXJfaGludHM7Cj4+ICvCoMKgwqDCoMKgwqDCoCBpbnQgcmYgPSBo YW50cm9fYXYxX2dldF9vcmRlcl9oaW50KGN0eCwgcmVmc19zZWxlY3RlZFsxXSk7Cj4+ICvCoMKg wqDCoMKgwqDCoCBpbnQgaWR4ID0gaGFudHJvX2F2MV9nZXRfZnJhbWVfaW5kZXgoY3R4LCByZWZz X3NlbGVjdGVkWzFdKTsKPj4gK8KgwqDCoMKgwqDCoMKgIHUzMiAqb2g7Cj4+IMKgwqDCoMKgwqDC oMKgwqDCoCBpbnQgdmFsOwo+PiDCoCArwqDCoMKgwqDCoMKgwqAgaWYgKGlkeCA9PSBBVjFfSU5W QUxJRF9JRFgpCj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGdvdG8gdGhpcmRfcmVmOwo+PiAr Cj4+ICvCoMKgwqDCoMKgwqDCoCBvaCA9IGF2MV9kZWMtPmZyYW1lX3JlZnNbaWR4XS5vcmRlcl9o aW50czsKPj4gKwo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgaGFudHJvX3JlZ193cml0ZSh2cHUsICZh djFfdXNlX3RlbXBvcmFsMV9tdnMsIDEpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9j a2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JF Rl9MQVNUX0ZSQU1FXSk7Cj4+ICvCoMKgwqDCoMKgwqDCoCB2YWwgPSBoYW50cm9fYXYxX2dldF9k aXN0KGN0eCwgcmYsIAo+PiBvaFtWNEwyX0FWMV9SRUZfTEFTVF9GUkFNRV0pOwo+PiDCoMKgwqDC oMKgwqDCoMKgwqAgaGFudHJvX3JlZ193cml0ZSh2cHUsICZhdjFfbWYyX2xhc3Rfb2Zmc2V0LCB2 YWwpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNf Z2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9MQVNUMl9GUkFNRV0pOwo+PiAr wqDCoMKgwqDCoMKgwqAgdmFsID0gaGFudHJvX2F2MV9nZXRfZGlzdChjdHgsIHJmLCAKPj4gb2hb VjRMMl9BVjFfUkVGX0xBU1QyX0ZSQU1FXSk7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBoYW50cm9f cmVnX3dyaXRlKHZwdSwgJmF2MV9tZjJfbGFzdDJfb2Zmc2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKg wqDCoMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwg Cj4+IG9oW1Y0TDJfQVYxX1JFRl9MQVNUM19GUkFNRV0pOwo+PiArwqDCoMKgwqDCoMKgwqAgdmFs ID0gaGFudHJvX2F2MV9nZXRfZGlzdChjdHgsIHJmLCAKPj4gb2hbVjRMMl9BVjFfUkVGX0xBU1Qz X0ZSQU1FXSk7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2 MV9tZjJfbGFzdDNfb2Zmc2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9j a2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JF Rl9HT0xERU5fRlJBTUVdKTsKPj4gK8KgwqDCoMKgwqDCoMKgIHZhbCA9IGhhbnRyb19hdjFfZ2V0 X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9HT0xERU5fRlJBTUVdKTsKPj4gwqDC oMKgwqDCoMKgwqDCoMKgIGhhbnRyb19yZWdfd3JpdGUodnB1LCAmYXYxX21mMl9nb2xkZW5fb2Zm c2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2 MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9CV0RSRUZfRlJBTUVd KTsKPj4gK8KgwqDCoMKgwqDCoMKgIHZhbCA9IGhhbnRyb19hdjFfZ2V0X2Rpc3QoY3R4LCByZiwg Cj4+IG9oW1Y0TDJfQVYxX1JFRl9CV0RSRUZfRlJBTUVdKTsKPj4gwqDCoMKgwqDCoMKgwqDCoMKg IGhhbnRyb19yZWdfd3JpdGUodnB1LCAmYXYxX21mMl9id2RyZWZfb2Zmc2V0LCB2YWwpOwo+PiDC oCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3Qo Y3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9BTFRSRUYyX0ZSQU1FXSk7Cj4+ICvCoMKgwqDC oMKgwqDCoCB2YWwgPSBoYW50cm9fYXYxX2dldF9kaXN0KGN0eCwgcmYsIAo+PiBvaFtWNEwyX0FW MV9SRUZfQUxUUkVGMl9GUkFNRV0pOwo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgaGFudHJvX3JlZ193 cml0ZSh2cHUsICZhdjFfbWYyX2FsdHJlZjJfb2Zmc2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDC oMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+ IG9oW1Y0TDJfQVYxX1JFRl9BTFRSRUZfRlJBTUVdKTsKPj4gK8KgwqDCoMKgwqDCoMKgIHZhbCA9 IGhhbnRyb19hdjFfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9BTFRSRUZf RlJBTUVdKTsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGhhbnRyb19yZWdfd3JpdGUodnB1LCAmYXYx X21mMl9hbHRyZWZfb2Zmc2V0LCB2YWwpOwo+PiDCoMKgwqDCoMKgIH0KPj4gwqAgK3RoaXJkX3Jl ZjoKPj4gwqDCoMKgwqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9tZjNfbGFzdF9vZmZz ZXQsIDApOwo+PiDCoMKgwqDCoMKgIGhhbnRyb19yZWdfd3JpdGUodnB1LCAmYXYxX21mM19sYXN0 Ml9vZmZzZXQsIDApOwo+PiDCoMKgwqDCoMKgIGhhbnRyb19yZWdfd3JpdGUodnB1LCAmYXYxX21m M19sYXN0M19vZmZzZXQsIDApOwo+PiBAQCAtMTgxNiwzNSArMTA2MCw0MSBAQCBzdGF0aWMgdm9p ZCAKPj4gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfc2V0X290aGVyX2ZyYW1lcyhzdHJ1Y3QgaGFu dHJvX2N0eCAqY3R4KQo+PiDCoMKgwqDCoMKgIGlmICh1c2VfcmVmX2ZyYW1lX212cyAmJiByZWZf aW5kID4gMiAmJgo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgY3VyX29mZnNldFttZl90eXBlc1syXSAt IFY0TDJfQVYxX1JFRl9MQVNUX0ZSQU1FXSA8PSAKPj4gTUFYX0ZSQU1FX0RJU1RBTkNFICYmCj4+ IMKgwqDCoMKgwqDCoMKgwqDCoCBjdXJfb2Zmc2V0W21mX3R5cGVzWzJdIC0gVjRMMl9BVjFfUkVG X0xBU1RfRlJBTUVdID49IAo+PiAtTUFYX0ZSQU1FX0RJU1RBTkNFKSB7Cj4+IC3CoMKgwqDCoMKg wqDCoCBpbnQgcmYgPSByb2NrY2hpcF92cHU5ODFfZ2V0X29yZGVyX2hpbnQoY3R4LCByZWZzX3Nl bGVjdGVkWzJdKTsKPj4gLcKgwqDCoMKgwqDCoMKgIGludCBpZHggPSByb2NrY2hpcF92cHU5ODFf Z2V0X2ZyYW1lX2luZGV4KGN0eCwgCj4+IHJlZnNfc2VsZWN0ZWRbMl0pOwo+PiAtwqDCoMKgwqDC oMKgwqAgdTMyICpvaCA9IGF2MV9kZWMtPmZyYW1lX3JlZnNbaWR4XS5vcmRlcl9oaW50czsKPj4g K8KgwqDCoMKgwqDCoMKgIGludCByZiA9IGhhbnRyb19hdjFfZ2V0X29yZGVyX2hpbnQoY3R4LCBy ZWZzX3NlbGVjdGVkWzJdKTsKPj4gK8KgwqDCoMKgwqDCoMKgIGludCBpZHggPSBoYW50cm9fYXYx X2dldF9mcmFtZV9pbmRleChjdHgsIHJlZnNfc2VsZWN0ZWRbMl0pOwo+PiArwqDCoMKgwqDCoMKg wqAgdTMyICpvaDsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGludCB2YWw7Cj4+IMKgICvCoMKgwqDC oMKgwqDCoCBpZiAoaWR4ID09IEFWMV9JTlZBTElEX0lEWCkKPj4gK8KgwqDCoMKgwqDCoMKgwqDC oMKgwqAgZ290byBvZmZzZXRzOwo+PiArCj4+ICvCoMKgwqDCoMKgwqDCoCBvaCA9IGF2MV9kZWMt PmZyYW1lX3JlZnNbaWR4XS5vcmRlcl9oaW50czsKPj4gKwo+PiDCoMKgwqDCoMKgwqDCoMKgwqAg aGFudHJvX3JlZ193cml0ZSh2cHUsICZhdjFfdXNlX3RlbXBvcmFsMl9tdnMsIDEpOwo+PiDCoCAt wqDCoMKgwqDCoMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4 LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9MQVNUX0ZSQU1FXSk7Cj4+ICvCoMKgwqDCoMKgwqDC oCB2YWwgPSBoYW50cm9fYXYxX2dldF9kaXN0KGN0eCwgcmYsIAo+PiBvaFtWNEwyX0FWMV9SRUZf TEFTVF9GUkFNRV0pOwo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgaGFudHJvX3JlZ193cml0ZSh2cHUs ICZhdjFfbWYzX2xhc3Rfb2Zmc2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0g cm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYx X1JFRl9MQVNUMl9GUkFNRV0pOwo+PiArwqDCoMKgwqDCoMKgwqAgdmFsID0gaGFudHJvX2F2MV9n ZXRfZGlzdChjdHgsIHJmLCAKPj4gb2hbVjRMMl9BVjFfUkVGX0xBU1QyX0ZSQU1FXSk7Cj4+IMKg wqDCoMKgwqDCoMKgwqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9tZjNfbGFzdDJfb2Zm c2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2 MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9MQVNUM19GUkFNRV0p Owo+PiArwqDCoMKgwqDCoMKgwqAgdmFsID0gaGFudHJvX2F2MV9nZXRfZGlzdChjdHgsIHJmLCAK Pj4gb2hbVjRMMl9BVjFfUkVGX0xBU1QzX0ZSQU1FXSk7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBo YW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9tZjNfbGFzdDNfb2Zmc2V0LCB2YWwpOwo+PiDCoCAt wqDCoMKgwqDCoMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4 LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9HT0xERU5fRlJBTUVdKTsKPj4gK8KgwqDCoMKgwqDC oMKgIHZhbCA9IGhhbnRyb19hdjFfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JF Rl9HT0xERU5fRlJBTUVdKTsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGhhbnRyb19yZWdfd3JpdGUo dnB1LCAmYXYxX21mM19nb2xkZW5fb2Zmc2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAg dmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0 TDJfQVYxX1JFRl9CV0RSRUZfRlJBTUVdKTsKPj4gK8KgwqDCoMKgwqDCoMKgIHZhbCA9IGhhbnRy b19hdjFfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9CV0RSRUZfRlJBTUVd KTsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGhhbnRyb19yZWdfd3JpdGUodnB1LCAmYXYxX21mM19i d2RyZWZfb2Zmc2V0LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9ja2NoaXBf dnB1OTgxX2F2MV9kZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9BTFRS RUYyX0ZSQU1FXSk7Cj4+ICvCoMKgwqDCoMKgwqDCoCB2YWwgPSBoYW50cm9fYXYxX2dldF9kaXN0 KGN0eCwgcmYsIAo+PiBvaFtWNEwyX0FWMV9SRUZfQUxUUkVGMl9GUkFNRV0pOwo+PiDCoMKgwqDC oMKgwqDCoMKgwqAgaGFudHJvX3JlZ193cml0ZSh2cHUsICZhdjFfbWYzX2FsdHJlZjJfb2Zmc2V0 LCB2YWwpOwo+PiDCoCAtwqDCoMKgwqDCoMKgwqAgdmFsID0gcm9ja2NoaXBfdnB1OTgxX2F2MV9k ZWNfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+IG9oW1Y0TDJfQVYxX1JFRl9BTFRSRUZfRlJBTUVdKTsK Pj4gK8KgwqDCoMKgwqDCoMKgIHZhbCA9IGhhbnRyb19hdjFfZ2V0X2Rpc3QoY3R4LCByZiwgCj4+ IG9oW1Y0TDJfQVYxX1JFRl9BTFRSRUZfRlJBTUVdKTsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGhh bnRyb19yZWdfd3JpdGUodnB1LCAmYXYxX21mM19hbHRyZWZfb2Zmc2V0LCB2YWwpOwo+PiDCoMKg wqDCoMKgIH0KPj4gwqAgK29mZnNldHM6Cj4+IMKgwqDCoMKgwqAgaGFudHJvX3JlZ193cml0ZSh2 cHUsICZhdjFfY3VyX2xhc3Rfb2Zmc2V0LCBjdXJfb2Zmc2V0WzBdKTsKPj4gwqDCoMKgwqDCoCBo YW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9jdXJfbGFzdDJfb2Zmc2V0LCBjdXJfb2Zmc2V0WzFd KTsKPj4gwqDCoMKgwqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9jdXJfbGFzdDNfb2Zm c2V0LCBjdXJfb2Zmc2V0WzJdKTsKPj4gQEAgLTE4ODMsOSArMTEzMyw5IEBAIHN0YXRpYyB2b2lk IAo+PiByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19zZXRfcmVmZXJlbmNlX2ZyYW1lcyhzdHJ1Y3Qg aGFudHJvX2N0eCAqY3R4KQo+PiDCoCDCoMKgwqDCoMKgIGlmICghYWxsb3dfaW50cmFiYykgewo+ PiDCoMKgwqDCoMKgwqDCoMKgwqAgZm9yIChpID0gMDsgaSA8IFY0TDJfQVYxX1JFRlNfUEVSX0ZS QU1FOyBpKyspIHsKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaW50IGlkeCA9IHJvY2tjaGlw X3ZwdTk4MV9nZXRfZnJhbWVfaW5kZXgoY3R4LCBpKTsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKg wqAgaW50IGlkeCA9IGhhbnRyb19hdjFfZ2V0X2ZyYW1lX2luZGV4KGN0eCwgaSk7Cj4+IMKgIC3C oMKgwqDCoMKgwqDCoMKgwqDCoMKgIGlmIChpZHggPj0gMCkKPj4gK8KgwqDCoMKgwqDCoMKgwqDC oMKgwqAgaWYgKGlkeCAhPSBBVjFfSU5WQUxJRF9JRFgpCj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgcmVmX2NvdW50W2lkeF0rKzsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIH0K Pj4gwqAgQEAgLTE4OTgsNyArMTE0OCw3IEBAIHN0YXRpYyB2b2lkIAo+PiByb2NrY2hpcF92cHU5 ODFfYXYxX2RlY19zZXRfcmVmZXJlbmNlX2ZyYW1lcyhzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4KQo+ PiDCoMKgwqDCoMKgIH0KPj4gwqDCoMKgwqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9y ZWZfZnJhbWVzLCByZWZfZnJhbWVzKTsKPj4gwqAgLcKgwqDCoCByb2NrY2hpcF92cHU5ODFfYXYx X2RlY19zZXRfZnJhbWVfc2lnbl9iaWFzKGN0eCk7Cj4+ICvCoMKgwqAgaGFudHJvX2F2MV9zZXRf ZnJhbWVfc2lnbl9iaWFzKGN0eCk7Cj4+IMKgIMKgwqDCoMKgwqAgZm9yIChpID0gVjRMMl9BVjFf UkVGX0xBU1RfRlJBTUU7IGkgPCAKPj4gVjRMMl9BVjFfVE9UQUxfUkVGU19QRVJfRlJBTUU7IGkr Kykgewo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgdTMyIHJlZiA9IGkgLSAxOwo+PiBAQCAtMTkxMCw4 ICsxMTYwLDggQEAgc3RhdGljIHZvaWQgCj4+IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX3NldF9y ZWZlcmVuY2VfZnJhbWVzKHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpCj4+IMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIHdpZHRoID0gZnJhbWUtPmZyYW1lX3dpZHRoX21pbnVzXzEgKyAxOwo+PiDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBoZWlnaHQgPSBmcmFtZS0+ZnJhbWVfaGVpZ2h0X21p bnVzXzEgKyAxOwo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgfSBlbHNlIHsKPj4gLcKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgaWYgKHJvY2tjaGlwX3ZwdTk4MV9nZXRfZnJhbWVfaW5kZXgoY3R4LCByZWYp ID4gMCkKPj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBpZHggPSByb2NrY2hpcF92 cHU5ODFfZ2V0X2ZyYW1lX2luZGV4KGN0eCwgcmVmKTsKPj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKg wqAgaWYgKGhhbnRyb19hdjFfZ2V0X2ZyYW1lX2luZGV4KGN0eCwgcmVmKSAhPSAKPj4gQVYxX0lO VkFMSURfSURYKQo+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGlkeCA9IGhhbnRy b19hdjFfZ2V0X2ZyYW1lX2luZGV4KGN0eCwgcmVmKTsKPj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgd2lkdGggPSBhdjFfZGVjLT5mcmFtZV9yZWZzW2lkeF0ud2lkdGg7Cj4+IMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIGhlaWdodCA9IGF2MV9kZWMtPmZyYW1lX3JlZnNbaWR4XS5oZWln aHQ7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCB9Cj4+IEBAIC0xOTQzLDIwICsxMTkzLDYgQEAgc3Rh dGljIHZvaWQgCj4+IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX3NldF9yZWZlcmVuY2VfZnJhbWVz KHN0cnVjdCBoYW50cm9fY3R4ICpjdHgpCj4+IMKgwqDCoMKgwqAgcm9ja2NoaXBfdnB1OTgxX2F2 MV9kZWNfc2V0X290aGVyX2ZyYW1lcyhjdHgpOwo+PiDCoCB9Cj4+IMKgIC1zdGF0aWMgaW50IHJv Y2tjaGlwX3ZwdTk4MV9hdjFfZ2V0X2hhcmR3YXJlX3R4X21vZGUoZW51bSAKPj4gdjRsMl9hdjFf dHhfbW9kZSB0eF9tb2RlKQo+PiAtewo+PiAtwqDCoMKgIHN3aXRjaCAodHhfbW9kZSkgewo+PiAt wqDCoMKgIGNhc2UgVjRMMl9BVjFfVFhfTU9ERV9PTkxZXzRYNDoKPj4gLcKgwqDCoMKgwqDCoMKg IHJldHVybiBST0NLQ0hJUF9BVjFfVFhfTU9ERV9PTkxZXzRYNDsKPj4gLcKgwqDCoCBjYXNlIFY0 TDJfQVYxX1RYX01PREVfTEFSR0VTVDoKPj4gLcKgwqDCoMKgwqDCoMKgIHJldHVybiBST0NLQ0hJ UF9BVjFfVFhfTU9ERV8zMngzMjsKPj4gLcKgwqDCoCBjYXNlIFY0TDJfQVYxX1RYX01PREVfU0VM RUNUOgo+PiAtwqDCoMKgwqDCoMKgwqAgcmV0dXJuIFJPQ0tDSElQX0FWMV9UWF9NT0RFX1NFTEVD VDsKPj4gLcKgwqDCoCB9Cj4+IC0KPj4gLcKgwqDCoCByZXR1cm4gUk9DS0NISVBfQVYxX1RYX01P REVfMzJ4MzI7Cj4+IC19Cj4+IC0KPj4gwqAgc3RhdGljIHZvaWQgcm9ja2NoaXBfdnB1OTgxX2F2 MV9kZWNfc2V0X3BhcmFtZXRlcnMoc3RydWN0IAo+PiBoYW50cm9fY3R4ICpjdHgpCj4+IMKgIHsK Pj4gwqDCoMKgwqDCoCBzdHJ1Y3QgaGFudHJvX2RldiAqdnB1ID0gY3R4LT5kZXY7Cj4+IEBAIC0y MDI5LDcgKzEyNjUsNyBAQCBzdGF0aWMgdm9pZCAKPj4gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNf c2V0X3BhcmFtZXRlcnMoc3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gwqDCoMKgwqDCoCBoYW50 cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9jb21wX3ByZWRfbW9kZSwKPj4gwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCAoY3RybHMtPmZyYW1lLT5mbGFncyAmIAo+PiBWNEwyX0FWMV9GUkFNRV9G TEFHX1JFRkVSRU5DRV9TRUxFQ1QpID8gMiA6IDApOwo+PiDCoCAtwqDCoMKgIHR4X21vZGUgPSAK Pj4gcm9ja2NoaXBfdnB1OTgxX2F2MV9nZXRfaGFyZHdhcmVfdHhfbW9kZShjdHJscy0+ZnJhbWUt PnR4X21vZGUpOwo+PiArwqDCoMKgIHR4X21vZGUgPSBoYW50cm9fYXYxX2dldF9oYXJkd2FyZV90 eF9tb2RlKGN0cmxzLT5mcmFtZS0+dHhfbW9kZSk7Cj4+IMKgwqDCoMKgwqAgaGFudHJvX3JlZ193 cml0ZSh2cHUsICZhdjFfdHJhbnNmb3JtX21vZGUsIHR4X21vZGUpOwo+PiDCoMKgwqDCoMKgIGhh bnRyb19yZWdfd3JpdGUodnB1LCAmYXYxX21heF9jYl9zaXplLAo+PiDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIChjdHJscy0+c2VxdWVuY2UtPmZsYWdzCj4+IEBAIC0yMDYxLDcgKzEyOTcs NyBAQCBzdGF0aWMgdm9pZCAKPj4gcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfc2V0X3BhcmFtZXRl cnMoc3RydWN0IGhhbnRyb19jdHggKmN0eCkKPj4gwqDCoMKgwqDCoMKgwqDCoMKgIGhhbnRyb19y ZWdfd3JpdGUodnB1LCAmYXYxX3FtbGV2ZWxfdiwgMHhmZik7Cj4+IMKgwqDCoMKgwqAgfQo+PiDC oCAtwqDCoMKgIGhhbnRyb19yZWdfd3JpdGUodnB1LCAmYXYxX2xvc3NsZXNzX2UsIAo+PiByb2Nr Y2hpcF92cHU5ODFfYXYxX2RlY19pc19sb3NzbGVzcyhjdHgpKTsKPj4gK8KgwqDCoCBoYW50cm9f cmVnX3dyaXRlKHZwdSwgJmF2MV9sb3NzbGVzc19lLCAKPj4gaGFudHJvX2F2MV9pc19sb3NzbGVz cyhjdHgpKTsKPj4gwqDCoMKgwqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9xdWFudF9k ZWx0YV92X2RjLCAKPj4gY3RybHMtPmZyYW1lLT5xdWFudGl6YXRpb24uZGVsdGFfcV92X2RjKTsK Pj4gwqDCoMKgwqDCoCBoYW50cm9fcmVnX3dyaXRlKHZwdSwgJmF2MV9xdWFudF9kZWx0YV92X2Fj LCAKPj4gY3RybHMtPmZyYW1lLT5xdWFudGl6YXRpb24uZGVsdGFfcV92X2FjKTsKPj4gwqAgQEAg LTIxMDksOCArMTM0NSw4IEBAIAo+PiByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19zZXRfb3V0cHV0 X2J1ZmZlcihzdHJ1Y3QgaGFudHJvX2N0eCAqY3R4KQo+PiDCoMKgwqDCoMKgIHN0cnVjdCBoYW50 cm9fZGVjb2RlZF9idWZmZXIgKmRzdDsKPj4gwqDCoMKgwqDCoCBzdHJ1Y3QgdmIyX3Y0bDJfYnVm ZmVyICp2YjJfZHN0Owo+PiDCoMKgwqDCoMKgIGRtYV9hZGRyX3QgbHVtYV9hZGRyLCBjaHJvbWFf YWRkciwgbXZfYWRkciA9IDA7Cj4+IC3CoMKgwqAgc2l6ZV90IGNyX29mZnNldCA9IHJvY2tjaGlw X3ZwdTk4MV9hdjFfZGVjX2x1bWFfc2l6ZShjdHgpOwo+PiAtwqDCoMKgIHNpemVfdCBtdl9vZmZz ZXQgPSByb2NrY2hpcF92cHU5ODFfYXYxX2RlY19jaHJvbWFfc2l6ZShjdHgpOwo+PiArwqDCoMKg IHNpemVfdCBjcl9vZmZzZXQgPSBoYW50cm9fYXYxX2x1bWFfc2l6ZShjdHgpOwo+PiArwqDCoMKg IHNpemVfdCBtdl9vZmZzZXQgPSBoYW50cm9fYXYxX2Nocm9tYV9zaXplKGN0eCk7Cj4+IMKgIMKg wqDCoMKgwqAgdmIyX2RzdCA9IAo+PiBhdjFfZGVjLT5mcmFtZV9yZWZzW2F2MV9kZWMtPmN1cnJl bnRfZnJhbWVfaW5kZXhdLnZiMl9yZWY7Cj4+IMKgwqDCoMKgwqAgZHN0ID0gdmIyX3RvX2hhbnRy b19kZWNvZGVkX2J1ZigmdmIyX2RzdC0+dmIyX2J1Zik7Cj4+IEBAIC0yMTM0LDcgKzEzNzAsNyBA QCBpbnQgcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfcnVuKHN0cnVjdCAKPj4gaGFudHJvX2N0eCAq Y3R4KQo+PiDCoCDCoMKgwqDCoMKgIGhhbnRyb19zdGFydF9wcmVwYXJlX3J1bihjdHgpOwo+PiDC oCAtwqDCoMKgIHJldCA9IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX3ByZXBhcmVfcnVuKGN0eCk7 Cj4+ICvCoMKgwqAgcmV0ID0gaGFudHJvX2F2MV9wcmVwYXJlX3J1bihjdHgpOwo+PiDCoMKgwqDC oMKgIGlmIChyZXQpCj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBnb3RvIHByZXBhcmVfZXJyb3I7Cj4+ IMKgIEBAIC0yMTQ0LDggKzEzODAsOCBAQCBpbnQgcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfcnVu KHN0cnVjdCAKPj4gaGFudHJvX2N0eCAqY3R4KQo+PiDCoMKgwqDCoMKgwqDCoMKgwqAgZ290byBw cmVwYXJlX2Vycm9yOwo+PiDCoMKgwqDCoMKgIH0KPj4gwqAgLcKgwqDCoCByb2NrY2hpcF92cHU5 ODFfYXYxX2RlY19jbGVhbl9yZWZzKGN0eCk7Cj4+IC3CoMKgwqAgcm9ja2NoaXBfdnB1OTgxX2F2 MV9kZWNfZnJhbWVfcmVmKGN0eCwgdmIyX3NyYy0+dmIyX2J1Zi50aW1lc3RhbXApOwo+PiArwqDC oMKgIGhhbnRyb19hdjFfY2xlYW5fcmVmcyhjdHgpOwo+PiArwqDCoMKgIGhhbnRyb19hdjFfZnJh bWVfcmVmKGN0eCwgdmIyX3NyYy0+dmIyX2J1Zi50aW1lc3RhbXApOwo+PiDCoCDCoMKgwqDCoMKg IHJvY2tjaGlwX3ZwdTk4MV9hdjFfZGVjX3NldF9wYXJhbWV0ZXJzKGN0eCk7Cj4+IMKgwqDCoMKg wqAgcm9ja2NoaXBfdnB1OTgxX2F2MV9kZWNfc2V0X2dsb2JhbF9tb2RlbChjdHgpOwo+PiBkaWZm IC0tZ2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS92ZXJpc2lsaWNvbi9yb2NrY2hpcF92cHVf aHcuYyAKPj4gYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL3JvY2tjaGlwX3Zw dV9ody5jCj4+IGluZGV4IDAyNjczYmU5ODc4ZS4uZjUwYTNlMzgwOTdlIDEwMDY0NAo+PiAtLS0g YS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL3ZlcmlzaWxpY29uL3JvY2tjaGlwX3ZwdV9ody5jCj4+ ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vdmVyaXNpbGljb24vcm9ja2NoaXBfdnB1X2h3 LmMKPj4gQEAgLTksNiArOSw3IEBACj4+IMKgICNpbmNsdWRlIDxsaW51eC9jbGsuaD4KPj4gwqAg wqAgI2luY2x1ZGUgImhhbnRyby5oIgo+PiArI2luY2x1ZGUgImhhbnRyb19hdjEuaCIKPj4gwqAg I2luY2x1ZGUgImhhbnRyb19qcGVnLmgiCj4+IMKgICNpbmNsdWRlICJoYW50cm9fZzFfcmVncy5o Igo+PiDCoCAjaW5jbHVkZSAiaGFudHJvX2gxX3JlZ3MuaCIKPj4gQEAgLTYwOCw5ICs2MDksOSBA QCBzdGF0aWMgY29uc3Qgc3RydWN0IGhhbnRyb19jb2RlY19vcHMgCj4+IHJrMzU2OF92ZXB1X2Nv ZGVjX29wc1tdID0gewo+PiDCoCBzdGF0aWMgY29uc3Qgc3RydWN0IGhhbnRyb19jb2RlY19vcHMg cmszNTg4X3ZwdTk4MV9jb2RlY19vcHNbXSA9IHsKPj4gwqDCoMKgwqDCoCBbSEFOVFJPX01PREVf QVYxX0RFQ10gPSB7Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoCAucnVuID0gcm9ja2NoaXBfdnB1OTgx X2F2MV9kZWNfcnVuLAo+PiAtwqDCoMKgwqDCoMKgwqAgLmluaXQgPSByb2NrY2hpcF92cHU5ODFf YXYxX2RlY19pbml0LAo+PiAtwqDCoMKgwqDCoMKgwqAgLmV4aXQgPSByb2NrY2hpcF92cHU5ODFf YXYxX2RlY19leGl0LAo+PiAtwqDCoMKgwqDCoMKgwqAgLmRvbmUgPSByb2NrY2hpcF92cHU5ODFf YXYxX2RlY19kb25lLAo+PiArwqDCoMKgwqDCoMKgwqAgLmluaXQgPSBoYW50cm9fYXYxX2luaXQs Cj4+ICvCoMKgwqDCoMKgwqDCoCAuZXhpdCA9IGhhbnRyb19hdjFfZXhpdCwKPj4gK8KgwqDCoMKg wqDCoMKgIC5kb25lID0gaGFudHJvX2F2MV91cGRhdGVfcHJvYiwKPj4gwqDCoMKgwqDCoCB9LAo+ PiDCoCB9Owo+PiDCoCAvKgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX18KTGludXgtcm9ja2NoaXAgbWFpbGluZyBsaXN0CkxpbnV4LXJvY2tjaGlwQGxpc3Rz LmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5m by9saW51eC1yb2NrY2hpcAo=