DPDK patches and discussions
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download: 
* Re: [PATCH] net/tap: allow more that 4 queues
  2024-02-29 17:56  3% [PATCH] net/tap: allow more that 4 queues Stephen Hemminger
@ 2024-03-06 16:14  0% ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2024-03-06 16:14 UTC (permalink / raw)
  To: Stephen Hemminger, dev

On 2/29/2024 5:56 PM, Stephen Hemminger wrote:
> The tap device needs to exchange file descriptors for tx and rx.
> But the EAL MP layer has limit of 8 file descriptors per message.
> The ideal resolution would be to increase the number of file
> descriptors allowed for rte_mp_sendmsg(), but this would break
> the ABI. Workaround the constraint by breaking into multiple messages.
> 
> Do not hide errors about MP message failures.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  drivers/net/tap/rte_eth_tap.c | 40 +++++++++++++++++++++++++++++------
>  1 file changed, 33 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
> index 69d9da695bed..df18c328f498 100644
> --- a/drivers/net/tap/rte_eth_tap.c
> +++ b/drivers/net/tap/rte_eth_tap.c
> @@ -863,21 +863,44 @@ tap_mp_req_on_rxtx(struct rte_eth_dev *dev)
>  		msg.fds[fd_iterator++] = process_private->txq_fds[i];
>  		msg.num_fds++;
>  		request_param->txq_count++;
> +
> +		/* Need to break request into chunks */
> +		if (fd_iterator >= RTE_MP_MAX_FD_NUM) {
> +			err = rte_mp_sendmsg(&msg);
> +			if (err < 0)
> +				goto fail;
> +
> +			fd_iterator = 0;
> +			msg.num_fds = 0;
> +			request_param->txq_count = 0;
> +		}
>  	}
>  	for (i = 0; i < dev->data->nb_rx_queues; i++) {
>  		msg.fds[fd_iterator++] = process_private->rxq_fds[i];
>  		msg.num_fds++;
>  		request_param->rxq_count++;
> +
> +		if (fd_iterator >= RTE_MP_MAX_FD_NUM) {
> +			err = rte_mp_sendmsg(&msg);
> +			if (err < 0)
> +				goto fail;
> +
> +			fd_iterator = 0;
> +			msg.num_fds = 0;
> +			request_param->rxq_count = 0;
> +		}
>  	}

Hi Stephen,

Did you able to verify with more than 4 queues?

As far as I can see, in the secondary counterpart of the
'rte_mp_sendmsg()', each time secondary index starts from 0, and
subsequent calls overwrites the fds in secondary.
So practically still only 4 queues works.

^ permalink raw reply	[relevance 0%]

* RE: [EXTERNAL] [PATCH v5 1/4] crypto/ipsec_mb: bump minimum IPsec Multi-buffer version
  @ 2024-03-06 11:12  4%     ` Power, Ciara
  0 siblings, 0 replies; 200+ results
From: Power, Ciara @ 2024-03-06 11:12 UTC (permalink / raw)
  To: Akhil Goyal, Dooley, Brian, Ji, Kai, De Lara Guarch, Pablo,
	Patrick Robb, Aaron Conole
  Cc: dev, Sivaramakrishnan, VenkatX, Wathsala Vithanage, thomas,
	Marchand, David



> -----Original Message-----
> From: Akhil Goyal <gakhil@marvell.com>
> Sent: Tuesday, March 5, 2024 7:12 PM
> To: Dooley, Brian <brian.dooley@intel.com>; Ji, Kai <kai.ji@intel.com>; De Lara
> Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Patrick Robb
> <probb@iol.unh.edu>; Aaron Conole <aconole@redhat.com>
> Cc: dev@dpdk.org; Sivaramakrishnan, VenkatX
> <venkatx.sivaramakrishnan@intel.com>; Power, Ciara <ciara.power@intel.com>;
> Wathsala Vithanage <wathsala.vithanage@arm.com>; thomas@monjalon.net;
> Marchand, David <david.marchand@redhat.com>
> Subject: RE: [EXTERNAL] [PATCH v5 1/4] crypto/ipsec_mb: bump minimum IPsec
> Multi-buffer version
> 
> > Subject: [EXTERNAL] [PATCH v5 1/4] crypto/ipsec_mb: bump minimum IPsec
> > Multi-buffer version
> >
> > From: Sivaramakrishnan Venkat <venkatx.sivaramakrishnan@intel.com>
> >
> > SW PMDs increment IPsec Multi-buffer version to 1.4.
> > A minimum IPsec Multi-buffer version of 1.4 or greater is now required.
> >
> > Signed-off-by: Sivaramakrishnan Venkat
> > <venkatx.sivaramakrishnan@intel.com>
> > Acked-by: Ciara Power <ciara.power@intel.com>
> > Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> > Acked-by: Wathsala Vithanage <wathsala.vithanage@arm.com>
> please check these:
> https://github.com/ovsrobot/dpdk/actions/runs/8160942783/job/223086396
> 70#step:19:19411
> Error: cannot find librte_crypto_ipsec_mb.so.24.0 in install You need to get this
> fixed or else CI would fail for every patch once this series is applied.

I am having trouble reproducing this one.
I have run these commands that I saw in the CI log, before the patches, and then after the patches are applied - with ipsec-mb v1.2 on system as in CI.

meson configure  build -Denable_docs=true -Dexamples=all -Dplatform=generic -Ddefault_library=shared -Dbuildtype=debug -Dcheck_includes=true  -Dlibdir=lib -Dwerror=true
meson install -C build
ninja -C build

It compiles ok both times, first time it compiles ipsec-mb PMDs, after the patches applied, it skips compiling the PMDs as expected.

I am wondering, could this error be to do with the ABI reference/install comparison?
Maybe reference has the ipsec_mb.so file from a build that supported it, and it can't find the equivalent in the new install, because it's not compiled anymore:
+ devtools/check-abi.sh reference install
Error: cannot find librte_crypto_ipsec_mb.so.24.0 in install

Aaron, could that be the case?
Or, maybe my steps to reproduce the build setup are incorrect?


> And this is also failing http://mails.dpdk.org/archives/test-report/2024-
> March/601301.html
> These need to be fixed in CI infra.

This function that throws the error is available in the recently tagged 1.4 equivalent Arm repo, so I am unsure why it can't find it.
Could there be some old installed ipsec-mb version in the environment that is being picked up by DPDK?
Sometimes the meson configure step will pick up the correct ipsec-mb version, but then ninja step links to an older version that still exists and hadn't been uninstalled previously.
Not sure if that could be the case for the CI container though - Patrick maybe you can verify there are no 1.3 or less versions on system that could be being picked up:
I usually use something like:  find /usr -name libIPSec_MB.so\*


Thanks for the help,
Ciara


^ permalink raw reply	[relevance 4%]

* Re: [PATCH v4 1/7] ethdev: support report register names and filter
  2024-02-26  8:01  0%     ` fengchengwen
@ 2024-03-06  7:22  0%       ` Jie Hai
  0 siblings, 0 replies; 200+ results
From: Jie Hai @ 2024-03-06  7:22 UTC (permalink / raw)
  To: fengchengwen, dev; +Cc: lihuisong, liuyonglong, huangdengdui, ferruh.yigit

Hi, fengchengwen,
On 2024/2/26 16:01, fengchengwen wrote:
> Hi Jie,
> 
> On 2024/2/26 11:07, Jie Hai wrote:
>> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
>> structure. Names of registers in data fields can be reported and
>> the registers can be filtered by their names.
>>
>> The new API rte_eth_dev_get_reg_info_ext() is added to support
>> reporting names and filtering by names. And the original API
>> rte_eth_dev_get_reg_info() does not use the name and filter fields.
>> A local variable is used in rte_eth_dev_get_reg_info for
>> compatibility. If the drivers does not report the names, set them
>> to "offset_XXX".
>>
>> Signed-off-by: Jie Hai <haijie1@huawei.com>
>> ---
>>   doc/guides/rel_notes/release_24_03.rst |  8 ++++++
>>   lib/ethdev/rte_dev_info.h              | 11 +++++++++
>>   lib/ethdev/rte_ethdev.c                | 34 ++++++++++++++++++++++++++
>>   lib/ethdev/rte_ethdev.h                | 28 +++++++++++++++++++++
>>   lib/ethdev/version.map                 |  1 +
>>   5 files changed, 82 insertions(+)
>>
>> diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
>> index 32d0ad8cf6a7..fa46da427dca 100644
>> --- a/doc/guides/rel_notes/release_24_03.rst
>> +++ b/doc/guides/rel_notes/release_24_03.rst
>> @@ -132,6 +132,11 @@ New Features
>>       to support TLS v1.2, TLS v1.3 and DTLS v1.2.
>>     * Added PMD API to allow raw submission of instructions to CPT.
>>   
>> +  * **Added support for dumping registers with names and filter.**
>> +
>> +    * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
>> +      the registers by their names and get the information of registers(names,
>> +      values and other attributes).
>>   
>>   Removed Items
>>   -------------
>> @@ -197,6 +202,9 @@ ABI Changes
>>   
>>   * No ABI change that would break compatibility with 23.11.
>>   
>> +* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
>> +  structure for reporting names of registers and filtering them by names.
>> +
>>   
>>   Known Issues
>>   ------------
>> diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
>> index 67cf0ae52668..0ad4a43b9526 100644
>> --- a/lib/ethdev/rte_dev_info.h
>> +++ b/lib/ethdev/rte_dev_info.h
>> @@ -11,6 +11,11 @@ extern "C" {
>>   
>>   #include <stdint.h>
>>   
>> +#define RTE_ETH_REG_NAME_SIZE 128
> 
> Almost all stats name size is 64, why not keep consistent?
> 
will correct.
>> +struct rte_eth_reg_name {
>> +	char name[RTE_ETH_REG_NAME_SIZE];
>> +};
>> +
>>   /*
>>    * Placeholder for accessing device registers
>>    */
>> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>>   	uint32_t length; /**< Number of registers to fetch */
>>   	uint32_t width; /**< Size of device register */
>>   	uint32_t version; /**< Device version */
>> +	/**
>> +	 * Filter for target subset of registers.
>> +	 * This field could affects register selection for data/length/names.
>> +	 */
>> +	const char *filter;
>> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>>   };
>>   
>>   /*
>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
>> index f1c658f49e80..9ef50c633ce3 100644
>> --- a/lib/ethdev/rte_ethdev.c
>> +++ b/lib/ethdev/rte_ethdev.c
>> @@ -6388,8 +6388,37 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
>>   
>>   int
>>   rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>> +{
>> +	struct rte_dev_reg_info reg_info = { 0 };
>> +	int ret;
>> +
>> +	if (info == NULL) {
>> +		RTE_ETHDEV_LOG_LINE(ERR,
>> +			"Cannot get ethdev port %u register info to NULL",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	reg_info.length = info->length;
>> +	reg_info.data = info->data;
>> +
>> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
>> +	if (ret != 0)
>> +		return ret;
>> +
>> +	info->length = reg_info.length;
>> +	info->width = reg_info.width;
>> +	info->version = reg_info.version;
>> +	info->offset = reg_info.offset;
>> +
>> +	return 0;
>> +}
>> +
>> +int
>> +rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
>>   {
>>   	struct rte_eth_dev *dev;
>> +	uint32_t i;
>>   	int ret;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> @@ -6408,6 +6437,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>>   
>>   	rte_ethdev_trace_get_reg_info(port_id, info, ret);
>>   
>> +	/* Report the default names if drivers not report. */
>> +	if (info->names != NULL && strlen(info->names[0].name) == 0)
>> +		for (i = 0; i < info->length; i++)
>> +			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
>> +				"offset_%x", info->offset + i * info->width);
> 
> %x has no prefix "0x", may lead to confused.
> How about use %u ?
> 
That sounds better.
> Another question, if app don't zero names' memory, then its value is random, so it will not enter this logic.
> Suggest memset item[0]'s name memory before invoke PMD ops.
> 
>>   	return ret;
>>   }
>>   
>> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
>> index ed27360447a3..09e2d5fdb49b 100644
>> --- a/lib/ethdev/rte_ethdev.h
>> +++ b/lib/ethdev/rte_ethdev.h
>> @@ -5066,6 +5066,34 @@ __rte_experimental
>>   int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
>>   		struct rte_power_monitor_cond *pmc);
>>   
>> +/**
>> + * Retrieve the filtered device registers (values and names) and
>> + * register attributes (number of registers and register size)
>> + *
>> + * @param port_id
>> + *   The port identifier of the Ethernet device.
>> + * @param info
>> + *   Pointer to rte_dev_reg_info structure to fill in.
>> + *   If info->filter is not NULL and the driver does not support names or
>> + *   filter, return error. If info->filter is NULL, return info for all
>> + *   registers (seen as filter none).
>> + *   If info->data is NULL, the function fills in the width and length fields.
>> + *   If non-NULL, ethdev considers there are enough spaces to store the
>> + *   registers, and the values of registers whose name contains the filter
>> + *   string are put into the buffer pointed at by the data field. Do the same
>> + *   for the names of registers if info->names is not NULL. If drivers do not
>> + *   report names, default names are given by ethdev.
> 
> It's a little hard to understand. Suggest use '-' for each field, just like rte_eth_remove_tx_callback
> 
I will try.
>> + * @return
>> + *   - (0) if successful.
>> + *   - (-ENOTSUP) if hardware doesn't support.
>> + *   - (-EINVAL) if bad parameter.
>> + *   - (-ENODEV) if *port_id* invalid.
>> + *   - (-EIO) if device is removed.
>> + *   - others depends on the specific operations implementation.
>> + */
>> +__rte_experimental
>> +int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
>> +
>>   /**
>>    * Retrieve device registers and register attributes (number of registers and
>>    * register size)
>> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
>> index 17e4eac8a4cc..c41a64e404db 100644
>> --- a/lib/ethdev/version.map
>> +++ b/lib/ethdev/version.map
>> @@ -325,6 +325,7 @@ EXPERIMENTAL {
>>   	rte_flow_template_table_resizable;
>>   	rte_flow_template_table_resize;
>>   	rte_flow_template_table_resize_complete;
>> +	rte_eth_dev_get_reg_info_ext;
> 
> should place with alphabetical order.
> 
> Thanks
Ok.
> 
>>   };
>>   
>>   INTERNAL {
>>
> .
Thanks,
Jie Hai

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] hash: make gfni stubs inline
  2024-03-05 17:53  3%   ` Tyler Retzlaff
@ 2024-03-05 18:44  0%     ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2024-03-05 18:44 UTC (permalink / raw)
  To: Tyler Retzlaff
  Cc: David Marchand, dev, Yipeng Wang, Sameh Gobriel,
	Bruce Richardson, Vladimir Medvedkin

On Tue, 5 Mar 2024 09:53:00 -0800
Tyler Retzlaff <roretzla@linux.microsoft.com> wrote:

> On Tue, Mar 05, 2024 at 11:14:45AM +0100, David Marchand wrote:
> > On Mon, Mar 4, 2024 at 7:45 PM Stephen Hemminger
> > <stephen@networkplumber.org> wrote:  
> > >
> > > This reverts commit 07d836e5929d18ad6640ebae90dd2f81a2cafb71.
> > >
> > > Tyler found build issues with MSVC and the thash gfni stubs.
> > > The problem would be link errors from missing symbols.  
> > 
> > Trying to understand this link error.
> > Does it come from the fact that rte_thash_gfni/rte_thash_gfni_bulk
> > declarations are hidden under RTE_THASH_GFNI_DEFINED in
> > rte_thash_gfni.h?
> > 
> > If so, why not always expose those two symbols unconditionnally and
> > link with the stub only when ! RTE_THASH_GFNI_DEFINED.  
> 
> So I don't have a lot of background of this lib.
> 
> I think we understand that we can't conditionally expose symbols. That's
> what windows was picking up because it seems none of our CI's ever end
> up with RTE_THASH_GFNI_DEFINED but my local test system did and failed.
> (my experiments showed that Linux would complain too if it was defined)
> 
> If we always expose the symbols then as you point out we have to
> conditionally link with the stub otherwise the inline (non-stub) will be
> duplicate and build / link will fail.
> 
> I guess the part I don't understand with your suggestion is how we would
> conditionally link with just the stub? We have to link with rte_hash to
> get the rest of hash and the stub. I've probably missed something here.
> 
> Since we never had a release exposing the new symbols introduced by
> Stephen in question my suggestion was that we just revert for 24.03 so
> we don't end up with an ABI break later if we choose to solve the
> problem without exports.
> 
> I don't know what else to do, but I think we need to decide for 24.03.
> 
> ty

Another option would be introduce dead code stubs all the time.
Then have inline wrapper that redirect to the dead stub if needed.

Something like:
From 7bb972d342e939200f8f993a9074b20794941f6a Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Tue, 5 Mar 2024 10:42:48 -0800
Subject: [PATCH] hash: rename GFNI stubs

Make the GFNI stub functions always built. This solves the conditional
linking problem. If GFNI is available, they will never get used.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/hash/rte_thash_gfni.c | 11 +++++------
 lib/hash/rte_thash_gfni.h | 23 ++++++++++++++++++-----
 lib/hash/version.map      |  9 +++++++--
 3 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/lib/hash/rte_thash_gfni.c b/lib/hash/rte_thash_gfni.c
index f1525f9838de..de67abb8b211 100644
--- a/lib/hash/rte_thash_gfni.c
+++ b/lib/hash/rte_thash_gfni.c
@@ -4,18 +4,18 @@
 
 #include <stdbool.h>
 
+#include <rte_common.h>
 #include <rte_log.h>
 #include <rte_thash_gfni.h>
 
-#ifndef RTE_THASH_GFNI_DEFINED
-
 RTE_LOG_REGISTER_SUFFIX(hash_gfni_logtype, gfni, INFO);
 #define RTE_LOGTYPE_HASH hash_gfni_logtype
 #define HASH_LOG(level, ...) \
 	RTE_LOG_LINE(level, HASH, "" __VA_ARGS__)
 
+__rte_internal
 uint32_t
-rte_thash_gfni(const uint64_t *mtrx __rte_unused,
+___rte_thash_gfni(const uint64_t *mtrx __rte_unused,
 	const uint8_t *key __rte_unused, int len __rte_unused)
 {
 	static bool warned;
@@ -29,8 +29,9 @@ rte_thash_gfni(const uint64_t *mtrx __rte_unused,
 	return 0;
 }
 
+__rte_internal
 void
-rte_thash_gfni_bulk(const uint64_t *mtrx __rte_unused,
+___rte_thash_gfni_bulk(const uint64_t *mtrx __rte_unused,
 	int len __rte_unused, uint8_t *tuple[] __rte_unused,
 	uint32_t val[], uint32_t num)
 {
@@ -47,5 +48,3 @@ rte_thash_gfni_bulk(const uint64_t *mtrx __rte_unused,
 	for (i = 0; i < num; i++)
 		val[i] = 0;
 }
-
-#endif
diff --git a/lib/hash/rte_thash_gfni.h b/lib/hash/rte_thash_gfni.h
index eed55fc86c86..1cb61cf39675 100644
--- a/lib/hash/rte_thash_gfni.h
+++ b/lib/hash/rte_thash_gfni.h
@@ -9,7 +9,16 @@
 extern "C" {
 #endif
 
-#include <rte_log.h>
+#include <rte_common.h>
+/*
+ * @internal
+ * Stubs defined for use when GFNI is not available
+ */
+uint32_t
+___rte_thash_gfni(const uint64_t *mtrx, const uint8_t *key, int len);
+void
+___rte_thash_gfni_bulk(const uint64_t *mtrx, int len, uint8_t *tuple[],
+		       uint32_t val[], uint32_t num);
 
 #ifdef RTE_ARCH_X86
 
@@ -18,10 +27,8 @@ extern "C" {
 #endif
 
 #ifndef RTE_THASH_GFNI_DEFINED
-
 /**
  * Calculate Toeplitz hash.
- * Dummy implementation.
  *
  * @param m
  *  Pointer to the matrices generated from the corresponding
@@ -34,7 +41,10 @@ extern "C" {
  *  Calculated Toeplitz hash value.
  */
 uint32_t
-rte_thash_gfni(const uint64_t *mtrx, const uint8_t *key, int len);
+rte_thash_gfni(const uint64_t *mtrx, const uint8_t *key, int len)
+{
+	return ___rte_thash_gfni(mtrx, key, len);
+}
 
 /**
  * Bulk implementation for Toeplitz hash.
@@ -55,7 +65,10 @@ rte_thash_gfni(const uint64_t *mtrx, const uint8_t *key, int len);
  */
 void
 rte_thash_gfni_bulk(const uint64_t *mtrx, int len, uint8_t *tuple[],
-	uint32_t val[], uint32_t num);
+	uint32_t val[], uint32_t num)
+{
+	return ___rte_thash_gfni_bulk(mtrx, len, tuple, val);
+}
 
 #endif /* RTE_THASH_GFNI_DEFINED */
 
diff --git a/lib/hash/version.map b/lib/hash/version.map
index 6b2afebf6b46..942e2998578f 100644
--- a/lib/hash/version.map
+++ b/lib/hash/version.map
@@ -41,10 +41,15 @@ DPDK_24 {
 	rte_thash_get_gfni_matrices;
 	rte_thash_get_helper;
 	rte_thash_get_key;
-	rte_thash_gfni;
-	rte_thash_gfni_bulk;
 	rte_thash_gfni_supported;
 	rte_thash_init_ctx;
 
 	local: *;
 };
+
+INTERNAL {
+	global:
+
+	___rte_thash_gfni;
+	___rte_thash_gfni_bulk;
+};
-- 
2.43.0


^ permalink raw reply	[relevance 0%]

* Re: [PATCH] hash: make gfni stubs inline
  @ 2024-03-05 17:53  3%   ` Tyler Retzlaff
  2024-03-05 18:44  0%     ` Stephen Hemminger
  0 siblings, 1 reply; 200+ results
From: Tyler Retzlaff @ 2024-03-05 17:53 UTC (permalink / raw)
  To: David Marchand
  Cc: Stephen Hemminger, dev, Yipeng Wang, Sameh Gobriel,
	Bruce Richardson, Vladimir Medvedkin

On Tue, Mar 05, 2024 at 11:14:45AM +0100, David Marchand wrote:
> On Mon, Mar 4, 2024 at 7:45 PM Stephen Hemminger
> <stephen@networkplumber.org> wrote:
> >
> > This reverts commit 07d836e5929d18ad6640ebae90dd2f81a2cafb71.
> >
> > Tyler found build issues with MSVC and the thash gfni stubs.
> > The problem would be link errors from missing symbols.
> 
> Trying to understand this link error.
> Does it come from the fact that rte_thash_gfni/rte_thash_gfni_bulk
> declarations are hidden under RTE_THASH_GFNI_DEFINED in
> rte_thash_gfni.h?
> 
> If so, why not always expose those two symbols unconditionnally and
> link with the stub only when ! RTE_THASH_GFNI_DEFINED.

So I don't have a lot of background of this lib.

I think we understand that we can't conditionally expose symbols. That's
what windows was picking up because it seems none of our CI's ever end
up with RTE_THASH_GFNI_DEFINED but my local test system did and failed.
(my experiments showed that Linux would complain too if it was defined)

If we always expose the symbols then as you point out we have to
conditionally link with the stub otherwise the inline (non-stub) will be
duplicate and build / link will fail.

I guess the part I don't understand with your suggestion is how we would
conditionally link with just the stub? We have to link with rte_hash to
get the rest of hash and the stub. I've probably missed something here.

Since we never had a release exposing the new symbols introduced by
Stephen in question my suggestion was that we just revert for 24.03 so
we don't end up with an ABI break later if we choose to solve the
problem without exports.

I don't know what else to do, but I think we need to decide for 24.03.

ty

> 
> -- 
> David Marchand

^ permalink raw reply	[relevance 3%]

* [PATCH] devtools: require version for experimental symbols
@ 2024-03-05 13:49  4% David Marchand
  0 siblings, 0 replies; 200+ results
From: David Marchand @ 2024-03-05 13:49 UTC (permalink / raw)
  To: dev; +Cc: thomas

Add version to all symbols maps and a check so any experimental symbol
is versioned.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 buildtools/map-list-symbol.sh              |  8 ++++++--
 devtools/check-symbol-maps.sh              | 15 +++++++++++++++
 doc/guides/contributing/abi_policy.rst     | 17 ++++++++++++++++-
 drivers/baseband/acc/version.map           |  1 +
 drivers/baseband/fpga_5gnr_fec/version.map |  1 +
 drivers/baseband/fpga_lte_fec/version.map  |  2 +-
 drivers/bus/pci/version.map                |  1 +
 drivers/dma/dpaa2/version.map              |  3 +++
 drivers/event/dlb2/version.map             |  1 +
 drivers/mempool/cnxk/version.map           |  2 ++
 drivers/net/atlantic/version.map           |  1 +
 drivers/net/i40e/version.map               |  7 ++++++-
 drivers/net/ixgbe/version.map              |  1 +
 lib/argparse/version.map                   |  1 +
 lib/metrics/version.map                    |  2 +-
 lib/mldev/version.map                      |  1 +
 lib/regexdev/version.map                   |  9 ++++++---
 lib/reorder/version.map                    |  2 ++
 18 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/buildtools/map-list-symbol.sh b/buildtools/map-list-symbol.sh
index a834399816..b76e2417c5 100755
--- a/buildtools/map-list-symbol.sh
+++ b/buildtools/map-list-symbol.sh
@@ -61,8 +61,12 @@ for file in $@; do
 		if (current_section == "") {
 			next;
 		}
-		if ("'$version'" != "" && "'$version'" != current_version) {
-			next;
+		if ("'$version'" != "") {
+			if ("'$version'" == "unset" && current_version != "") {
+				next;
+			} else if ("'$version'" != "unset" && "'$version'" != current_version) {
+				next;
+			}
 		}
 		gsub(";","");
 		if ("'$symbol'" == "all" || $1 == "'$symbol'") {
diff --git a/devtools/check-symbol-maps.sh b/devtools/check-symbol-maps.sh
index ba2f892f56..6121f78ec6 100755
--- a/devtools/check-symbol-maps.sh
+++ b/devtools/check-symbol-maps.sh
@@ -97,4 +97,19 @@ if [ -n "$bad_format_maps" ] ; then
     ret=1
 fi
 
+find_non_versioned_maps ()
+{
+    for map in $@ ; do
+        [ $(buildtools/map-list-symbol.sh -S EXPERIMENTAL -V unset $map | wc -l) = '0' ] ||
+            echo $map
+    done
+}
+
+non_versioned_maps=$(find_non_versioned_maps $@)
+if [ -n "$non_versioned_maps" ] ; then
+    echo "Found non versioned maps:"
+    echo "$non_versioned_maps"
+    ret=1
+fi
+
 exit $ret
diff --git a/doc/guides/contributing/abi_policy.rst b/doc/guides/contributing/abi_policy.rst
index 5fd4052585..3c4478692a 100644
--- a/doc/guides/contributing/abi_policy.rst
+++ b/doc/guides/contributing/abi_policy.rst
@@ -331,7 +331,22 @@ become part of a tracked ABI version.
 Note that marking an API as experimental is a multi step process.
 To mark an API as experimental, the symbols which are desired to be exported
 must be placed in an EXPERIMENTAL version block in the corresponding libraries'
-version map script.
+version map script. Experimental symbols must be commented so
+that it is clear in which DPDK version they were introduced.
+
+.. code-block:: none
+
+ EXPERIMENTAL {
+        global:
+
+        # added in 20.11
+        rte_foo_init;
+        rte_foo_configure;
+
+        # added in 21.02
+        rte_foo_cleanup;
+ ...
+
 Secondly, the corresponding prototypes of those exported functions (in the
 development header files), must be marked with the ``__rte_experimental`` tag
 (see ``rte_compat.h``).
diff --git a/drivers/baseband/acc/version.map b/drivers/baseband/acc/version.map
index 1b6b1cd10d..fa39a63f0f 100644
--- a/drivers/baseband/acc/version.map
+++ b/drivers/baseband/acc/version.map
@@ -5,5 +5,6 @@ DPDK_24 {
 EXPERIMENTAL {
 	global:
 
+	# added in 22.11
 	rte_acc_configure;
 };
diff --git a/drivers/baseband/fpga_5gnr_fec/version.map b/drivers/baseband/fpga_5gnr_fec/version.map
index 2da20cabc1..855ce55703 100644
--- a/drivers/baseband/fpga_5gnr_fec/version.map
+++ b/drivers/baseband/fpga_5gnr_fec/version.map
@@ -5,6 +5,7 @@ DPDK_24 {
 EXPERIMENTAL {
 	global:
 
+	# added in 20.11
 	rte_fpga_5gnr_fec_configure;
 
 };
diff --git a/drivers/baseband/fpga_lte_fec/version.map b/drivers/baseband/fpga_lte_fec/version.map
index 83f3a8a267..2c8e60375d 100644
--- a/drivers/baseband/fpga_lte_fec/version.map
+++ b/drivers/baseband/fpga_lte_fec/version.map
@@ -5,6 +5,6 @@ DPDK_24 {
 EXPERIMENTAL {
 	global:
 
+	# added in 20.11
 	rte_fpga_lte_fec_configure;
-
 };
diff --git a/drivers/bus/pci/version.map b/drivers/bus/pci/version.map
index 9e4d8f5e54..5d9dced5b2 100644
--- a/drivers/bus/pci/version.map
+++ b/drivers/bus/pci/version.map
@@ -17,6 +17,7 @@ DPDK_24 {
 EXPERIMENTAL {
 	global:
 
+	# added in 20.11
 	rte_pci_find_ext_capability;
 
 	# added in 21.08
diff --git a/drivers/dma/dpaa2/version.map b/drivers/dma/dpaa2/version.map
index 7dc2d6e185..713ed41f0c 100644
--- a/drivers/dma/dpaa2/version.map
+++ b/drivers/dma/dpaa2/version.map
@@ -3,6 +3,9 @@ DPDK_24 {
 };
 
 EXPERIMENTAL {
+	global:
+
+	# added in 22.07
 	rte_dpaa2_qdma_completed_multi;
 	rte_dpaa2_qdma_copy_multi;
 	rte_dpaa2_qdma_vchan_fd_us_enable;
diff --git a/drivers/event/dlb2/version.map b/drivers/event/dlb2/version.map
index 8aabf8b727..1d0a0a75d7 100644
--- a/drivers/event/dlb2/version.map
+++ b/drivers/event/dlb2/version.map
@@ -5,5 +5,6 @@ DPDK_24 {
 EXPERIMENTAL {
 	global:
 
+	# added in 20.11
 	rte_pmd_dlb2_set_token_pop_mode;
 };
diff --git a/drivers/mempool/cnxk/version.map b/drivers/mempool/cnxk/version.map
index 775d46d934..8249417527 100644
--- a/drivers/mempool/cnxk/version.map
+++ b/drivers/mempool/cnxk/version.map
@@ -4,6 +4,8 @@ DPDK_24 {
 
 EXPERIMENTAL {
 	global:
+
+	# added in 23.07
 	rte_pmd_cnxk_mempool_is_hwpool;
 	rte_pmd_cnxk_mempool_mbuf_exchange;
 	rte_pmd_cnxk_mempool_range_check_disable;
diff --git a/drivers/net/atlantic/version.map b/drivers/net/atlantic/version.map
index b063baa7a4..cbe9ee9263 100644
--- a/drivers/net/atlantic/version.map
+++ b/drivers/net/atlantic/version.map
@@ -5,6 +5,7 @@ DPDK_24 {
 EXPERIMENTAL {
 	global:
 
+	# added in 19.05
 	rte_pmd_atl_macsec_enable;
 	rte_pmd_atl_macsec_disable;
 	rte_pmd_atl_macsec_config_txsc;
diff --git a/drivers/net/i40e/version.map b/drivers/net/i40e/version.map
index 3ba31f4768..52b7a3269a 100644
--- a/drivers/net/i40e/version.map
+++ b/drivers/net/i40e/version.map
@@ -42,9 +42,14 @@ DPDK_24 {
 EXPERIMENTAL {
 	global:
 
+	# added in 19.11
+	rte_pmd_i40e_set_switch_dev;
+
+	# added in 20.08
 	rte_pmd_i40e_get_fdir_info;
 	rte_pmd_i40e_get_fdir_stats;
 	rte_pmd_i40e_set_gre_key_len;
+
+	# added in 23.07
 	rte_pmd_i40e_set_pf_src_prune;
-	rte_pmd_i40e_set_switch_dev;
 };
diff --git a/drivers/net/ixgbe/version.map b/drivers/net/ixgbe/version.map
index 2c9d977f5c..9a6ef29b1d 100644
--- a/drivers/net/ixgbe/version.map
+++ b/drivers/net/ixgbe/version.map
@@ -43,6 +43,7 @@ DPDK_24 {
 EXPERIMENTAL {
 	global:
 
+	# added in 20.08
 	rte_pmd_ixgbe_get_fdir_info;
 	rte_pmd_ixgbe_get_fdir_stats;
 };
diff --git a/lib/argparse/version.map b/lib/argparse/version.map
index 9b68464600..46da99a3e2 100644
--- a/lib/argparse/version.map
+++ b/lib/argparse/version.map
@@ -1,6 +1,7 @@
 EXPERIMENTAL {
 	global:
 
+	# added in 24.03
 	rte_argparse_parse;
 	rte_argparse_parse_type;
 
diff --git a/lib/metrics/version.map b/lib/metrics/version.map
index 4763ac6b8b..9766a1af5b 100644
--- a/lib/metrics/version.map
+++ b/lib/metrics/version.map
@@ -16,11 +16,11 @@ DPDK_24 {
 EXPERIMENTAL {
 	global:
 
+	# added in 20.05
 	rte_metrics_tel_encode_json_format;
 	rte_metrics_tel_reg_all_ethdev;
 	rte_metrics_tel_get_global_stats;
 	rte_metrics_tel_get_port_stats_ids;
 	rte_metrics_tel_get_ports_stats_json;
 	rte_metrics_tel_extract_data;
-
 };
diff --git a/lib/mldev/version.map b/lib/mldev/version.map
index 1978695314..84bdd6c300 100644
--- a/lib/mldev/version.map
+++ b/lib/mldev/version.map
@@ -1,6 +1,7 @@
 EXPERIMENTAL {
 	global:
 
+	# added in 22.11
 	rte_ml_dequeue_burst;
 	rte_ml_dev_close;
 	rte_ml_dev_configure;
diff --git a/lib/regexdev/version.map b/lib/regexdev/version.map
index 3c6e9fffa1..4c0435180c 100644
--- a/lib/regexdev/version.map
+++ b/lib/regexdev/version.map
@@ -1,7 +1,7 @@
 EXPERIMENTAL {
 	global:
 
-	rte_regex_devices;
+	# added in 20.08
 	rte_regexdev_attr_get;
 	rte_regexdev_attr_set;
 	rte_regexdev_close;
@@ -12,8 +12,6 @@ EXPERIMENTAL {
 	rte_regexdev_enqueue_burst;
 	rte_regexdev_get_dev_id;
 	rte_regexdev_info_get;
-	rte_regexdev_is_valid_dev;
-	rte_regexdev_logtype;
 	rte_regexdev_queue_pair_setup;
 	rte_regexdev_rule_db_compile_activate;
 	rte_regexdev_rule_db_export;
@@ -27,6 +25,11 @@ EXPERIMENTAL {
 	rte_regexdev_xstats_names_get;
 	rte_regexdev_xstats_reset;
 
+	# added in 22.03
+	rte_regex_devices;
+	rte_regexdev_is_valid_dev;
+	rte_regexdev_logtype;
+
 	local: *;
 };
 
diff --git a/lib/reorder/version.map b/lib/reorder/version.map
index ea60759106..5baeab56f8 100644
--- a/lib/reorder/version.map
+++ b/lib/reorder/version.map
@@ -15,11 +15,13 @@ DPDK_24 {
 EXPERIMENTAL {
 	global:
 
+	# added in 20.11
 	rte_reorder_seqn_dynfield_offset;
 
 	# added in 23.03
 	rte_reorder_drain_up_to_seqn;
 	rte_reorder_min_seqn_set;
+
 	# added in 23.07
 	rte_reorder_memory_footprint_get;
 };
-- 
2.43.0


^ permalink raw reply	[relevance 4%]

* Re: [PATCH v4 1/7] ethdev: support report register names and filter
  2024-02-29  9:52  3%     ` Thomas Monjalon
@ 2024-03-05  7:45  5%       ` Jie Hai
  0 siblings, 0 replies; 200+ results
From: Jie Hai @ 2024-03-05  7:45 UTC (permalink / raw)
  To: Thomas Monjalon, ferruh.yigit
  Cc: dev, lihuisong, fengchengwen, liuyonglong, huangdengdui

Hi, Thomas ,

Thanks for your review.
On 2024/2/29 17:52, Thomas Monjalon wrote:
> 26/02/2024 04:07, Jie Hai:
>> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
>> structure. Names of registers in data fields can be reported and
>> the registers can be filtered by their names.
>>
>> The new API rte_eth_dev_get_reg_info_ext() is added to support
>> reporting names and filtering by names. And the original API
>> rte_eth_dev_get_reg_info() does not use the name and filter fields.
>> A local variable is used in rte_eth_dev_get_reg_info for
>> compatibility. If the drivers does not report the names, set them
>> to "offset_XXX".
> 
> Isn't it possible to implement filtering in the original function?
> What would it break?
> 
If we implement filtering in the original function
rte_eth_dev_get_reg_info(), ABI would be broken and
old app cannot run with linked to the new library.

Existing binary applications will have backwards compatibility with our 
current patch.
Although the ABI is modified, the old app can still behave normally in 
the case of dynamic linking with the new library.
And the new APP using rte_eth_dev_get_reg_info() works well with  the 
old library.
>> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>>   	uint32_t length; /**< Number of registers to fetch */
>>   	uint32_t width; /**< Size of device register */
>>   	uint32_t version; /**< Device version */
>> +	/**
>> +	 * Filter for target subset of registers.
>> +	 * This field could affects register selection for data/length/names.
>> +	 */
>> +	const char *filter;
>> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>>   };
> 
> I suppose this is an ABI break?
> Confirmed: http://mails.dpdk.org/archives/test-report/2024-February/587314.html
> 
I think  it is ABI change but not ABI break. please see above.
> 
> .
Best regards,
Jie Hai

^ permalink raw reply	[relevance 5%]

* RE: [RFC PATCH 1/2] power: refactor core power management library
  2024-03-01  2:56  3%   ` lihuisong (C)
  2024-03-01 10:39  0%     ` Hunt, David
@ 2024-03-05  4:35  3%     ` Tummala, Sivaprasad
  1 sibling, 0 replies; 200+ results
From: Tummala, Sivaprasad @ 2024-03-05  4:35 UTC (permalink / raw)
  To: lihuisong (C),
	david.hunt, anatoly.burakov, jerinj, radu.nicolau, gakhil,
	cristian.dumitrescu, Yigit, Ferruh, konstantin.ananyev
  Cc: dev

[AMD Official Use Only - General]

Hi Lihuisong,

> -----Original Message-----
> From: lihuisong (C) <lihuisong@huawei.com>
> Sent: Friday, March 1, 2024 8:27 AM
> To: Tummala, Sivaprasad <Sivaprasad.Tummala@amd.com>;
> david.hunt@intel.com; anatoly.burakov@intel.com; jerinj@marvell.com;
> radu.nicolau@intel.com; gakhil@marvell.com; cristian.dumitrescu@intel.com; Yigit,
> Ferruh <Ferruh.Yigit@amd.com>; konstantin.ananyev@huawei.com
> Cc: dev@dpdk.org
> Subject: Re: [RFC PATCH 1/2] power: refactor core power management library
>
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
>
>
> 在 2024/2/20 23:33, Sivaprasad Tummala 写道:
> > This patch introduces a comprehensive refactor to the core power
> > management library. The primary focus is on improving modularity and
> > organization by relocating specific driver implementations from the
> > 'lib/power' directory to dedicated directories within
> > 'drivers/power/core/*'. The adjustment of meson.build files enables
> > the selective activation of individual drivers.
> >
> > These changes contribute to a significant enhancement in code
> > organization, providing a clearer structure for driver implementations.
> > The refactor aims to improve overall code clarity and boost
> > maintainability. Additionally, it establishes a foundation for future
> > development, allowing for more focused work on individual drivers and
> > seamless integration of forthcoming enhancements.
>
> Good job. +1 to refacotor.
>
> <...>
>
> > diff --git a/drivers/meson.build b/drivers/meson.build index
> > f2be71bc05..e293c3945f 100644
> > --- a/drivers/meson.build
> > +++ b/drivers/meson.build
> > @@ -28,6 +28,7 @@ subdirs = [
> >           'event',          # depends on common, bus, mempool and net.
> >           'baseband',       # depends on common and bus.
> >           'gpu',            # depends on common and bus.
> > +        'power',          # depends on common (in future).
> >   ]
> >
> >   if meson.is_cross_build()
> > diff --git a/drivers/power/core/acpi/meson.build
> > b/drivers/power/core/acpi/meson.build
> > new file mode 100644
> > index 0000000000..d10ec8ee94
> > --- /dev/null
> > +++ b/drivers/power/core/acpi/meson.build
> > @@ -0,0 +1,8 @@
> > +# SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2024 AMD
> > +Limited
> > +
> > +sources = files('power_acpi_cpufreq.c')
> > +
> > +headers = files('power_acpi_cpufreq.h')
> > +
> > +deps += ['power']
> > diff --git a/lib/power/power_acpi_cpufreq.c
> > b/drivers/power/core/acpi/power_acpi_cpufreq.c
> > similarity index 95%
> > rename from lib/power/power_acpi_cpufreq.c rename to
> > drivers/power/core/acpi/power_acpi_cpufreq.c
> This file is in power lib.
> How about remove the 'power' prefix of this file name?
> like acpi_cpufreq.c, cppc_cpufreq.c.
ACK

> > index f8d978d03d..69d80ad2ae 100644
> > --- a/lib/power/power_acpi_cpufreq.c
> > +++ b/drivers/power/core/acpi/power_acpi_cpufreq.c
> > @@ -577,3 +577,22 @@ int power_acpi_get_capabilities(unsigned int
> > lcore_id,
> >
> >       return 0;
> >   }
> > +
> > +static struct rte_power_ops acpi_ops = {
> How about use the following structure name?
> "struct rte_power_cpufreq_ops" or "struct rte_power_core_ops"
> After all, we also have other power ops, like uncore, right?
Agreed.
> > +     .init = power_acpi_cpufreq_init,
> > +     .exit = power_acpi_cpufreq_exit,
> > +     .check_env_support = power_acpi_cpufreq_check_supported,
> > +     .get_avail_freqs = power_acpi_cpufreq_freqs,
> > +     .get_freq = power_acpi_cpufreq_get_freq,
> > +     .set_freq = power_acpi_cpufreq_set_freq,
> > +     .freq_down = power_acpi_cpufreq_freq_down,
> > +     .freq_up = power_acpi_cpufreq_freq_up,
> > +     .freq_max = power_acpi_cpufreq_freq_max,
> > +     .freq_min = power_acpi_cpufreq_freq_min,
> > +     .turbo_status = power_acpi_turbo_status,
> > +     .enable_turbo = power_acpi_enable_turbo,
> > +     .disable_turbo = power_acpi_disable_turbo,
> > +     .get_caps = power_acpi_get_capabilities };
> > +
> > +RTE_POWER_REGISTER_OPS(acpi_ops);
> > diff --git a/lib/power/power_acpi_cpufreq.h
> > b/drivers/power/core/acpi/power_acpi_cpufreq.h
> > similarity index 100%
> > rename from lib/power/power_acpi_cpufreq.h rename to
> > drivers/power/core/acpi/power_acpi_cpufreq.h
> > diff --git a/drivers/power/core/amd-pstate/meson.build
> > b/drivers/power/core/amd-pstate/meson.build
> > new file mode 100644
> > index 0000000000..8ec4c960f5
> > --- /dev/null
> > +++ b/drivers/power/core/amd-pstate/meson.build
> > @@ -0,0 +1,8 @@
> > +# SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2024 AMD
> > +Limited
> > +
> > +sources = files('power_amd_pstate_cpufreq.c')
> > +
> > +headers = files('power_amd_pstate_cpufreq.h')
> > +
> > +deps += ['power']
> > diff --git a/lib/power/power_amd_pstate_cpufreq.c
> > b/drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.c
> > similarity index 95%
> > rename from lib/power/power_amd_pstate_cpufreq.c
> > rename to drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.c
> > index 028f84416b..9938de72a6 100644
> > --- a/lib/power/power_amd_pstate_cpufreq.c
> > +++ b/drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.c
> > @@ -700,3 +700,22 @@ power_amd_pstate_get_capabilities(unsigned int
> > lcore_id,
> >
> >       return 0;
> >   }
> > +
> > +static struct rte_power_ops amd_pstate_ops = {
> > +     .init = power_amd_pstate_cpufreq_init,
> > +     .exit = power_amd_pstate_cpufreq_exit,
> > +     .check_env_support = power_amd_pstate_cpufreq_check_supported,
> > +     .get_avail_freqs = power_amd_pstate_cpufreq_freqs,
> > +     .get_freq = power_amd_pstate_cpufreq_get_freq,
> > +     .set_freq = power_amd_pstate_cpufreq_set_freq,
> > +     .freq_down = power_amd_pstate_cpufreq_freq_down,
> > +     .freq_up = power_amd_pstate_cpufreq_freq_up,
> > +     .freq_max = power_amd_pstate_cpufreq_freq_max,
> > +     .freq_min = power_amd_pstate_cpufreq_freq_min,
> > +     .turbo_status = power_amd_pstate_turbo_status,
> > +     .enable_turbo = power_amd_pstate_enable_turbo,
> > +     .disable_turbo = power_amd_pstate_disable_turbo,
> > +     .get_caps = power_amd_pstate_get_capabilities };
> > +
> > +RTE_POWER_REGISTER_OPS(amd_pstate_ops);
> > diff --git a/lib/power/power_amd_pstate_cpufreq.h
> > b/drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.h
> > similarity index 100%
> > rename from lib/power/power_amd_pstate_cpufreq.h
> > rename to drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.h
> > diff --git a/drivers/power/core/cppc/meson.build
> > b/drivers/power/core/cppc/meson.build
> > new file mode 100644
> > index 0000000000..06f3b99bb8
> > --- /dev/null
> > +++ b/drivers/power/core/cppc/meson.build
> > @@ -0,0 +1,8 @@
> > +# SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2024 AMD
> > +Limited
> > +
> > +sources = files('power_cppc_cpufreq.c')
> > +
> > +headers = files('power_cppc_cpufreq.h')
> > +
> > +deps += ['power']
> > diff --git a/lib/power/power_cppc_cpufreq.c
> > b/drivers/power/core/cppc/power_cppc_cpufreq.c
> > similarity index 96%
> > rename from lib/power/power_cppc_cpufreq.c rename to
> > drivers/power/core/cppc/power_cppc_cpufreq.c
> > index 3ddf39bd76..605f633309 100644
> > --- a/lib/power/power_cppc_cpufreq.c
> > +++ b/drivers/power/core/cppc/power_cppc_cpufreq.c
> > @@ -685,3 +685,22 @@ power_cppc_get_capabilities(unsigned int
> > lcore_id,
> >
> >       return 0;
> >   }
> > +
> > +static struct rte_power_ops cppc_ops = {
> > +     .init = power_cppc_cpufreq_init,
> > +     .exit = power_cppc_cpufreq_exit,
> > +     .check_env_support = power_cppc_cpufreq_check_supported,
> > +     .get_avail_freqs = power_cppc_cpufreq_freqs,
> > +     .get_freq = power_cppc_cpufreq_get_freq,
> > +     .set_freq = power_cppc_cpufreq_set_freq,
> > +     .freq_down = power_cppc_cpufreq_freq_down,
> > +     .freq_up = power_cppc_cpufreq_freq_up,
> > +     .freq_max = power_cppc_cpufreq_freq_max,
> > +     .freq_min = power_cppc_cpufreq_freq_min,
> > +     .turbo_status = power_cppc_turbo_status,
> > +     .enable_turbo = power_cppc_enable_turbo,
> > +     .disable_turbo = power_cppc_disable_turbo,
> > +     .get_caps = power_cppc_get_capabilities };
> > +
> > +RTE_POWER_REGISTER_OPS(cppc_ops);
> > diff --git a/lib/power/power_cppc_cpufreq.h
> > b/drivers/power/core/cppc/power_cppc_cpufreq.h
> > similarity index 100%
> > rename from lib/power/power_cppc_cpufreq.h rename to
> > drivers/power/core/cppc/power_cppc_cpufreq.h
> > diff --git a/lib/power/guest_channel.c
> > b/drivers/power/core/kvm-vm/guest_channel.c
> > similarity index 100%
> > rename from lib/power/guest_channel.c
> > rename to drivers/power/core/kvm-vm/guest_channel.c
> > diff --git a/lib/power/guest_channel.h
> > b/drivers/power/core/kvm-vm/guest_channel.h
> > similarity index 100%
> > rename from lib/power/guest_channel.h
> > rename to drivers/power/core/kvm-vm/guest_channel.h
> > diff --git a/drivers/power/core/kvm-vm/meson.build
> > b/drivers/power/core/kvm-vm/meson.build
> > new file mode 100644
> > index 0000000000..3150c6674b
> > --- /dev/null
> > +++ b/drivers/power/core/kvm-vm/meson.build
> > @@ -0,0 +1,20 @@
> > +# SPDX-License-Identifier: BSD-3-Clause # Copyright(C) 2024 AMD
> > +Limited.
> > +#
> > +
> > +if not is_linux
> > +    build = false
> > +    reason = 'only supported on Linux'
> > +    subdir_done()
> > +endif
> > +
> > +sources = files(
> > +        'guest_channel.c',
> > +        'power_kvm_vm.c',
> > +)
> > +
> > +headers = files(
> > +        'guest_channel.h',
> > +        'power_kvm_vm.h',
> > +)
> > +deps += ['power']
> > diff --git a/lib/power/power_kvm_vm.c
> > b/drivers/power/core/kvm-vm/power_kvm_vm.c
> > similarity index 83%
> > rename from lib/power/power_kvm_vm.c
> > rename to drivers/power/core/kvm-vm/power_kvm_vm.c
> > index f15be8fac5..a5d6984d26 100644
> > --- a/lib/power/power_kvm_vm.c
> > +++ b/drivers/power/core/kvm-vm/power_kvm_vm.c
> > @@ -137,3 +137,22 @@ int power_kvm_vm_get_capabilities(__rte_unused
> unsigned int lcore_id,
> >       POWER_LOG(ERR, "rte_power_get_capabilities is not implemented for Virtual
> Machine Power Management");
> >       return -ENOTSUP;
> >   }
> > +
> > +static struct rte_power_ops kvm_vm_ops = {
> > +     .init = power_kvm_vm_init,
> > +     .exit = power_kvm_vm_exit,
> > +     .check_env_support = power_kvm_vm_check_supported,
> > +     .get_avail_freqs = power_kvm_vm_freqs,
> > +     .get_freq = power_kvm_vm_get_freq,
> > +     .set_freq = power_kvm_vm_set_freq,
> > +     .freq_down = power_kvm_vm_freq_down,
> > +     .freq_up = power_kvm_vm_freq_up,
> > +     .freq_max = power_kvm_vm_freq_max,
> > +     .freq_min = power_kvm_vm_freq_min,
> > +     .turbo_status = power_kvm_vm_turbo_status,
> > +     .enable_turbo = power_kvm_vm_enable_turbo,
> > +     .disable_turbo = power_kvm_vm_disable_turbo,
> > +     .get_caps = power_kvm_vm_get_capabilities };
> > +
> > +RTE_POWER_REGISTER_OPS(kvm_vm_ops);
> > diff --git a/lib/power/power_kvm_vm.h
> > b/drivers/power/core/kvm-vm/power_kvm_vm.h
> > similarity index 100%
> > rename from lib/power/power_kvm_vm.h
> > rename to drivers/power/core/kvm-vm/power_kvm_vm.h
> > diff --git a/drivers/power/core/meson.build
> > b/drivers/power/core/meson.build new file mode 100644 index
> > 0000000000..4081dafaa0
> > --- /dev/null
> > +++ b/drivers/power/core/meson.build
> > @@ -0,0 +1,12 @@
> > +# SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2024 AMD
> > +Limited
> > +
> > +drivers = [
> > +        'acpi',
> > +        'amd-pstate',
> > +        'cppc',
> > +        'kvm-vm',
> > +        'pstate'
> > +]
> > +
> > +std_deps = ['power']
> > diff --git a/drivers/power/core/pstate/meson.build
> > b/drivers/power/core/pstate/meson.build
> > new file mode 100644
> > index 0000000000..1025c64e48
> > --- /dev/null
> > +++ b/drivers/power/core/pstate/meson.build
> > @@ -0,0 +1,8 @@
> > +# SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2024 AMD
> > +Limited
> > +
> > +sources = files('power_pstate_cpufreq.c')
> > +
> > +headers = files('power_pstate_cpufreq.h')
> > +
> > +deps += ['power']
> > diff --git a/lib/power/power_pstate_cpufreq.c
> > b/drivers/power/core/pstate/power_pstate_cpufreq.c
> > similarity index 96%
> > rename from lib/power/power_pstate_cpufreq.c rename to
> > drivers/power/core/pstate/power_pstate_cpufreq.c
> > index 73138dc4e4..d4c3645ff8 100644
> > --- a/lib/power/power_pstate_cpufreq.c
> > +++ b/drivers/power/core/pstate/power_pstate_cpufreq.c
> > @@ -888,3 +888,22 @@ int power_pstate_get_capabilities(unsigned int
> > lcore_id,
> >
> >       return 0;
> >   }
> > +
> > +static struct rte_power_ops pstate_ops = {
> > +     .init = power_pstate_cpufreq_init,
> > +     .exit = power_pstate_cpufreq_exit,
> > +     .check_env_support = power_pstate_cpufreq_check_supported,
> > +     .get_avail_freqs = power_pstate_cpufreq_freqs,
> > +     .get_freq = power_pstate_cpufreq_get_freq,
> > +     .set_freq = power_pstate_cpufreq_set_freq,
> > +     .freq_down = power_pstate_cpufreq_freq_down,
> > +     .freq_up = power_pstate_cpufreq_freq_up,
> > +     .freq_max = power_pstate_cpufreq_freq_max,
> > +     .freq_min = power_pstate_cpufreq_freq_min,
> > +     .turbo_status = power_pstate_turbo_status,
> > +     .enable_turbo = power_pstate_enable_turbo,
> > +     .disable_turbo = power_pstate_disable_turbo,
> > +     .get_caps = power_pstate_get_capabilities };
> > +
> > +RTE_POWER_REGISTER_OPS(pstate_ops);
> > diff --git a/lib/power/power_pstate_cpufreq.h
> > b/drivers/power/core/pstate/power_pstate_cpufreq.h
> > similarity index 100%
> > rename from lib/power/power_pstate_cpufreq.h rename to
> > drivers/power/core/pstate/power_pstate_cpufreq.h
> > diff --git a/drivers/power/meson.build b/drivers/power/meson.build new
> > file mode 100644 index 0000000000..7d9034c7ac
> > --- /dev/null
> > +++ b/drivers/power/meson.build
> > @@ -0,0 +1,8 @@
> > +# SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2024 AMD
> > +Limited
> > +
> > +drivers = [
> > +        'core',
> > +]
> > +
> > +std_deps = ['power']
> > diff --git a/lib/power/meson.build b/lib/power/meson.build index
> > b8426589b2..207d96d877 100644
> > --- a/lib/power/meson.build
> > +++ b/lib/power/meson.build
> > @@ -12,14 +12,8 @@ if not is_linux
> >       reason = 'only supported on Linux'
> >   endif
> >   sources = files(
> > -        'guest_channel.c',
> > -        'power_acpi_cpufreq.c',
> > -        'power_amd_pstate_cpufreq.c',
> >           'power_common.c',
> > -        'power_cppc_cpufreq.c',
> > -        'power_kvm_vm.c',
> >           'power_intel_uncore.c',
> > -        'power_pstate_cpufreq.c',
> >           'rte_power.c',
> >           'rte_power_uncore.c',
> >           'rte_power_pmd_mgmt.c',
> > diff --git a/lib/power/power_common.h b/lib/power/power_common.h index
> > 30966400ba..c90b611f4f 100644
> > --- a/lib/power/power_common.h
> > +++ b/lib/power/power_common.h
> > @@ -23,13 +23,24 @@ extern int power_logtype;
> >   #endif
> >
> >   /* check if scaling driver matches one we want */
> > +__rte_internal
> >   int cpufreq_check_scaling_driver(const char *driver);
> > +
> > +__rte_internal
> >   int power_set_governor(unsigned int lcore_id, const char *new_governor,
> >               char *orig_governor, size_t orig_governor_len);
> > +
> > +__rte_internal
> >   int open_core_sysfs_file(FILE **f, const char *mode, const char *format, ...)
> >               __rte_format_printf(3, 4);
> > +
> > +__rte_internal
> >   int read_core_sysfs_u32(FILE *f, uint32_t *val);
> > +
> > +__rte_internal
> >   int read_core_sysfs_s(FILE *f, char *buf, unsigned int len);
> > +
> > +__rte_internal
> >   int write_core_sysfs_s(FILE *f, const char *str);
> >
> >   #endif /* _POWER_COMMON_H_ */
> > diff --git a/lib/power/rte_power.c b/lib/power/rte_power.c index
> > 36c3f3da98..70176807f4 100644
> > --- a/lib/power/rte_power.c
> > +++ b/lib/power/rte_power.c
> > @@ -8,64 +8,80 @@
> >   #include <rte_spinlock.h>
> >
> >   #include "rte_power.h"
> > -#include "power_acpi_cpufreq.h"
> > -#include "power_cppc_cpufreq.h"
> >   #include "power_common.h"
> > -#include "power_kvm_vm.h"
> > -#include "power_pstate_cpufreq.h"
> > -#include "power_amd_pstate_cpufreq.h"
> >
> >   enum power_management_env global_default_env = PM_ENV_NOT_SET;
> use a pointer to save the current power cpufreq ops?
ACK

> >
> >   static rte_spinlock_t global_env_cfg_lock =
> > RTE_SPINLOCK_INITIALIZER;
> > +static struct rte_power_ops rte_power_ops[PM_ENV_MAX];
> >
> > -/* function pointers */
> > -rte_power_freqs_t rte_power_freqs  = NULL; -rte_power_get_freq_t
> > rte_power_get_freq = NULL; -rte_power_set_freq_t rte_power_set_freq =
> > NULL; -rte_power_freq_change_t rte_power_freq_up = NULL;
> > -rte_power_freq_change_t rte_power_freq_down = NULL;
> > -rte_power_freq_change_t rte_power_freq_max = NULL;
> > -rte_power_freq_change_t rte_power_freq_min = NULL;
> > -rte_power_freq_change_t rte_power_turbo_status;
> > -rte_power_freq_change_t rte_power_freq_enable_turbo;
> > -rte_power_freq_change_t rte_power_freq_disable_turbo;
> > -rte_power_get_capabilities_t rte_power_get_capabilities;
> > -
> > -static void
> > -reset_power_function_ptrs(void)
> > +/* register the ops struct in rte_power_ops, return 0 on success. */
> > +int rte_power_register_ops(const struct rte_power_ops *op) {
> > +     struct rte_power_ops *ops;
> > +
> > +     if (op->env >= PM_ENV_MAX) {
> > +             POWER_LOG(ERR, "Unsupported power management environment\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     if (op->status != 0) {
> > +             POWER_LOG(ERR, "Power management env[%d] ops registered
> already\n",
> > +                     op->env);
> > +             return -EINVAL;
> > +     }
> > +
> > +     if (!op->init || !op->exit || !op->check_env_support ||
> > +             !op->get_avail_freqs || !op->get_freq || !op->set_freq ||
> > +             !op->freq_up || !op->freq_down || !op->freq_max ||
> > +             !op->freq_min || !op->turbo_status || !op->enable_turbo ||
> > +             !op->disable_turbo || !op->get_caps) {
> > +             POWER_LOG(ERR, "Missing callbacks while registering power ops\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ops = &rte_power_ops[op->env];
> It is better to use a global linked list instead of an array.
> And we should extract a list structure including this ops structure and this ops's
> owner.
> > +     ops->env = op->env;
> > +     ops->init = op->init;
> > +     ops->exit = op->exit;
> > +     ops->check_env_support = op->check_env_support;
> > +     ops->get_avail_freqs = op->get_avail_freqs;
> > +     ops->get_freq = op->get_freq;
> > +     ops->set_freq = op->set_freq;
> > +     ops->freq_up = op->freq_up;
> > +     ops->freq_down = op->freq_down;
> > +     ops->freq_max = op->freq_max;
> > +     ops->freq_min = op->freq_min;
> > +     ops->turbo_status = op->turbo_status;
> > +     ops->enable_turbo = op->enable_turbo;
> > +     ops->disable_turbo = op->disable_turbo;
> *ops = *op?
> > +     ops->status = 1; /* registered */
> status --> registered?
> But if use ops linked list, this flag also can be removed.
> > +
> > +     return 0;
> > +}
> > +
> > +struct rte_power_ops *
> > +rte_power_get_ops(int ops_index)
> AFAICS, there is only one cpufreq driver on one platform and just have one
> power_cpufreq_ops to use for user.
> We don't need user to get other power ops, and user just want to know the power
> ops using currently, right?
> So using 'index' toget this ops is not good.
Agreed! I will rework this to make it global.
> >   {
> > -     rte_power_freqs  = NULL;
> > -     rte_power_get_freq = NULL;
> > -     rte_power_set_freq = NULL;
> > -     rte_power_freq_up = NULL;
> > -     rte_power_freq_down = NULL;
> > -     rte_power_freq_max = NULL;
> > -     rte_power_freq_min = NULL;
> > -     rte_power_turbo_status = NULL;
> > -     rte_power_freq_enable_turbo = NULL;
> > -     rte_power_freq_disable_turbo = NULL;
> > -     rte_power_get_capabilities = NULL;
> > +     RTE_VERIFY((ops_index >= PM_ENV_NOT_SET) && (ops_index <
> PM_ENV_MAX));
> > +     RTE_VERIFY(rte_power_ops[ops_index].status != 0);
> > +
> > +     return &rte_power_ops[ops_index];
> >   }
> >
> >   int
> >   rte_power_check_env_supported(enum power_management_env env)
> >   {
> > -     switch (env) {
> > -     case PM_ENV_ACPI_CPUFREQ:
> > -             return power_acpi_cpufreq_check_supported();
> > -     case PM_ENV_PSTATE_CPUFREQ:
> > -             return power_pstate_cpufreq_check_supported();
> > -     case PM_ENV_KVM_VM:
> > -             return power_kvm_vm_check_supported();
> > -     case PM_ENV_CPPC_CPUFREQ:
> > -             return power_cppc_cpufreq_check_supported();
> > -     case PM_ENV_AMD_PSTATE_CPUFREQ:
> > -             return power_amd_pstate_cpufreq_check_supported();
> > -     default:
> > -             rte_errno = EINVAL;
> > -             return -1;
> > +     struct rte_power_ops *ops;
> > +
> > +     if ((env > PM_ENV_NOT_SET) && (env < PM_ENV_MAX)) {
> > +             ops = rte_power_get_ops(env);
> > +             return ops->check_env_support();
> >       }
> > +
> > +     rte_errno = EINVAL;
> > +     return -1;
> >   }
> >
> >   int
> > @@ -80,80 +96,26 @@ rte_power_set_env(enum power_management_env
> env)
> >       }
> >
> >       int ret = 0;
> > +     struct rte_power_ops *ops;
> > +
> > +     if ((env == PM_ENV_NOT_SET) || (env >= PM_ENV_MAX)) {
> > +             POWER_LOG(ERR, "Invalid Power Management Environment(%d)"
> > +                             " set\n", env);
> > +             ret = -1;
> > +     }
> >
> <...>
> > +     ops = rte_power_get_ops(env);
> To find the target ops from the global list according to the env?
> > +     if (ops->status == 0) {
> > +             POWER_LOG(ERR, WER,
> > +                     "Power Management Environment(%d) not"
> > +                     " registered\n", env);
> >               ret = -1;
> >       }
> >
> >       if (ret == 0)
> >               global_default_env = env;
> It is more convenient to use a global variable to point to the default power_cpufreq
> ops or its list node.
Agreed
> > -     else {
> > +     else
> >               global_default_env = PM_ENV_NOT_SET;
> > -             reset_power_function_ptrs();
> > -     }
> >
> >       rte_spinlock_unlock(&global_env_cfg_lock);
> >       return ret;
> > @@ -164,7 +126,6 @@ rte_power_unset_env(void)
> >   {
> >       rte_spinlock_lock(&global_env_cfg_lock);
> >       global_default_env = PM_ENV_NOT_SET;
> > -     reset_power_function_ptrs();
> >       rte_spinlock_unlock(&global_env_cfg_lock);
> >   }
> >
> > @@ -177,59 +138,76 @@ int
> >   rte_power_init(unsigned int lcore_id)
> >   {
> >       int ret = -1;
> > +     struct rte_power_ops *ops;
> >
> > -     switch (global_default_env) {
> > -     case PM_ENV_ACPI_CPUFREQ:
> > -             return power_acpi_cpufreq_init(lcore_id);
> > -     case PM_ENV_KVM_VM:
> > -             return power_kvm_vm_init(lcore_id);
> > -     case PM_ENV_PSTATE_CPUFREQ:
> > -             return power_pstate_cpufreq_init(lcore_id);
> > -     case PM_ENV_CPPC_CPUFREQ:
> > -             return power_cppc_cpufreq_init(lcore_id);
> > -     case PM_ENV_AMD_PSTATE_CPUFREQ:
> > -             return power_amd_pstate_cpufreq_init(lcore_id);
> > -     default:
> > -             POWER_LOG(INFO, "Env isn't set yet!");
> > +     if (global_default_env != PM_ENV_NOT_SET) {
> > +             ops = &rte_power_ops[global_default_env];
> > +             if (!ops->status) {
> > +                     POWER_LOG(ERR, "Power management env[%d] not"
> > +                             " supported\n", global_default_env);
> > +                     goto out;
> > +             }
> > +             return ops->init(lcore_id);
> >       }
> > +     POWER_LOG(INFO, POWER, "Env isn't set yet!\n");
> >
> >       /* Auto detect Environment */
> > -     POWER_LOG(INFO, "Attempting to initialise ACPI cpufreq power
> management...");
> > -     ret = power_acpi_cpufreq_init(lcore_id);
> > -     if (ret == 0) {
> > -             rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
> > -             goto out;
> > +     POWER_LOG(INFO, "Attempting to initialise ACPI cpufreq"
> > +                     " power management...\n");
> > +     ops = &rte_power_ops[PM_ENV_ACPI_CPUFREQ];
> > +     if (ops->status) {
> > +             ret = ops->init(lcore_id);
> > +             if (ret == 0) {
> > +                     rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
> > +                     goto out;
> > +             }
> >       }
> >
> > -     POWER_LOG(INFO, "Attempting to initialise PSTAT power management...");
> > -     ret = power_pstate_cpufreq_init(lcore_id);
> > -     if (ret == 0) {
> > -             rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
> > -             goto out;
> > +     POWER_LOG(INFO, "Attempting to initialise PSTAT"
> > +                     " power management...\n");
> > +     ops = &rte_power_ops[PM_ENV_PSTATE_CPUFREQ];
> > +     if (ops->status) {
> > +             ret = ops->init(lcore_id);
> > +             if (ret == 0) {
> > +                     rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
> > +                     goto out;
> > +             }
> >       }
> >
> > -     POWER_LOG(INFO, "Attempting to initialise AMD PSTATE power
> management...");
> > -     ret = power_amd_pstate_cpufreq_init(lcore_id);
> > -     if (ret == 0) {
> > -             rte_power_set_env(PM_ENV_AMD_PSTATE_CPUFREQ);
> > -             goto out;
> > +     POWER_LOG(INFO, "Attempting to initialise AMD PSTATE"
> > +                     " power management...\n");
> > +     ops = &rte_power_ops[PM_ENV_AMD_PSTATE_CPUFREQ];
> > +     if (ops->status) {
> > +             ret = ops->init(lcore_id);
> > +             if (ret == 0) {
> > +                     rte_power_set_env(PM_ENV_AMD_PSTATE_CPUFREQ);
> > +                     goto out;
> > +             }
> >       }
> >
> > -     POWER_LOG(INFO, "Attempting to initialise CPPC power management...");
> > -     ret = power_cppc_cpufreq_init(lcore_id);
> > -     if (ret == 0) {
> > -             rte_power_set_env(PM_ENV_CPPC_CPUFREQ);
> > -             goto out;
> > +     POWER_LOG(INFO, "Attempting to initialise CPPC power"
> > +                     " management...\n");
> > +     ops = &rte_power_ops[PM_ENV_CPPC_CPUFREQ];
> > +     if (ops->status) {
> > +             ret = ops->init(lcore_id);
> > +             if (ret == 0) {
> > +                     rte_power_set_env(PM_ENV_CPPC_CPUFREQ);
> > +                     goto out;
> > +             }
> >       }
> >
> > -     POWER_LOG(INFO, "Attempting to initialise VM power management...");
> > -     ret = power_kvm_vm_init(lcore_id);
> > -     if (ret == 0) {
> > -             rte_power_set_env(PM_ENV_KVM_VM);
> > -             goto out;
> > +     POWER_LOG(INFO, "Attempting to initialise VM power"
> > +                     " management...\n");
> > +     ops = &rte_power_ops[PM_ENV_KVM_VM];
> > +     if (ops->status) {
> > +             ret = ops->init(lcore_id);
> > +             if (ret == 0) {
> > +                     rte_power_set_env(PM_ENV_KVM_VM);
> > +                     goto out;
> > +             }
> >       }
> If we use a linked list, above code can be simpled like this:
> ->
> for_each_power_cpufreq_ops(ops, ...) {
>      ret = ops->init()
>      if (ret) {
>          ....
>      }
> }
ACK
> > -     POWER_LOG(ERR, "Unable to set Power Management Environment for lcore "
> > -                     "%u", lcore_id);
> > +     POWER_LOG(ERR, "Unable to set Power Management Environment"
> > +                     " for lcore %u\n", lcore_id);
> >   out:
> >       return ret;
> >   }
> > @@ -237,21 +215,14 @@ rte_power_init(unsigned int lcore_id)
> >   int
> >   rte_power_exit(unsigned int lcore_id)
> >   {
> > -     switch (global_default_env) {
> > -     case PM_ENV_ACPI_CPUFREQ:
> > -             return power_acpi_cpufreq_exit(lcore_id);
> > -     case PM_ENV_KVM_VM:
> > -             return power_kvm_vm_exit(lcore_id);
> > -     case PM_ENV_PSTATE_CPUFREQ:
> > -             return power_pstate_cpufreq_exit(lcore_id);
> > -     case PM_ENV_CPPC_CPUFREQ:
> > -             return power_cppc_cpufreq_exit(lcore_id);
> > -     case PM_ENV_AMD_PSTATE_CPUFREQ:
> > -             return power_amd_pstate_cpufreq_exit(lcore_id);
> > -     default:
> > -             POWER_LOG(ERR, "Environment has not been set, unable to exit
> gracefully");
> > +     struct rte_power_ops *ops;
> >
> > +     if (global_default_env != PM_ENV_NOT_SET) {
> > +             ops = &rte_power_ops[global_default_env];
> > +             return ops->exit(lcore_id);
> >       }
> > -     return -1;
> > +     POWER_LOG(ERR, "Environment has not been set, unable "
> > +                     "to exit gracefully\n");
> >
> > +     return -1;
> >   }
> > diff --git a/lib/power/rte_power.h b/lib/power/rte_power.h index
> > 4fa4afe399..749bb823ab 100644
> > --- a/lib/power/rte_power.h
> > +++ b/lib/power/rte_power.h
> > @@ -1,5 +1,6 @@
> >   /* SPDX-License-Identifier: BSD-3-Clause
> >    * Copyright(c) 2010-2014 Intel Corporation
> > + * Copyright(c) 2024 AMD Limited
> >    */
> >
> >   #ifndef _RTE_POWER_H
> > @@ -21,7 +22,7 @@ extern "C" {
> >   /* Power Management Environment State */
> >   enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ,
> PM_ENV_KVM_VM,
> >               PM_ENV_PSTATE_CPUFREQ, PM_ENV_CPPC_CPUFREQ,
> > -             PM_ENV_AMD_PSTATE_CPUFREQ};
> > +             PM_ENV_AMD_PSTATE_CPUFREQ, PM_ENV_MAX};
> "enum power_management_env" is not good. may be like "enum
> power_cpufreq_driver_type"?
> In previous linked list structure to be defined, may be directly use a string name
> instead of a fixed enum is better.
> Becuase the new "PM_ENV_MAX" will  lead to break ABI when add a new cpufreq
> driver.
I will rework this to remove the max macro.
How changing the enum power_management_env requires ABI versioning.
Will consider this change in future.
> >
> >   /**
> >    * Check if a specific power management environment type is
> > supported on a @@ -66,6 +67,97 @@ void rte_power_unset_env(void);
> >    */
> >   enum power_management_env rte_power_get_env(void);
> >
> > +typedef int (*rte_power_cpufreq_init_t)(unsigned int lcore_id);
> > +typedef int (*rte_power_cpufreq_exit_t)(unsigned int lcore_id);
> > +typedef int (*rte_power_check_env_support_t)(void);
> > +
> > +typedef uint32_t (*rte_power_freqs_t)(unsigned int lcore_id, uint32_t *freqs,
> > +                                     uint32_t num); typedef uint32_t
> > +(*rte_power_get_freq_t)(unsigned int lcore_id); typedef int
> > +(*rte_power_set_freq_t)(unsigned int lcore_id, uint32_t index);
> > +typedef int (*rte_power_freq_change_t)(unsigned int lcore_id);
> > +
> > +/**
> > + * Function pointer definition for generic frequency change
> > +functions. Review
> > + * each environments specific documentation for usage.
> > + *
> > + * @param lcore_id
> > + *  lcore id.
> > + *
> > + * @return
> > + *  - 1 on success with frequency changed.
> > + *  - 0 on success without frequency changed.
> > + *  - Negative on error.
> > + */
> > +
> > +/**
> > + * Power capabilities summary.
> > + */
> > +struct rte_power_core_capabilities {
> > +     union {
> > +             uint64_t capabilities;
> > +             struct {
> > +                     uint64_t turbo:1;       /**< Turbo can be enabled. */
> > +                     uint64_t priority:1;    /**< SST-BF high freq core */
> > +             };
> > +     };
> > +};
> > +
> > +typedef int (*rte_power_get_capabilities_t)(unsigned int lcore_id,
> > +                             struct rte_power_core_capabilities
> > +*caps);
> > +
> > +/** Structure defining core power operations structure */ struct
> > +rte_power_ops {
> > +uint8_t status;                         /**< ops register status. */
> > +     enum power_management_env env;          /**< power mgmt env. */
> > +     rte_power_cpufreq_init_t init;    /**< Initialize power management. */
> > +     rte_power_cpufreq_exit_t exit;    /**< Exit power management. */
> > +     rte_power_check_env_support_t check_env_support; /**< verify env is
> supported. */
> > +     rte_power_freqs_t get_avail_freqs; /**< Get the available frequencies. */
> > +     rte_power_get_freq_t get_freq; /**< Get frequency index. */
> > +     rte_power_set_freq_t set_freq; /**< Set frequency index. */
> > +     rte_power_freq_change_t freq_up;   /**< Scale up frequency. */
> > +     rte_power_freq_change_t freq_down; /**< Scale down frequency. */
> > +     rte_power_freq_change_t freq_max;  /**< Scale up frequency to highest.
> */
> > +     rte_power_freq_change_t freq_min;  /**< Scale up frequency to lowest. */
> > +     rte_power_freq_change_t turbo_status; /**< Get Turbo status. */
> > +     rte_power_freq_change_t enable_turbo; /**< Enable Turbo. */
> > +     rte_power_freq_change_t disable_turbo; /**< Disable Turbo. */
> > +     rte_power_get_capabilities_t get_caps; /**< power capabilities.
> > +*/ } __rte_cache_aligned;
> Suggest that fix this sturcture, like:
> struct rte_power_cpufreq_list {
>      char name[];   // like "cppc_cpufreq", "pstate_cpufreq"
>      struct rte_power_cpufreq *ops;
>      struct rte_power_cpufreq_list *node; }
ACK
> > +
> > +/**
> > + * Register power cpu frequency operations.
> > + *
> > + * @param ops
> > + *   Pointer to an ops structure to register.
> > + * @return
> > + *   - >=0: Success; return the index of the ops struct in the table.
> > + *   - -EINVAL - error while registering ops struct.
> > + */
> > +__rte_internal
> > +int rte_power_register_ops(const struct rte_power_ops *ops);
> > +
> > +/**
> > + * Macro to statically register the ops of a cpufreq driver.
> > + */
> > +#define RTE_POWER_REGISTER_OPS(ops)          \
> > +     (RTE_INIT(power_hdlr_init_##ops)        \
> > +     {                                       \
> > +             rte_power_register_ops(&ops);   \
> > +     })
> > +
> > +/**
> > + * @internal Get the power ops struct from its index.
> > + *
> > + * @param ops_index
> > + *   The index of the ops struct in the ops struct table.
> > + * @return
> > + *   The pointer to the ops struct in the table if registered.
> > + */
> > +struct rte_power_ops *
> > +rte_power_get_ops(int ops_index);
> > +
> >   /**
> >    * Initialize power management for a specific lcore. If rte_power_set_env() has
> >    * not been called then an auto-detect of the environment will start
> > and @@ -108,10 +200,14 @@ int rte_power_exit(unsigned int lcore_id);
> >    * @return
> >    *  The number of available frequencies.
> >    */
> > -typedef uint32_t (*rte_power_freqs_t)(unsigned int lcore_id, uint32_t *freqs,
> > -             uint32_t num);
> > +static inline uint32_t
> > +rte_power_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t n) {
> > +     struct rte_power_ops *ops;
> >
> > -extern rte_power_freqs_t rte_power_freqs;
> > +     ops = rte_power_get_ops(rte_power_get_env());
> > +     return ops->get_avail_freqs(lcore_id, freqs, n); }
> nice.
> <...>

^ permalink raw reply	[relevance 3%]

* [PATCH 3/5] net/nfp: uniform function name format
    2024-03-05  2:29  4% ` [PATCH 1/5] net/nfp: create " Chaoyong He
@ 2024-03-05  2:29  3% ` Chaoyong He
  1 sibling, 0 replies; 200+ results
From: Chaoyong He @ 2024-03-05  2:29 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Long Wu, Chaoyong He

From: Long Wu <long.wu@corigine.com>

Uniform function name format and add the same prefix.

Signed-off-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
---
 drivers/net/nfp/nfd3/nfp_nfd3_dp.c |  5 ++--
 drivers/net/nfp/nfdk/nfp_nfdk_dp.c |  5 ++--
 drivers/net/nfp/nfp_net_common.c   |  2 +-
 drivers/net/nfp/nfp_net_meta.c     | 38 +++++++++++++++---------------
 drivers/net/nfp/nfp_net_meta.h     |  8 +++----
 drivers/net/nfp/nfp_rxtx.c         |  2 +-
 6 files changed, 29 insertions(+), 31 deletions(-)

diff --git a/drivers/net/nfp/nfd3/nfp_nfd3_dp.c b/drivers/net/nfp/nfd3/nfp_nfd3_dp.c
index 5fb76ae9d7..7e281ae498 100644
--- a/drivers/net/nfp/nfd3/nfp_nfd3_dp.c
+++ b/drivers/net/nfp/nfd3/nfp_nfd3_dp.c
@@ -194,8 +194,7 @@ nfp_net_nfd3_set_meta_data(struct nfp_net_meta_raw *meta_data,
 				PMD_DRV_LOG(ERR, "At most 1 layers of vlan is supported");
 				return -EINVAL;
 			}
-
-			nfp_net_set_meta_vlan(meta_data, pkt, layer);
+			nfp_net_meta_set_vlan(meta_data, pkt, layer);
 			vlan_layer++;
 			break;
 		case NFP_NET_META_IPSEC:
@@ -204,7 +203,7 @@ nfp_net_nfd3_set_meta_data(struct nfp_net_meta_raw *meta_data,
 				return -EINVAL;
 			}
 
-			nfp_net_set_meta_ipsec(meta_data, txq, pkt, layer, ipsec_layer);
+			nfp_net_meta_set_ipsec(meta_data, txq, pkt, layer, ipsec_layer);
 			ipsec_layer++;
 			break;
 		default:
diff --git a/drivers/net/nfp/nfdk/nfp_nfdk_dp.c b/drivers/net/nfp/nfdk/nfp_nfdk_dp.c
index 8bdab5d463..b8592b1767 100644
--- a/drivers/net/nfp/nfdk/nfp_nfdk_dp.c
+++ b/drivers/net/nfp/nfdk/nfp_nfdk_dp.c
@@ -228,8 +228,7 @@ nfp_net_nfdk_set_meta_data(struct rte_mbuf *pkt,
 				PMD_DRV_LOG(ERR, "At most 1 layers of vlan is supported");
 				return -EINVAL;
 			}
-
-			nfp_net_set_meta_vlan(&meta_data, pkt, layer);
+			nfp_net_meta_set_vlan(&meta_data, pkt, layer);
 			vlan_layer++;
 			break;
 		case NFP_NET_META_IPSEC:
@@ -238,7 +237,7 @@ nfp_net_nfdk_set_meta_data(struct rte_mbuf *pkt,
 				return -EINVAL;
 			}
 
-			nfp_net_set_meta_ipsec(&meta_data, txq, pkt, layer, ipsec_layer);
+			nfp_net_meta_set_ipsec(&meta_data, txq, pkt, layer, ipsec_layer);
 			ipsec_layer++;
 			break;
 		default:
diff --git a/drivers/net/nfp/nfp_net_common.c b/drivers/net/nfp/nfp_net_common.c
index 384e042dfd..71038d6be9 100644
--- a/drivers/net/nfp/nfp_net_common.c
+++ b/drivers/net/nfp/nfp_net_common.c
@@ -1312,7 +1312,7 @@ nfp_net_common_init(struct rte_pci_device *pci_dev,
 	hw->max_mtu = nn_cfg_readl(&hw->super, NFP_NET_CFG_MAX_MTU);
 	hw->flbufsz = DEFAULT_FLBUF_SIZE;
 
-	nfp_net_init_metadata_format(hw);
+	nfp_net_meta_init_format(hw);
 
 	/* Read the Rx offset configured from firmware */
 	if (hw->ver.major < 2)
diff --git a/drivers/net/nfp/nfp_net_meta.c b/drivers/net/nfp/nfp_net_meta.c
index 0fd5ba17a0..2ec20aba7d 100644
--- a/drivers/net/nfp/nfp_net_meta.c
+++ b/drivers/net/nfp/nfp_net_meta.c
@@ -17,7 +17,7 @@ enum nfp_net_meta_ipsec_layer {
 
 /* Parse the chained metadata from packet */
 static bool
-nfp_net_parse_chained_meta(uint8_t *meta_base,
+nfp_net_meta_parse_chained(uint8_t *meta_base,
 		rte_be32_t meta_header,
 		struct nfp_net_meta_parsed *meta)
 {
@@ -73,7 +73,7 @@ nfp_net_parse_chained_meta(uint8_t *meta_base,
  * Get it from metadata area.
  */
 static inline void
-nfp_net_parse_single_meta(uint8_t *meta_base,
+nfp_net_meta_parse_single(uint8_t *meta_base,
 		rte_be32_t meta_header,
 		struct nfp_net_meta_parsed *meta)
 {
@@ -83,7 +83,7 @@ nfp_net_parse_single_meta(uint8_t *meta_base,
 
 /* Set mbuf hash data based on the metadata info */
 static void
-nfp_net_parse_meta_hash(const struct nfp_net_meta_parsed *meta,
+nfp_net_meta_parse_hash(const struct nfp_net_meta_parsed *meta,
 		struct nfp_net_rxq *rxq,
 		struct rte_mbuf *mbuf)
 {
@@ -98,7 +98,7 @@ nfp_net_parse_meta_hash(const struct nfp_net_meta_parsed *meta,
 
 /* Set mbuf vlan_strip data based on metadata info */
 static void
-nfp_net_parse_meta_vlan(const struct nfp_net_meta_parsed *meta,
+nfp_net_meta_parse_vlan(const struct nfp_net_meta_parsed *meta,
 		struct nfp_net_rx_desc *rxd,
 		struct nfp_net_rxq *rxq,
 		struct rte_mbuf *mb)
@@ -146,7 +146,7 @@ nfp_net_parse_meta_vlan(const struct nfp_net_meta_parsed *meta,
  * qinq not set & vlan not set: meta->vlan_layer=0
  */
 static void
-nfp_net_parse_meta_qinq(const struct nfp_net_meta_parsed *meta,
+nfp_net_meta_parse_qinq(const struct nfp_net_meta_parsed *meta,
 		struct nfp_net_rxq *rxq,
 		struct rte_mbuf *mb)
 {
@@ -175,7 +175,7 @@ nfp_net_parse_meta_qinq(const struct nfp_net_meta_parsed *meta,
  * Extract and decode metadata info and set the mbuf ol_flags.
  */
 static void
-nfp_net_parse_meta_ipsec(struct nfp_net_meta_parsed *meta,
+nfp_net_meta_parse_ipsec(struct nfp_net_meta_parsed *meta,
 		struct nfp_net_rxq *rxq,
 		struct rte_mbuf *mbuf)
 {
@@ -202,7 +202,7 @@ nfp_net_parse_meta_ipsec(struct nfp_net_meta_parsed *meta,
 }
 
 static void
-nfp_net_parse_meta_mark(const struct nfp_net_meta_parsed *meta,
+nfp_net_meta_parse_mark(const struct nfp_net_meta_parsed *meta,
 		struct rte_mbuf *mbuf)
 {
 	if (((meta->flags >> NFP_NET_META_MARK) & 0x1) == 0)
@@ -214,7 +214,7 @@ nfp_net_parse_meta_mark(const struct nfp_net_meta_parsed *meta,
 
 /* Parse the metadata from packet */
 void
-nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
+nfp_net_meta_parse(struct nfp_net_rx_desc *rxds,
 		struct nfp_net_rxq *rxq,
 		struct nfp_net_hw *hw,
 		struct rte_mbuf *mb,
@@ -231,20 +231,20 @@ nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
 
 	switch (hw->meta_format) {
 	case NFP_NET_METAFORMAT_CHAINED:
-		if (nfp_net_parse_chained_meta(meta_base, meta_header, meta)) {
-			nfp_net_parse_meta_hash(meta, rxq, mb);
-			nfp_net_parse_meta_vlan(meta, rxds, rxq, mb);
-			nfp_net_parse_meta_qinq(meta, rxq, mb);
-			nfp_net_parse_meta_ipsec(meta, rxq, mb);
-			nfp_net_parse_meta_mark(meta, mb);
+		if (nfp_net_meta_parse_chained(meta_base, meta_header, meta)) {
+			nfp_net_meta_parse_hash(meta, rxq, mb);
+			nfp_net_meta_parse_vlan(meta, rxds, rxq, mb);
+			nfp_net_meta_parse_qinq(meta, rxq, mb);
+			nfp_net_meta_parse_ipsec(meta, rxq, mb);
+			nfp_net_meta_parse_mark(meta, mb);
 		} else {
 			PMD_RX_LOG(DEBUG, "RX chained metadata format is wrong!");
 		}
 		break;
 	case NFP_NET_METAFORMAT_SINGLE:
 		if ((rxds->rxd.flags & PCIE_DESC_RX_RSS) != 0) {
-			nfp_net_parse_single_meta(meta_base, meta_header, meta);
-			nfp_net_parse_meta_hash(meta, rxq, mb);
+			nfp_net_meta_parse_single(meta_base, meta_header, meta);
+			nfp_net_meta_parse_hash(meta, rxq, mb);
 		}
 		break;
 	default:
@@ -253,7 +253,7 @@ nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
 }
 
 void
-nfp_net_init_metadata_format(struct nfp_net_hw *hw)
+nfp_net_meta_init_format(struct nfp_net_hw *hw)
 {
 	/*
 	 * ABI 4.x and ctrl vNIC always use chained metadata, in other cases we allow use of
@@ -276,7 +276,7 @@ nfp_net_init_metadata_format(struct nfp_net_hw *hw)
 }
 
 void
-nfp_net_set_meta_vlan(struct nfp_net_meta_raw *meta_data,
+nfp_net_meta_set_vlan(struct nfp_net_meta_raw *meta_data,
 		struct rte_mbuf *pkt,
 		uint8_t layer)
 {
@@ -290,7 +290,7 @@ nfp_net_set_meta_vlan(struct nfp_net_meta_raw *meta_data,
 }
 
 void
-nfp_net_set_meta_ipsec(struct nfp_net_meta_raw *meta_data,
+nfp_net_meta_set_ipsec(struct nfp_net_meta_raw *meta_data,
 		struct nfp_net_txq *txq,
 		struct rte_mbuf *pkt,
 		uint8_t layer,
diff --git a/drivers/net/nfp/nfp_net_meta.h b/drivers/net/nfp/nfp_net_meta.h
index 46caa777da..1d26b089d5 100644
--- a/drivers/net/nfp/nfp_net_meta.h
+++ b/drivers/net/nfp/nfp_net_meta.h
@@ -90,16 +90,16 @@ struct nfp_net_meta_parsed {
 	} vlan[NFP_NET_META_MAX_VLANS];
 };
 
-void nfp_net_init_metadata_format(struct nfp_net_hw *hw);
-void nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
+void nfp_net_meta_init_format(struct nfp_net_hw *hw);
+void nfp_net_meta_parse(struct nfp_net_rx_desc *rxds,
 		struct nfp_net_rxq *rxq,
 		struct nfp_net_hw *hw,
 		struct rte_mbuf *mb,
 		struct nfp_net_meta_parsed *meta);
-void nfp_net_set_meta_vlan(struct nfp_net_meta_raw *meta_data,
+void nfp_net_meta_set_vlan(struct nfp_net_meta_raw *meta_data,
 		struct rte_mbuf *pkt,
 		uint8_t layer);
-void nfp_net_set_meta_ipsec(struct nfp_net_meta_raw *meta_data,
+void nfp_net_meta_set_ipsec(struct nfp_net_meta_raw *meta_data,
 		struct nfp_net_txq *txq,
 		struct rte_mbuf *pkt,
 		uint8_t layer,
diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c
index e863c42039..716a6af34f 100644
--- a/drivers/net/nfp/nfp_rxtx.c
+++ b/drivers/net/nfp/nfp_rxtx.c
@@ -498,7 +498,7 @@ nfp_net_recv_pkts(void *rx_queue,
 		mb->port = rxq->port_id;
 
 		struct nfp_net_meta_parsed meta = {};
-		nfp_net_parse_meta(rxds, rxq, hw, mb, &meta);
+		nfp_net_meta_parse(rxds, rxq, hw, mb, &meta);
 
 		nfp_net_parse_ptype(rxq, rxds, mb);
 
-- 
2.39.1


^ permalink raw reply	[relevance 3%]

* [PATCH 1/5] net/nfp: create new meta data module
  @ 2024-03-05  2:29  4% ` Chaoyong He
  2024-03-05  2:29  3% ` [PATCH 3/5] net/nfp: uniform function name format Chaoyong He
  1 sibling, 0 replies; 200+ results
From: Chaoyong He @ 2024-03-05  2:29 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Long Wu, Chaoyong He

From: Long Wu <long.wu@corigine.com>

Move the Rx meta data code to new 'nfp_net_meta' module, which
makes related logic more clean and the code architecture more
reasonable.
There is no functional change, just moving verbatim code around.

Signed-off-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
---
 drivers/common/nfp/nfp_common_ctrl.h     |  41 ---
 drivers/net/nfp/flower/nfp_flower.c      |   1 +
 drivers/net/nfp/flower/nfp_flower_cmsg.c |   1 +
 drivers/net/nfp/flower/nfp_flower_ctrl.c |   1 +
 drivers/net/nfp/meson.build              |   1 +
 drivers/net/nfp/nfd3/nfp_nfd3_dp.c       |   1 +
 drivers/net/nfp/nfdk/nfp_nfdk_dp.c       |   1 +
 drivers/net/nfp/nfp_ipsec.c              |   1 +
 drivers/net/nfp/nfp_ipsec.h              |   6 -
 drivers/net/nfp/nfp_net_common.c         |  24 +-
 drivers/net/nfp/nfp_net_common.h         |   7 +-
 drivers/net/nfp/nfp_net_meta.c           | 320 +++++++++++++++++++++++
 drivers/net/nfp/nfp_net_meta.h           | 108 ++++++++
 drivers/net/nfp/nfp_rxtx.c               | 305 +--------------------
 drivers/net/nfp/nfp_rxtx.h               |  20 --
 15 files changed, 438 insertions(+), 400 deletions(-)
 create mode 100644 drivers/net/nfp/nfp_net_meta.c
 create mode 100644 drivers/net/nfp/nfp_net_meta.h

diff --git a/drivers/common/nfp/nfp_common_ctrl.h b/drivers/common/nfp/nfp_common_ctrl.h
index 7749ba6459..6badf769fc 100644
--- a/drivers/common/nfp/nfp_common_ctrl.h
+++ b/drivers/common/nfp/nfp_common_ctrl.h
@@ -13,47 +13,6 @@
  */
 #define NFP_NET_CFG_BAR_SZ              (32 * 1024)
 
-/* Offset in Freelist buffer where packet starts on RX */
-#define NFP_NET_RX_OFFSET               32
-
-/* Working with metadata api (NFD version > 3.0) */
-#define NFP_NET_META_FIELD_SIZE         4
-#define NFP_NET_META_FIELD_MASK ((1 << NFP_NET_META_FIELD_SIZE) - 1)
-#define NFP_NET_META_HEADER_SIZE        4
-#define NFP_NET_META_NFDK_LENGTH        8
-
-/* Working with metadata vlan api (NFD version >= 2.0) */
-#define NFP_NET_META_VLAN_INFO          16
-#define NFP_NET_META_VLAN_OFFLOAD       31
-#define NFP_NET_META_VLAN_TPID          3
-#define NFP_NET_META_VLAN_MASK          ((1 << NFP_NET_META_VLAN_INFO) - 1)
-#define NFP_NET_META_VLAN_TPID_MASK     ((1 << NFP_NET_META_VLAN_TPID) - 1)
-#define NFP_NET_META_TPID(d)            (((d) >> NFP_NET_META_VLAN_INFO) & \
-						NFP_NET_META_VLAN_TPID_MASK)
-
-/* Prepend field types */
-#define NFP_NET_META_HASH               1 /* Next field carries hash type */
-#define NFP_NET_META_MARK               2
-#define NFP_NET_META_VLAN               4
-#define NFP_NET_META_PORTID             5
-#define NFP_NET_META_IPSEC              9
-
-#define NFP_META_PORT_ID_CTRL           ~0U
-
-/* Hash type prepended when a RSS hash was computed */
-#define NFP_NET_RSS_NONE                0
-#define NFP_NET_RSS_IPV4                1
-#define NFP_NET_RSS_IPV6                2
-#define NFP_NET_RSS_IPV6_EX             3
-#define NFP_NET_RSS_IPV4_TCP            4
-#define NFP_NET_RSS_IPV6_TCP            5
-#define NFP_NET_RSS_IPV6_EX_TCP         6
-#define NFP_NET_RSS_IPV4_UDP            7
-#define NFP_NET_RSS_IPV6_UDP            8
-#define NFP_NET_RSS_IPV6_EX_UDP         9
-#define NFP_NET_RSS_IPV4_SCTP           10
-#define NFP_NET_RSS_IPV6_SCTP           11
-
 /*
  * @NFP_NET_TXR_MAX:         Maximum number of TX rings
  * @NFP_NET_TXR_MASK:        Mask for TX rings
diff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c
index c6a744e868..97219ff379 100644
--- a/drivers/net/nfp/flower/nfp_flower.c
+++ b/drivers/net/nfp/flower/nfp_flower.c
@@ -16,6 +16,7 @@
 #include "../nfp_cpp_bridge.h"
 #include "../nfp_logs.h"
 #include "../nfp_mtr.h"
+#include "../nfp_net_meta.h"
 #include "nfp_flower_ctrl.h"
 #include "nfp_flower_representor.h"
 #include "nfp_flower_service.h"
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.c b/drivers/net/nfp/flower/nfp_flower_cmsg.c
index 8effe9474d..f78bfba332 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.c
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.c
@@ -7,6 +7,7 @@
 
 #include "../nfpcore/nfp_nsp.h"
 #include "../nfp_logs.h"
+#include "../nfp_net_meta.h"
 #include "nfp_flower_ctrl.h"
 #include "nfp_flower_representor.h"
 
diff --git a/drivers/net/nfp/flower/nfp_flower_ctrl.c b/drivers/net/nfp/flower/nfp_flower_ctrl.c
index bcb325d475..720a0d9495 100644
--- a/drivers/net/nfp/flower/nfp_flower_ctrl.c
+++ b/drivers/net/nfp/flower/nfp_flower_ctrl.c
@@ -10,6 +10,7 @@
 #include "../nfd3/nfp_nfd3.h"
 #include "../nfdk/nfp_nfdk.h"
 #include "../nfp_logs.h"
+#include "../nfp_net_meta.h"
 #include "nfp_flower_representor.h"
 #include "nfp_mtr.h"
 #include "nfp_flower_service.h"
diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index 959ca01844..d805644ec5 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -41,6 +41,7 @@ sources = files(
         'nfp_net_common.c',
         'nfp_net_ctrl.c',
         'nfp_net_flow.c',
+        'nfp_net_meta.c',
         'nfp_rxtx.c',
         'nfp_service.c',
 )
diff --git a/drivers/net/nfp/nfd3/nfp_nfd3_dp.c b/drivers/net/nfp/nfd3/nfp_nfd3_dp.c
index be31f4ac33..5fb76ae9d7 100644
--- a/drivers/net/nfp/nfd3/nfp_nfd3_dp.c
+++ b/drivers/net/nfp/nfd3/nfp_nfd3_dp.c
@@ -10,6 +10,7 @@
 
 #include "../flower/nfp_flower.h"
 #include "../nfp_logs.h"
+#include "../nfp_net_meta.h"
 
 /* Flags in the host TX descriptor */
 #define NFD3_DESC_TX_CSUM               RTE_BIT32(7)
diff --git a/drivers/net/nfp/nfdk/nfp_nfdk_dp.c b/drivers/net/nfp/nfdk/nfp_nfdk_dp.c
index daf5ac5b30..8bdab5d463 100644
--- a/drivers/net/nfp/nfdk/nfp_nfdk_dp.c
+++ b/drivers/net/nfp/nfdk/nfp_nfdk_dp.c
@@ -11,6 +11,7 @@
 
 #include "../flower/nfp_flower.h"
 #include "../nfp_logs.h"
+#include "../nfp_net_meta.h"
 
 #define NFDK_TX_DESC_GATHER_MAX         17
 
diff --git a/drivers/net/nfp/nfp_ipsec.c b/drivers/net/nfp/nfp_ipsec.c
index 0b815fa983..0bf146b9be 100644
--- a/drivers/net/nfp/nfp_ipsec.c
+++ b/drivers/net/nfp/nfp_ipsec.c
@@ -18,6 +18,7 @@
 #include "nfp_net_common.h"
 #include "nfp_net_ctrl.h"
 #include "nfp_rxtx.h"
+#include "nfp_net_meta.h"
 
 #define NFP_UDP_ESP_PORT            4500
 
diff --git a/drivers/net/nfp/nfp_ipsec.h b/drivers/net/nfp/nfp_ipsec.h
index d7a729398a..4ef0e196be 100644
--- a/drivers/net/nfp/nfp_ipsec.h
+++ b/drivers/net/nfp/nfp_ipsec.h
@@ -168,12 +168,6 @@ struct nfp_net_ipsec_data {
 	struct nfp_ipsec_session *sa_entries[NFP_NET_IPSEC_MAX_SA_CNT];
 };
 
-enum nfp_ipsec_meta_layer {
-	NFP_IPSEC_META_SAIDX,       /**< Order of SA index in metadata */
-	NFP_IPSEC_META_SEQLOW,      /**< Order of Sequence Number (low 32bits) in metadata */
-	NFP_IPSEC_META_SEQHI,       /**< Order of Sequence Number (high 32bits) in metadata */
-};
-
 int nfp_ipsec_init(struct rte_eth_dev *dev);
 void nfp_ipsec_uninit(struct rte_eth_dev *dev);
 
diff --git a/drivers/net/nfp/nfp_net_common.c b/drivers/net/nfp/nfp_net_common.c
index 20e628bfd1..384e042dfd 100644
--- a/drivers/net/nfp/nfp_net_common.c
+++ b/drivers/net/nfp/nfp_net_common.c
@@ -15,6 +15,7 @@
 #include "nfpcore/nfp_mip.h"
 #include "nfpcore/nfp_nsp.h"
 #include "nfp_logs.h"
+#include "nfp_net_meta.h"
 
 #define NFP_TX_MAX_SEG       UINT8_MAX
 #define NFP_TX_MAX_MTU_SEG   8
@@ -2038,29 +2039,6 @@ nfp_net_check_dma_mask(struct nfp_net_hw *hw,
 	return 0;
 }
 
-void
-nfp_net_init_metadata_format(struct nfp_net_hw *hw)
-{
-	/*
-	 * ABI 4.x and ctrl vNIC always use chained metadata, in other cases we allow use of
-	 * single metadata if only RSS(v1) is supported by hw capability, and RSS(v2)
-	 * also indicate that we are using chained metadata.
-	 */
-	if (hw->ver.major == 4) {
-		hw->meta_format = NFP_NET_METAFORMAT_CHAINED;
-	} else if ((hw->super.cap & NFP_NET_CFG_CTRL_CHAIN_META) != 0) {
-		hw->meta_format = NFP_NET_METAFORMAT_CHAINED;
-		/*
-		 * RSS is incompatible with chained metadata. hw->super.cap just represents
-		 * firmware's ability rather than the firmware's configuration. We decide
-		 * to reduce the confusion to allow us can use hw->super.cap to identify RSS later.
-		 */
-		hw->super.cap &= ~NFP_NET_CFG_CTRL_RSS;
-	} else {
-		hw->meta_format = NFP_NET_METAFORMAT_SINGLE;
-	}
-}
-
 void
 nfp_net_cfg_read_version(struct nfp_net_hw *hw)
 {
diff --git a/drivers/net/nfp/nfp_net_common.h b/drivers/net/nfp/nfp_net_common.h
index 628c0d3491..49a5a84044 100644
--- a/drivers/net/nfp/nfp_net_common.h
+++ b/drivers/net/nfp/nfp_net_common.h
@@ -16,6 +16,7 @@
 #include "nfpcore/nfp_sync.h"
 #include "nfp_net_ctrl.h"
 #include "nfp_service.h"
+#include "nfp_net_meta.h"
 
 /* Interrupt definitions */
 #define NFP_NET_IRQ_LSC_IDX             0
@@ -67,11 +68,6 @@ enum nfp_app_fw_id {
 	NFP_APP_FW_FLOWER_NIC             = 0x3,
 };
 
-enum nfp_net_meta_format {
-	NFP_NET_METAFORMAT_SINGLE,
-	NFP_NET_METAFORMAT_CHAINED,
-};
-
 /* Parsed control BAR TLV capabilities */
 struct nfp_net_tlv_caps {
 	uint32_t mbox_off;               /**< VNIC mailbox area offset */
@@ -306,7 +302,6 @@ void nfp_net_tx_desc_limits(struct nfp_net_hw *hw,
 		uint16_t *min_tx_desc,
 		uint16_t *max_tx_desc);
 int nfp_net_check_dma_mask(struct nfp_net_hw *hw, char *name);
-void nfp_net_init_metadata_format(struct nfp_net_hw *hw);
 void nfp_net_cfg_read_version(struct nfp_net_hw *hw);
 int nfp_net_firmware_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size);
 bool nfp_net_is_valid_nfd_version(struct nfp_net_fw_ver version);
diff --git a/drivers/net/nfp/nfp_net_meta.c b/drivers/net/nfp/nfp_net_meta.c
new file mode 100644
index 0000000000..0bc22b2f88
--- /dev/null
+++ b/drivers/net/nfp/nfp_net_meta.c
@@ -0,0 +1,320 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2023 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#include "nfp_net_meta.h"
+
+#include "nfp_net_common.h"
+#include "nfp_ipsec.h"
+#include "nfp_logs.h"
+
+enum nfp_ipsec_meta_layer {
+	NFP_IPSEC_META_SAIDX,       /**< Order of SA index in metadata */
+	NFP_IPSEC_META_SEQLOW,      /**< Order of Sequence Number (low 32bits) in metadata */
+	NFP_IPSEC_META_SEQHI,       /**< Order of Sequence Number (high 32bits) in metadata */
+};
+
+/* Parse the chained metadata from packet */
+static bool
+nfp_net_parse_chained_meta(uint8_t *meta_base,
+		rte_be32_t meta_header,
+		struct nfp_meta_parsed *meta)
+{
+	uint32_t meta_info;
+	uint32_t vlan_info;
+	uint8_t *meta_offset;
+
+	meta_info = rte_be_to_cpu_32(meta_header);
+	meta_offset = meta_base + 4;
+
+	for (; meta_info != 0; meta_info >>= NFP_NET_META_FIELD_SIZE, meta_offset += 4) {
+		switch (meta_info & NFP_NET_META_FIELD_MASK) {
+		case NFP_NET_META_PORTID:
+			meta->port_id = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
+			break;
+		case NFP_NET_META_HASH:
+			/* Next field type is about the hash type */
+			meta_info >>= NFP_NET_META_FIELD_SIZE;
+			/* Hash value is in the data field */
+			meta->hash = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
+			meta->hash_type = meta_info & NFP_NET_META_FIELD_MASK;
+			break;
+		case NFP_NET_META_VLAN:
+			vlan_info = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
+			meta->vlan[meta->vlan_layer].offload =
+					vlan_info >> NFP_NET_META_VLAN_OFFLOAD;
+			meta->vlan[meta->vlan_layer].tci =
+					vlan_info & NFP_NET_META_VLAN_MASK;
+			meta->vlan[meta->vlan_layer].tpid = NFP_NET_META_TPID(vlan_info);
+			meta->vlan_layer++;
+			break;
+		case NFP_NET_META_IPSEC:
+			meta->sa_idx = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
+			meta->ipsec_type = meta_info & NFP_NET_META_FIELD_MASK;
+			break;
+		case NFP_NET_META_MARK:
+			meta->flags |= (1 << NFP_NET_META_MARK);
+			meta->mark_id = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
+			break;
+		default:
+			/* Unsupported metadata can be a performance issue */
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/*
+ * Parse the single metadata
+ *
+ * The RSS hash and hash-type are prepended to the packet data.
+ * Get it from metadata area.
+ */
+static inline void
+nfp_net_parse_single_meta(uint8_t *meta_base,
+		rte_be32_t meta_header,
+		struct nfp_meta_parsed *meta)
+{
+	meta->hash_type = rte_be_to_cpu_32(meta_header);
+	meta->hash = rte_be_to_cpu_32(*(rte_be32_t *)(meta_base + 4));
+}
+
+/* Set mbuf hash data based on the metadata info */
+static void
+nfp_net_parse_meta_hash(const struct nfp_meta_parsed *meta,
+		struct nfp_net_rxq *rxq,
+		struct rte_mbuf *mbuf)
+{
+	struct nfp_net_hw *hw = rxq->hw;
+
+	if ((hw->super.ctrl & NFP_NET_CFG_CTRL_RSS_ANY) == 0)
+		return;
+
+	mbuf->hash.rss = meta->hash;
+	mbuf->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
+}
+
+/* Set mbuf vlan_strip data based on metadata info */
+static void
+nfp_net_parse_meta_vlan(const struct nfp_meta_parsed *meta,
+		struct nfp_net_rx_desc *rxd,
+		struct nfp_net_rxq *rxq,
+		struct rte_mbuf *mb)
+{
+	uint32_t ctrl = rxq->hw->super.ctrl;
+
+	/* Skip if hardware don't support setting vlan. */
+	if ((ctrl & (NFP_NET_CFG_CTRL_RXVLAN | NFP_NET_CFG_CTRL_RXVLAN_V2)) == 0)
+		return;
+
+	/*
+	 * The firmware support two ways to send the VLAN info (with priority) :
+	 * 1. Using the metadata when NFP_NET_CFG_CTRL_RXVLAN_V2 is set,
+	 * 2. Using the descriptor when NFP_NET_CFG_CTRL_RXVLAN is set.
+	 */
+	if ((ctrl & NFP_NET_CFG_CTRL_RXVLAN_V2) != 0) {
+		if (meta->vlan_layer > 0 && meta->vlan[0].offload != 0) {
+			mb->vlan_tci = rte_cpu_to_le_32(meta->vlan[0].tci);
+			mb->ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
+		}
+	} else if ((ctrl & NFP_NET_CFG_CTRL_RXVLAN) != 0) {
+		if ((rxd->rxd.flags & PCIE_DESC_RX_VLAN) != 0) {
+			mb->vlan_tci = rte_cpu_to_le_32(rxd->rxd.offload_info);
+			mb->ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
+		}
+	}
+}
+
+/*
+ * Set mbuf qinq_strip data based on metadata info
+ *
+ * The out VLAN tci are prepended to the packet data.
+ * Extract and decode it and set the mbuf fields.
+ *
+ * If both RTE_MBUF_F_RX_VLAN and NFP_NET_CFG_CTRL_RXQINQ are set, the 2 VLANs
+ *   have been stripped by the hardware and their TCIs are saved in
+ *   mbuf->vlan_tci (inner) and mbuf->vlan_tci_outer (outer).
+ * If NFP_NET_CFG_CTRL_RXQINQ is set and RTE_MBUF_F_RX_VLAN is unset, only the
+ *   outer VLAN is removed from packet data, but both tci are saved in
+ *   mbuf->vlan_tci (inner) and mbuf->vlan_tci_outer (outer).
+ *
+ * qinq set & vlan set : meta->vlan_layer>=2, meta->vlan[0].offload=1, meta->vlan[1].offload=1
+ * qinq set & vlan not set: meta->vlan_layer>=2, meta->vlan[1].offload=1,meta->vlan[0].offload=0
+ * qinq not set & vlan set: meta->vlan_layer=1, meta->vlan[0].offload=1
+ * qinq not set & vlan not set: meta->vlan_layer=0
+ */
+static void
+nfp_net_parse_meta_qinq(const struct nfp_meta_parsed *meta,
+		struct nfp_net_rxq *rxq,
+		struct rte_mbuf *mb)
+{
+	struct nfp_hw *hw = &rxq->hw->super;
+
+	if ((hw->ctrl & NFP_NET_CFG_CTRL_RXQINQ) == 0 ||
+			(hw->cap & NFP_NET_CFG_CTRL_RXQINQ) == 0)
+		return;
+
+	if (meta->vlan_layer < NFP_META_MAX_VLANS)
+		return;
+
+	if (meta->vlan[0].offload == 0)
+		mb->vlan_tci = rte_cpu_to_le_16(meta->vlan[0].tci);
+
+	mb->vlan_tci_outer = rte_cpu_to_le_16(meta->vlan[1].tci);
+	PMD_RX_LOG(DEBUG, "Received outer vlan TCI is %u inner vlan TCI is %u",
+			mb->vlan_tci_outer, mb->vlan_tci);
+	mb->ol_flags |= RTE_MBUF_F_RX_QINQ | RTE_MBUF_F_RX_QINQ_STRIPPED;
+}
+
+/*
+ * Set mbuf IPsec Offload features based on metadata info.
+ *
+ * The IPsec Offload features is prepended to the mbuf ol_flags.
+ * Extract and decode metadata info and set the mbuf ol_flags.
+ */
+static void
+nfp_net_parse_meta_ipsec(struct nfp_meta_parsed *meta,
+		struct nfp_net_rxq *rxq,
+		struct rte_mbuf *mbuf)
+{
+	int offset;
+	uint32_t sa_idx;
+	struct nfp_net_hw *hw;
+	struct nfp_tx_ipsec_desc_msg *desc_md;
+
+	hw = rxq->hw;
+	sa_idx = meta->sa_idx;
+
+	if (meta->ipsec_type != NFP_NET_META_IPSEC)
+		return;
+
+	if (sa_idx >= NFP_NET_IPSEC_MAX_SA_CNT) {
+		mbuf->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
+	} else {
+		mbuf->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD;
+		offset = hw->ipsec_data->pkt_dynfield_offset;
+		desc_md = RTE_MBUF_DYNFIELD(mbuf, offset, struct nfp_tx_ipsec_desc_msg *);
+		desc_md->sa_idx = sa_idx;
+		desc_md->enc = 0;
+	}
+}
+
+static void
+nfp_net_parse_meta_mark(const struct nfp_meta_parsed *meta,
+		struct rte_mbuf *mbuf)
+{
+	if (((meta->flags >> NFP_NET_META_MARK) & 0x1) == 0)
+		return;
+
+	mbuf->hash.fdir.hi = meta->mark_id;
+	mbuf->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
+}
+
+/* Parse the metadata from packet */
+void
+nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
+		struct nfp_net_rxq *rxq,
+		struct nfp_net_hw *hw,
+		struct rte_mbuf *mb,
+		struct nfp_meta_parsed *meta)
+{
+	uint8_t *meta_base;
+	rte_be32_t meta_header;
+
+	if (unlikely(NFP_DESC_META_LEN(rxds) == 0))
+		return;
+
+	meta_base = rte_pktmbuf_mtod_offset(mb, uint8_t *, -NFP_DESC_META_LEN(rxds));
+	meta_header = *(rte_be32_t *)meta_base;
+
+	switch (hw->meta_format) {
+	case NFP_NET_METAFORMAT_CHAINED:
+		if (nfp_net_parse_chained_meta(meta_base, meta_header, meta)) {
+			nfp_net_parse_meta_hash(meta, rxq, mb);
+			nfp_net_parse_meta_vlan(meta, rxds, rxq, mb);
+			nfp_net_parse_meta_qinq(meta, rxq, mb);
+			nfp_net_parse_meta_ipsec(meta, rxq, mb);
+			nfp_net_parse_meta_mark(meta, mb);
+		} else {
+			PMD_RX_LOG(DEBUG, "RX chained metadata format is wrong!");
+		}
+		break;
+	case NFP_NET_METAFORMAT_SINGLE:
+		if ((rxds->rxd.flags & PCIE_DESC_RX_RSS) != 0) {
+			nfp_net_parse_single_meta(meta_base, meta_header, meta);
+			nfp_net_parse_meta_hash(meta, rxq, mb);
+		}
+		break;
+	default:
+		PMD_RX_LOG(DEBUG, "RX metadata do not exist.");
+	}
+}
+
+void
+nfp_net_init_metadata_format(struct nfp_net_hw *hw)
+{
+	/*
+	 * ABI 4.x and ctrl vNIC always use chained metadata, in other cases we allow use of
+	 * single metadata if only RSS(v1) is supported by hw capability, and RSS(v2)
+	 * also indicate that we are using chained metadata.
+	 */
+	if (hw->ver.major == 4) {
+		hw->meta_format = NFP_NET_METAFORMAT_CHAINED;
+	} else if ((hw->super.cap & NFP_NET_CFG_CTRL_CHAIN_META) != 0) {
+		hw->meta_format = NFP_NET_METAFORMAT_CHAINED;
+		/*
+		 * RSS is incompatible with chained metadata. hw->super.cap just represents
+		 * firmware's ability rather than the firmware's configuration. We decide
+		 * to reduce the confusion to allow us can use hw->super.cap to identify RSS later.
+		 */
+		hw->super.cap &= ~NFP_NET_CFG_CTRL_RSS;
+	} else {
+		hw->meta_format = NFP_NET_METAFORMAT_SINGLE;
+	}
+}
+
+void
+nfp_net_set_meta_vlan(struct nfp_net_meta_raw *meta_data,
+		struct rte_mbuf *pkt,
+		uint8_t layer)
+{
+	uint16_t tpid;
+	uint16_t vlan_tci;
+
+	tpid = RTE_ETHER_TYPE_VLAN;
+	vlan_tci = pkt->vlan_tci;
+
+	meta_data->data[layer] = rte_cpu_to_be_32(tpid << 16 | vlan_tci);
+}
+
+void
+nfp_net_set_meta_ipsec(struct nfp_net_meta_raw *meta_data,
+		struct nfp_net_txq *txq,
+		struct rte_mbuf *pkt,
+		uint8_t layer,
+		uint8_t ipsec_layer)
+{
+	int offset;
+	struct nfp_net_hw *hw;
+	struct nfp_tx_ipsec_desc_msg *desc_md;
+
+	hw = txq->hw;
+	offset = hw->ipsec_data->pkt_dynfield_offset;
+	desc_md = RTE_MBUF_DYNFIELD(pkt, offset, struct nfp_tx_ipsec_desc_msg *);
+
+	switch (ipsec_layer) {
+	case NFP_IPSEC_META_SAIDX:
+		meta_data->data[layer] = desc_md->sa_idx;
+		break;
+	case NFP_IPSEC_META_SEQLOW:
+		meta_data->data[layer] = desc_md->esn.low;
+		break;
+	case NFP_IPSEC_META_SEQHI:
+		meta_data->data[layer] = desc_md->esn.hi;
+		break;
+	default:
+		break;
+	}
+}
diff --git a/drivers/net/nfp/nfp_net_meta.h b/drivers/net/nfp/nfp_net_meta.h
new file mode 100644
index 0000000000..da2091ce9f
--- /dev/null
+++ b/drivers/net/nfp/nfp_net_meta.h
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2014, 2015 Netronome Systems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef __NFP_NET_META_H__
+#define __NFP_NET_META_H__
+
+#include "nfp_rxtx.h"
+
+/* Hash type prepended when a RSS hash was computed */
+#define NFP_NET_RSS_NONE                0
+#define NFP_NET_RSS_IPV4                1
+#define NFP_NET_RSS_IPV6                2
+#define NFP_NET_RSS_IPV6_EX             3
+#define NFP_NET_RSS_IPV4_TCP            4
+#define NFP_NET_RSS_IPV6_TCP            5
+#define NFP_NET_RSS_IPV6_EX_TCP         6
+#define NFP_NET_RSS_IPV4_UDP            7
+#define NFP_NET_RSS_IPV6_UDP            8
+#define NFP_NET_RSS_IPV6_EX_UDP         9
+#define NFP_NET_RSS_IPV4_SCTP           10
+#define NFP_NET_RSS_IPV6_SCTP           11
+
+/* Offset in Freelist buffer where packet starts on RX */
+#define NFP_NET_RX_OFFSET               32
+
+/* Working with metadata api (NFD version > 3.0) */
+#define NFP_NET_META_FIELD_SIZE         4
+#define NFP_NET_META_FIELD_MASK ((1 << NFP_NET_META_FIELD_SIZE) - 1)
+#define NFP_NET_META_HEADER_SIZE        4
+#define NFP_NET_META_NFDK_LENGTH        8
+
+/* Working with metadata vlan api (NFD version >= 2.0) */
+#define NFP_NET_META_VLAN_INFO          16
+#define NFP_NET_META_VLAN_OFFLOAD       31
+#define NFP_NET_META_VLAN_TPID          3
+#define NFP_NET_META_VLAN_MASK          ((1 << NFP_NET_META_VLAN_INFO) - 1)
+#define NFP_NET_META_VLAN_TPID_MASK     ((1 << NFP_NET_META_VLAN_TPID) - 1)
+#define NFP_NET_META_TPID(d)            (((d) >> NFP_NET_META_VLAN_INFO) & \
+						NFP_NET_META_VLAN_TPID_MASK)
+
+/* Prepend field types */
+#define NFP_NET_META_HASH               1 /* Next field carries hash type */
+#define NFP_NET_META_MARK               2
+#define NFP_NET_META_VLAN               4
+#define NFP_NET_META_PORTID             5
+#define NFP_NET_META_IPSEC              9
+
+#define NFP_META_PORT_ID_CTRL           ~0U
+
+#define NFP_DESC_META_LEN(d) ((d)->rxd.meta_len_dd & PCIE_DESC_RX_META_LEN_MASK)
+
+/* Maximum number of NFP packet metadata fields. */
+#define NFP_META_MAX_FIELDS      8
+
+/* Maximum number of supported VLANs in parsed form packet metadata. */
+#define NFP_META_MAX_VLANS       2
+
+enum nfp_net_meta_format {
+	NFP_NET_METAFORMAT_SINGLE,
+	NFP_NET_METAFORMAT_CHAINED,
+};
+
+/* Describe the raw metadata format. */
+struct nfp_net_meta_raw {
+	uint32_t header; /**< Field type header (see format in nfp.rst) */
+	uint32_t data[NFP_META_MAX_FIELDS]; /**< Array of each fields data member */
+	uint8_t length; /**< Number of valid fields in @header */
+};
+
+/* Record metadata parsed from packet */
+struct nfp_meta_parsed {
+	uint32_t port_id;         /**< Port id value */
+	uint32_t sa_idx;          /**< IPsec SA index */
+	uint32_t hash;            /**< RSS hash value */
+	uint32_t mark_id;         /**< Mark id value */
+	uint16_t flags;           /**< Bitmap to indicate if meta exist */
+	uint8_t hash_type;        /**< RSS hash type */
+	uint8_t ipsec_type;       /**< IPsec type */
+	uint8_t vlan_layer;       /**< The valid number of value in @vlan[] */
+	/**
+	 * Holds information parses from NFP_NET_META_VLAN.
+	 * The inner most vlan starts at position 0
+	 */
+	struct {
+		uint8_t offload;  /**< Flag indicates whether VLAN is offloaded */
+		uint8_t tpid;     /**< Vlan TPID */
+		uint16_t tci;     /**< Vlan TCI (PCP + Priority + VID) */
+	} vlan[NFP_META_MAX_VLANS];
+};
+
+void nfp_net_init_metadata_format(struct nfp_net_hw *hw);
+void nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
+		struct nfp_net_rxq *rxq,
+		struct nfp_net_hw *hw,
+		struct rte_mbuf *mb,
+		struct nfp_meta_parsed *meta);
+void nfp_net_set_meta_vlan(struct nfp_net_meta_raw *meta_data,
+		struct rte_mbuf *pkt,
+		uint8_t layer);
+void nfp_net_set_meta_ipsec(struct nfp_net_meta_raw *meta_data,
+		struct nfp_net_txq *txq,
+		struct rte_mbuf *pkt,
+		uint8_t layer,
+		uint8_t ipsec_layer);
+
+#endif /* __NFP_NET_META_H__ */
diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c
index cbcf57d769..0256eba456 100644
--- a/drivers/net/nfp/nfp_rxtx.c
+++ b/drivers/net/nfp/nfp_rxtx.c
@@ -16,30 +16,7 @@
 
 #include "nfp_ipsec.h"
 #include "nfp_logs.h"
-
-/* Maximum number of supported VLANs in parsed form packet metadata. */
-#define NFP_META_MAX_VLANS       2
-
-/* Record metadata parsed from packet */
-struct nfp_meta_parsed {
-	uint32_t port_id;         /**< Port id value */
-	uint32_t sa_idx;          /**< IPsec SA index */
-	uint32_t hash;            /**< RSS hash value */
-	uint32_t mark_id;         /**< Mark id value */
-	uint16_t flags;           /**< Bitmap to indicate if meta exist */
-	uint8_t hash_type;        /**< RSS hash type */
-	uint8_t ipsec_type;       /**< IPsec type */
-	uint8_t vlan_layer;       /**< The valid number of value in @vlan[] */
-	/**
-	 * Holds information parses from NFP_NET_META_VLAN.
-	 * The inner most vlan starts at position 0
-	 */
-	struct {
-		uint8_t offload;  /**< Flag indicates whether VLAN is offloaded */
-		uint8_t tpid;     /**< Vlan TPID */
-		uint16_t tci;     /**< Vlan TCI (PCP + Priority + VID) */
-	} vlan[NFP_META_MAX_VLANS];
-};
+#include "nfp_net_meta.h"
 
 /*
  * The bit format and map of nfp packet type for rxd.offload_info in Rx descriptor.
@@ -254,242 +231,6 @@ nfp_net_rx_queue_count(void *rx_queue)
 	return count;
 }
 
-/* Parse the chained metadata from packet */
-static bool
-nfp_net_parse_chained_meta(uint8_t *meta_base,
-		rte_be32_t meta_header,
-		struct nfp_meta_parsed *meta)
-{
-	uint32_t meta_info;
-	uint32_t vlan_info;
-	uint8_t *meta_offset;
-
-	meta_info = rte_be_to_cpu_32(meta_header);
-	meta_offset = meta_base + 4;
-
-	for (; meta_info != 0; meta_info >>= NFP_NET_META_FIELD_SIZE, meta_offset += 4) {
-		switch (meta_info & NFP_NET_META_FIELD_MASK) {
-		case NFP_NET_META_PORTID:
-			meta->port_id = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
-			break;
-		case NFP_NET_META_HASH:
-			/* Next field type is about the hash type */
-			meta_info >>= NFP_NET_META_FIELD_SIZE;
-			/* Hash value is in the data field */
-			meta->hash = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
-			meta->hash_type = meta_info & NFP_NET_META_FIELD_MASK;
-			break;
-		case NFP_NET_META_VLAN:
-			vlan_info = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
-			meta->vlan[meta->vlan_layer].offload =
-					vlan_info >> NFP_NET_META_VLAN_OFFLOAD;
-			meta->vlan[meta->vlan_layer].tci =
-					vlan_info & NFP_NET_META_VLAN_MASK;
-			meta->vlan[meta->vlan_layer].tpid = NFP_NET_META_TPID(vlan_info);
-			meta->vlan_layer++;
-			break;
-		case NFP_NET_META_IPSEC:
-			meta->sa_idx = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
-			meta->ipsec_type = meta_info & NFP_NET_META_FIELD_MASK;
-			break;
-		case NFP_NET_META_MARK:
-			meta->flags |= (1 << NFP_NET_META_MARK);
-			meta->mark_id = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
-			break;
-		default:
-			/* Unsupported metadata can be a performance issue */
-			return false;
-		}
-	}
-
-	return true;
-}
-
-/* Set mbuf hash data based on the metadata info */
-static void
-nfp_net_parse_meta_hash(const struct nfp_meta_parsed *meta,
-		struct nfp_net_rxq *rxq,
-		struct rte_mbuf *mbuf)
-{
-	struct nfp_net_hw *hw = rxq->hw;
-
-	if ((hw->super.ctrl & NFP_NET_CFG_CTRL_RSS_ANY) == 0)
-		return;
-
-	mbuf->hash.rss = meta->hash;
-	mbuf->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
-}
-
-/*
- * Parse the single metadata
- *
- * The RSS hash and hash-type are prepended to the packet data.
- * Get it from metadata area.
- */
-static inline void
-nfp_net_parse_single_meta(uint8_t *meta_base,
-		rte_be32_t meta_header,
-		struct nfp_meta_parsed *meta)
-{
-	meta->hash_type = rte_be_to_cpu_32(meta_header);
-	meta->hash = rte_be_to_cpu_32(*(rte_be32_t *)(meta_base + 4));
-}
-
-/* Set mbuf vlan_strip data based on metadata info */
-static void
-nfp_net_parse_meta_vlan(const struct nfp_meta_parsed *meta,
-		struct nfp_net_rx_desc *rxd,
-		struct nfp_net_rxq *rxq,
-		struct rte_mbuf *mb)
-{
-	uint32_t ctrl = rxq->hw->super.ctrl;
-
-	/* Skip if hardware don't support setting vlan. */
-	if ((ctrl & (NFP_NET_CFG_CTRL_RXVLAN | NFP_NET_CFG_CTRL_RXVLAN_V2)) == 0)
-		return;
-
-	/*
-	 * The firmware support two ways to send the VLAN info (with priority) :
-	 * 1. Using the metadata when NFP_NET_CFG_CTRL_RXVLAN_V2 is set,
-	 * 2. Using the descriptor when NFP_NET_CFG_CTRL_RXVLAN is set.
-	 */
-	if ((ctrl & NFP_NET_CFG_CTRL_RXVLAN_V2) != 0) {
-		if (meta->vlan_layer > 0 && meta->vlan[0].offload != 0) {
-			mb->vlan_tci = rte_cpu_to_le_32(meta->vlan[0].tci);
-			mb->ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
-		}
-	} else if ((ctrl & NFP_NET_CFG_CTRL_RXVLAN) != 0) {
-		if ((rxd->rxd.flags & PCIE_DESC_RX_VLAN) != 0) {
-			mb->vlan_tci = rte_cpu_to_le_32(rxd->rxd.offload_info);
-			mb->ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
-		}
-	}
-}
-
-/*
- * Set mbuf qinq_strip data based on metadata info
- *
- * The out VLAN tci are prepended to the packet data.
- * Extract and decode it and set the mbuf fields.
- *
- * If both RTE_MBUF_F_RX_VLAN and NFP_NET_CFG_CTRL_RXQINQ are set, the 2 VLANs
- *   have been stripped by the hardware and their TCIs are saved in
- *   mbuf->vlan_tci (inner) and mbuf->vlan_tci_outer (outer).
- * If NFP_NET_CFG_CTRL_RXQINQ is set and RTE_MBUF_F_RX_VLAN is unset, only the
- *   outer VLAN is removed from packet data, but both tci are saved in
- *   mbuf->vlan_tci (inner) and mbuf->vlan_tci_outer (outer).
- *
- * qinq set & vlan set : meta->vlan_layer>=2, meta->vlan[0].offload=1, meta->vlan[1].offload=1
- * qinq set & vlan not set: meta->vlan_layer>=2, meta->vlan[1].offload=1,meta->vlan[0].offload=0
- * qinq not set & vlan set: meta->vlan_layer=1, meta->vlan[0].offload=1
- * qinq not set & vlan not set: meta->vlan_layer=0
- */
-static void
-nfp_net_parse_meta_qinq(const struct nfp_meta_parsed *meta,
-		struct nfp_net_rxq *rxq,
-		struct rte_mbuf *mb)
-{
-	struct nfp_hw *hw = &rxq->hw->super;
-
-	if ((hw->ctrl & NFP_NET_CFG_CTRL_RXQINQ) == 0)
-		return;
-
-	if (meta->vlan_layer < NFP_META_MAX_VLANS)
-		return;
-
-	if (meta->vlan[0].offload == 0)
-		mb->vlan_tci = rte_cpu_to_le_16(meta->vlan[0].tci);
-
-	mb->vlan_tci_outer = rte_cpu_to_le_16(meta->vlan[1].tci);
-	PMD_RX_LOG(DEBUG, "Received outer vlan TCI is %u inner vlan TCI is %u",
-			mb->vlan_tci_outer, mb->vlan_tci);
-	mb->ol_flags |= RTE_MBUF_F_RX_QINQ | RTE_MBUF_F_RX_QINQ_STRIPPED;
-}
-
-/*
- * Set mbuf IPsec Offload features based on metadata info.
- *
- * The IPsec Offload features is prepended to the mbuf ol_flags.
- * Extract and decode metadata info and set the mbuf ol_flags.
- */
-static void
-nfp_net_parse_meta_ipsec(struct nfp_meta_parsed *meta,
-		struct nfp_net_rxq *rxq,
-		struct rte_mbuf *mbuf)
-{
-	int offset;
-	uint32_t sa_idx;
-	struct nfp_net_hw *hw;
-	struct nfp_tx_ipsec_desc_msg *desc_md;
-
-	hw = rxq->hw;
-	sa_idx = meta->sa_idx;
-
-	if (meta->ipsec_type != NFP_NET_META_IPSEC)
-		return;
-
-	if (sa_idx >= NFP_NET_IPSEC_MAX_SA_CNT) {
-		mbuf->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
-	} else {
-		mbuf->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD;
-		offset = hw->ipsec_data->pkt_dynfield_offset;
-		desc_md = RTE_MBUF_DYNFIELD(mbuf, offset, struct nfp_tx_ipsec_desc_msg *);
-		desc_md->sa_idx = sa_idx;
-		desc_md->enc = 0;
-	}
-}
-
-static void
-nfp_net_parse_meta_mark(const struct nfp_meta_parsed *meta,
-		struct rte_mbuf *mbuf)
-{
-	if (((meta->flags >> NFP_NET_META_MARK) & 0x1) == 0)
-		return;
-
-	mbuf->hash.fdir.hi = meta->mark_id;
-	mbuf->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
-}
-
-/* Parse the metadata from packet */
-static void
-nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
-		struct nfp_net_rxq *rxq,
-		struct nfp_net_hw *hw,
-		struct rte_mbuf *mb,
-		struct nfp_meta_parsed *meta)
-{
-	uint8_t *meta_base;
-	rte_be32_t meta_header;
-
-	if (unlikely(NFP_DESC_META_LEN(rxds) == 0))
-		return;
-
-	meta_base = rte_pktmbuf_mtod_offset(mb, uint8_t *, -NFP_DESC_META_LEN(rxds));
-	meta_header = *(rte_be32_t *)meta_base;
-
-	switch (hw->meta_format) {
-	case NFP_NET_METAFORMAT_CHAINED:
-		if (nfp_net_parse_chained_meta(meta_base, meta_header, meta)) {
-			nfp_net_parse_meta_hash(meta, rxq, mb);
-			nfp_net_parse_meta_vlan(meta, rxds, rxq, mb);
-			nfp_net_parse_meta_qinq(meta, rxq, mb);
-			nfp_net_parse_meta_ipsec(meta, rxq, mb);
-			nfp_net_parse_meta_mark(meta, mb);
-		} else {
-			PMD_RX_LOG(DEBUG, "RX chained metadata format is wrong!");
-		}
-		break;
-	case NFP_NET_METAFORMAT_SINGLE:
-		if ((rxds->rxd.flags & PCIE_DESC_RX_RSS) != 0) {
-			nfp_net_parse_single_meta(meta_base, meta_header, meta);
-			nfp_net_parse_meta_hash(meta, rxq, mb);
-		}
-		break;
-	default:
-		PMD_RX_LOG(DEBUG, "RX metadata do not exist.");
-	}
-}
-
 /**
  * Set packet type to mbuf based on parsed structure.
  *
@@ -1038,50 +779,6 @@ nfp_net_reset_tx_queue(struct nfp_net_txq *txq)
 	txq->rd_p = 0;
 }
 
-void
-nfp_net_set_meta_vlan(struct nfp_net_meta_raw *meta_data,
-		struct rte_mbuf *pkt,
-		uint8_t layer)
-{
-	uint16_t tpid;
-	uint16_t vlan_tci;
-
-	tpid = RTE_ETHER_TYPE_VLAN;
-	vlan_tci = pkt->vlan_tci;
-
-	meta_data->data[layer] = rte_cpu_to_be_32(tpid << 16 | vlan_tci);
-}
-
-void
-nfp_net_set_meta_ipsec(struct nfp_net_meta_raw *meta_data,
-		struct nfp_net_txq *txq,
-		struct rte_mbuf *pkt,
-		uint8_t layer,
-		uint8_t ipsec_layer)
-{
-	int offset;
-	struct nfp_net_hw *hw;
-	struct nfp_tx_ipsec_desc_msg *desc_md;
-
-	hw = txq->hw;
-	offset = hw->ipsec_data->pkt_dynfield_offset;
-	desc_md = RTE_MBUF_DYNFIELD(pkt, offset, struct nfp_tx_ipsec_desc_msg *);
-
-	switch (ipsec_layer) {
-	case NFP_IPSEC_META_SAIDX:
-		meta_data->data[layer] = desc_md->sa_idx;
-		break;
-	case NFP_IPSEC_META_SEQLOW:
-		meta_data->data[layer] = desc_md->esn.low;
-		break;
-	case NFP_IPSEC_META_SEQHI:
-		meta_data->data[layer] = desc_md->esn.hi;
-		break;
-	default:
-		break;
-	}
-}
-
 int
 nfp_net_tx_queue_setup(struct rte_eth_dev *dev,
 		uint16_t queue_idx,
diff --git a/drivers/net/nfp/nfp_rxtx.h b/drivers/net/nfp/nfp_rxtx.h
index 5695a31636..6ecabc232c 100644
--- a/drivers/net/nfp/nfp_rxtx.h
+++ b/drivers/net/nfp/nfp_rxtx.h
@@ -8,18 +8,6 @@
 
 #include <ethdev_driver.h>
 
-#define NFP_DESC_META_LEN(d) ((d)->rxd.meta_len_dd & PCIE_DESC_RX_META_LEN_MASK)
-
-/* Maximum number of NFP packet metadata fields. */
-#define NFP_META_MAX_FIELDS      8
-
-/* Describe the raw metadata format. */
-struct nfp_net_meta_raw {
-	uint32_t header; /**< Field type header (see format in nfp.rst) */
-	uint32_t data[NFP_META_MAX_FIELDS]; /**< Array of each fields data member */
-	uint8_t length; /**< Number of valid fields in @header */
-};
-
 /* Descriptor alignment */
 #define NFP_ALIGN_RING_DESC 128
 
@@ -238,13 +226,5 @@ int nfp_net_tx_queue_setup(struct rte_eth_dev *dev,
 		unsigned int socket_id,
 		const struct rte_eth_txconf *tx_conf);
 uint32_t nfp_net_tx_free_bufs(struct nfp_net_txq *txq);
-void nfp_net_set_meta_vlan(struct nfp_net_meta_raw *meta_data,
-		struct rte_mbuf *pkt,
-		uint8_t layer);
-void nfp_net_set_meta_ipsec(struct nfp_net_meta_raw *meta_data,
-		struct nfp_net_txq *txq,
-		struct rte_mbuf *pkt,
-		uint8_t layer,
-		uint8_t ipsec_layer);
 
 #endif /* __NFP_RXTX_H__ */
-- 
2.39.1


^ permalink raw reply	[relevance 4%]

* [PATCH v7 27/39] mempool: use C11 alignas
  @ 2024-03-04 17:52  3%   ` Tyler Retzlaff
  0 siblings, 0 replies; 200+ results
From: Tyler Retzlaff @ 2024-03-04 17:52 UTC (permalink / raw)
  To: dev
  Cc: Andrew Rybchenko, Bruce Richardson, Chengwen Feng,
	Cristian Dumitrescu, David Christensen, David Hunt, Ferruh Yigit,
	Honnappa Nagarahalli, Jasvinder Singh, Jerin Jacob, Kevin Laatz,
	Konstantin Ananyev, Min Zhou, Ruifeng Wang, Sameh Gobriel,
	Stanislaw Kardach, Thomas Monjalon, Vladimir Medvedkin,
	Yipeng Wang, Tyler Retzlaff

The current location used for __rte_aligned(a) for alignment of types
and variables is not compatible with MSVC. There is only a single
location accepted by both toolchains.

For variables standard C11 offers alignas(a) supported by conformant
compilers i.e. both MSVC and GCC.

For types the standard offers no alignment facility that compatibly
interoperates with C and C++ but may be achieved by relocating the
placement of __rte_aligned(a) to the aforementioned location accepted
by all currently supported toolchains.

To allow alignment for both compilers do the following:

* Move __rte_aligned from the end of {struct,union} definitions to
  be between {struct,union} and tag.

  The placement between {struct,union} and the tag allows the desired
  alignment to be imparted on the type regardless of the toolchain being
  used for all of GCC, LLVM, MSVC compilers building both C and C++.

* Replace use of __rte_aligned(a) on variables/fields with alignas(a).

Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
Acked-by: Morten Brørup <mb@smartsharesystems.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@huawei.com>
---
 lib/mempool/rte_mempool.h | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/lib/mempool/rte_mempool.h b/lib/mempool/rte_mempool.h
index 6fa4d48..23fd5c8 100644
--- a/lib/mempool/rte_mempool.h
+++ b/lib/mempool/rte_mempool.h
@@ -34,6 +34,7 @@
  * user cache created with rte_mempool_cache_create().
  */
 
+#include <stdalign.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <inttypes.h>
@@ -66,7 +67,7 @@
  * captured since they can be calculated from other stats.
  * For example: put_cache_objs = put_objs - put_common_pool_objs.
  */
-struct rte_mempool_debug_stats {
+struct __rte_cache_aligned rte_mempool_debug_stats {
 	uint64_t put_bulk;             /**< Number of puts. */
 	uint64_t put_objs;             /**< Number of objects successfully put. */
 	uint64_t put_common_pool_bulk; /**< Number of bulks enqueued in common pool. */
@@ -80,13 +81,13 @@ struct rte_mempool_debug_stats {
 	uint64_t get_success_blks;     /**< Successful allocation number of contiguous blocks. */
 	uint64_t get_fail_blks;        /**< Failed allocation number of contiguous blocks. */
 	RTE_CACHE_GUARD;
-} __rte_cache_aligned;
+};
 #endif
 
 /**
  * A structure that stores a per-core object cache.
  */
-struct rte_mempool_cache {
+struct __rte_cache_aligned rte_mempool_cache {
 	uint32_t size;	      /**< Size of the cache */
 	uint32_t flushthresh; /**< Threshold before we flush excess elements */
 	uint32_t len;	      /**< Current cache count */
@@ -109,8 +110,8 @@ struct rte_mempool_cache {
 	 * Cache is allocated to this size to allow it to overflow in certain
 	 * cases to avoid needless emptying of cache.
 	 */
-	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2] __rte_cache_aligned;
-} __rte_cache_aligned;
+	alignas(RTE_CACHE_LINE_SIZE) void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2];
+};
 
 /**
  * A structure that stores the size of mempool elements.
@@ -218,15 +219,15 @@ struct rte_mempool_memhdr {
  * The structure is cache-line aligned to avoid ABI breakages in
  * a number of cases when something small is added.
  */
-struct rte_mempool_info {
+struct __rte_cache_aligned rte_mempool_info {
 	/** Number of objects in the contiguous block */
 	unsigned int contig_block_size;
-} __rte_cache_aligned;
+};
 
 /**
  * The RTE mempool structure.
  */
-struct rte_mempool {
+struct __rte_cache_aligned rte_mempool {
 	char name[RTE_MEMPOOL_NAMESIZE]; /**< Name of mempool. */
 	union {
 		void *pool_data;         /**< Ring or pool to store objects. */
@@ -268,7 +269,7 @@ struct rte_mempool {
 	 */
 	struct rte_mempool_debug_stats stats[RTE_MAX_LCORE + 1];
 #endif
-}  __rte_cache_aligned;
+};
 
 /** Spreading among memory channels not required. */
 #define RTE_MEMPOOL_F_NO_SPREAD		0x0001
@@ -688,7 +689,7 @@ typedef int (*rte_mempool_get_info_t)(const struct rte_mempool *mp,
 
 
 /** Structure defining mempool operations structure */
-struct rte_mempool_ops {
+struct __rte_cache_aligned rte_mempool_ops {
 	char name[RTE_MEMPOOL_OPS_NAMESIZE]; /**< Name of mempool ops struct. */
 	rte_mempool_alloc_t alloc;       /**< Allocate private data. */
 	rte_mempool_free_t free;         /**< Free the external pool. */
@@ -713,7 +714,7 @@ struct rte_mempool_ops {
 	 * Dequeue a number of contiguous object blocks.
 	 */
 	rte_mempool_dequeue_contig_blocks_t dequeue_contig_blocks;
-} __rte_cache_aligned;
+};
 
 #define RTE_MEMPOOL_MAX_OPS_IDX 16  /**< Max registered ops structs */
 
@@ -726,14 +727,14 @@ struct rte_mempool_ops {
  * any function pointers stored directly in the mempool struct would not be.
  * This results in us simply having "ops_index" in the mempool struct.
  */
-struct rte_mempool_ops_table {
+struct __rte_cache_aligned rte_mempool_ops_table {
 	rte_spinlock_t sl;     /**< Spinlock for add/delete. */
 	uint32_t num_ops;      /**< Number of used ops structs in the table. */
 	/**
 	 * Storage for all possible ops structs.
 	 */
 	struct rte_mempool_ops ops[RTE_MEMPOOL_MAX_OPS_IDX];
-} __rte_cache_aligned;
+};
 
 /** Array of registered ops structs. */
 extern struct rte_mempool_ops_table rte_mempool_ops_table;
-- 
1.8.3.1


^ permalink raw reply	[relevance 3%]

* RE: [PATCH 0/7] add Nitrox compress device support
  2024-03-02  9:38  3% Nagadheeraj Rottela
@ 2024-03-04  7:14  0% ` Akhil Goyal
  0 siblings, 0 replies; 200+ results
From: Akhil Goyal @ 2024-03-04  7:14 UTC (permalink / raw)
  To: Nagadheeraj Rottela, fanzhang.oss, Ashish Gupta; +Cc: dev, Nagadheeraj Rottela

> Subject: [PATCH 0/7] add Nitrox compress device support
> 
> Add the Nitrox PMD to support Nitrox compress device.
> ---
> v5:
> * Added missing entry for nitrox folder in compress meson.json
> 
> v4:
> * Fixed checkpatch warnings.
> * Updated release notes.
> 
> v3:
> * Fixed ABI compatibility issue.
> 
> v2:
> * Reformatted patches to minimize number of changes.
> * Removed empty file with only copyright.
> * Updated all feature flags in nitrox.ini file.
> * Added separate gotos in nitrox_pci_probe() function.
> 
> Nagadheeraj Rottela (7):
>   crypto/nitrox: move common code
>   drivers/compress: add Nitrox driver
>   common/nitrox: add compress hardware queue management
>   crypto/nitrox: set queue type during queue pair setup
>   compress/nitrox: add software queue management
>   compress/nitrox: support stateless request
>   compress/nitrox: support stateful request
> 
>  MAINTAINERS                                   |    8 +
>  doc/guides/compressdevs/features/nitrox.ini   |   17 +
>  doc/guides/compressdevs/index.rst             |    1 +
>  doc/guides/compressdevs/nitrox.rst            |   50 +
>  doc/guides/rel_notes/release_24_03.rst        |    3 +
>  drivers/common/nitrox/meson.build             |   19 +
>  .../{crypto => common}/nitrox/nitrox_csr.h    |   12 +
>  .../{crypto => common}/nitrox/nitrox_device.c |   51 +-
>  .../{crypto => common}/nitrox/nitrox_device.h |    4 +-
>  .../{crypto => common}/nitrox/nitrox_hal.c    |  116 ++
>  .../{crypto => common}/nitrox/nitrox_hal.h    |  115 ++
>  .../{crypto => common}/nitrox/nitrox_logs.c   |    0
>  .../{crypto => common}/nitrox/nitrox_logs.h   |    0
>  drivers/{crypto => common}/nitrox/nitrox_qp.c |   56 +-
>  drivers/{crypto => common}/nitrox/nitrox_qp.h |   60 +-
>  drivers/common/nitrox/version.map             |    9 +
>  drivers/compress/meson.build                  |    1 +
>  drivers/compress/nitrox/meson.build           |   16 +
>  drivers/compress/nitrox/nitrox_comp.c         |  604 +++++++++
>  drivers/compress/nitrox/nitrox_comp.h         |   35 +
>  drivers/compress/nitrox/nitrox_comp_reqmgr.c  | 1194 +++++++++++++++++
>  drivers/compress/nitrox/nitrox_comp_reqmgr.h  |   58 +
>  drivers/crypto/nitrox/meson.build             |   11 +-
>  drivers/crypto/nitrox/nitrox_sym.c            |    1 +
>  drivers/meson.build                           |    1 +
>  25 files changed, 2412 insertions(+), 30 deletions(-)
>  create mode 100644 doc/guides/compressdevs/features/nitrox.ini
>  create mode 100644 doc/guides/compressdevs/nitrox.rst
>  create mode 100644 drivers/common/nitrox/meson.build
>  rename drivers/{crypto => common}/nitrox/nitrox_csr.h (67%)
>  rename drivers/{crypto => common}/nitrox/nitrox_device.c (77%)
>  rename drivers/{crypto => common}/nitrox/nitrox_device.h (81%)
>  rename drivers/{crypto => common}/nitrox/nitrox_hal.c (65%)
>  rename drivers/{crypto => common}/nitrox/nitrox_hal.h (59%)
>  rename drivers/{crypto => common}/nitrox/nitrox_logs.c (100%)
>  rename drivers/{crypto => common}/nitrox/nitrox_logs.h (100%)
>  rename drivers/{crypto => common}/nitrox/nitrox_qp.c (67%)
>  rename drivers/{crypto => common}/nitrox/nitrox_qp.h (55%)
>  create mode 100644 drivers/common/nitrox/version.map
>  create mode 100644 drivers/compress/nitrox/meson.build
>  create mode 100644 drivers/compress/nitrox/nitrox_comp.c
>  create mode 100644 drivers/compress/nitrox/nitrox_comp.h
>  create mode 100644 drivers/compress/nitrox/nitrox_comp_reqmgr.c
>  create mode 100644 drivers/compress/nitrox/nitrox_comp_reqmgr.h
> 
Applied to dpdk-next-crypto.

Reworked and moved release notes changes to last patch.

^ permalink raw reply	[relevance 0%]

* [RFC 0/7] Improve EAL bit operations API
@ 2024-03-02 13:53  2% Mattias Rönnblom
  0 siblings, 0 replies; 200+ results
From: Mattias Rönnblom @ 2024-03-02 13:53 UTC (permalink / raw)
  To: dev; +Cc: hofors, Heng Wang, Mattias Rönnblom

This patch set represent an attempt to improve and extend the RTE
bitops API, in particular for functions that operate on individual
bits.

RFCv1 is submitted primarily to 1) receive general feedback on if
improvements in this area is worth working on, and 2) receive feedback
on the API.

No test cases are included in v1 and the various functions may well
not do what they are intended to.

The legacy <rte_bitops.h> rte_bit_relaxed_*() family of functions is
replaced with three families:

rte_bit_[test|set|clear|assign][32|64]() which provides no memory
ordering or atomicity guarantees and no read-once or write-once
semantics (e.g., no use of volatile), but does provide the best
performance. The performance degradation resulting from the use of
volatile (e.g., forcing loads and stores to actually occur and in the
number specified) and atomic (e.g., LOCK instructions on x86) may be a
significant.

rte_bit_once_*() which guarantees program-level load and stores
actually occurring (i.e., prevents certain optimizations). The primary
use of these functions are in the context of memory mapped
I/O. Feedback on the details (semantics, naming) here would be greatly
appreciated, since the author is not much of a driver developer.

rte_bit_atomic_*() which provides atomic bit-level operations,
including the possibility to specifying memory ordering constraints
(or the lack thereof).

The atomic functions take non-_Atomic pointers, to be flexible, just
like the GCC builtins and default <rte_stdatomic.h>. The issue with
_Atomic APIs is that it may well be the case that the user wants to
perform both non-atomic and atomic operations on the same word.

Having _Atomic-marked addresses would complicate supporting atomic
bit-level operations in the proposed bitset API (and potentially other
APIs depending on RTE bitops for atomic bit-level ops). Either one
needs two bitset variants, one _Atomic bitset and one non-atomic one,
or the bitset code needs to cast the non-_Atomic pointer to an _Atomic
one. Having a separate _Atomic bitset would be bloat and also prevent
the user from both, in some situations, doing atomic operations
against a bit set, while in other situations (e.g., at times when MT
safety is not a concern) operating on the same words in a non-atomic
manner. That said, all this is still unclear to the author and much
depending on the future path of DPDK atomics.

Unlike rte_bit_relaxed_*(), individual bits are represented by bool,
not uint32_t or uint64_t. The author found the use of such large types
confusing, and also failed to see any performance benefits.

A set of functions rte_bit_*_assign*() are added, to assign a
particular boolean value to a particular bit.

All functions have properly documented semantics.

All functions are available in uint32_t and uint64_t variants.

In addition, for every function there is a generic selection variant
which operates on both 32-bit and 64-bit words (depending on the
pointer type). The use of C11 generic selection is the first in the
DPDK code base.

_Generic allow the user code to be a little more impact. Have a
generic atomic test/set/clear/assign bit API also seems consistent
with the "core" (word-size) atomics API, which is generic (both GCC
builtins and <rte_stdatomic.h> are).

The _Generic versions also may avoid having explicit unsigned long
versions of all functions. If you have an unsigned long, it's safe to
use the generic version (e.g., rte_set_bit()) and _Generic will pick
the right function, provided long is either 32 or 64 bit on your
platform (which it is on all DPDK-supported ABIs).

The generic rte_bit_set() is a macro, and not a function, but
nevertheless has been given a lower-case name. That's how C11 does it
(for atomics, and other _Generic), and <rte_stdatomic.h>. Its address
can't be taken, but it does not evaluate its parameters more than
once.

Things that are left out of this patch set, that may be included
in future versions:

 * Have all functions returning a bit number have the same return type
   (i.e., unsigned int).
 * Harmonize naming of some GCC builtin wrappers (i.e., rte_fls_u32()).
 * Add __builtin_ffsll()/ffs() wrapper and potentially other wrappers
   for useful/used bit-level GCC builtins.
 * Eliminate the MSVC #ifdef-induced documentation duplication.
 * _Generic versions of things like rte_popcount32(). (?)

ABI-breaking patches should probably go into a separate patch set (?).

Mattias Rönnblom (7):
  eal: extend bit manipulation functions
  eal: add generic bit manipulation macros
  eal: add bit manipulation functions which read or write once
  eal: add generic once-type bit operations macros
  eal: add atomic bit operations
  eal: add generic atomic bit operations
  eal: deprecate relaxed family of bit operations

 lib/eal/include/rte_bitops.h | 1115 +++++++++++++++++++++++++++++++++-
 1 file changed, 1113 insertions(+), 2 deletions(-)

-- 
2.34.1


^ permalink raw reply	[relevance 2%]

* [PATCH 0/7] add Nitrox compress device support
@ 2024-03-02  9:38  3% Nagadheeraj Rottela
  2024-03-04  7:14  0% ` Akhil Goyal
  0 siblings, 1 reply; 200+ results
From: Nagadheeraj Rottela @ 2024-03-02  9:38 UTC (permalink / raw)
  To: gakhil, fanzhang.oss, ashishg; +Cc: dev, Nagadheeraj Rottela

Add the Nitrox PMD to support Nitrox compress device.
---
v5:
* Added missing entry for nitrox folder in compress meson.json

v4:
* Fixed checkpatch warnings.
* Updated release notes.

v3:
* Fixed ABI compatibility issue.

v2:
* Reformatted patches to minimize number of changes.
* Removed empty file with only copyright.
* Updated all feature flags in nitrox.ini file.
* Added separate gotos in nitrox_pci_probe() function.

Nagadheeraj Rottela (7):
  crypto/nitrox: move common code
  drivers/compress: add Nitrox driver
  common/nitrox: add compress hardware queue management
  crypto/nitrox: set queue type during queue pair setup
  compress/nitrox: add software queue management
  compress/nitrox: support stateless request
  compress/nitrox: support stateful request

 MAINTAINERS                                   |    8 +
 doc/guides/compressdevs/features/nitrox.ini   |   17 +
 doc/guides/compressdevs/index.rst             |    1 +
 doc/guides/compressdevs/nitrox.rst            |   50 +
 doc/guides/rel_notes/release_24_03.rst        |    3 +
 drivers/common/nitrox/meson.build             |   19 +
 .../{crypto => common}/nitrox/nitrox_csr.h    |   12 +
 .../{crypto => common}/nitrox/nitrox_device.c |   51 +-
 .../{crypto => common}/nitrox/nitrox_device.h |    4 +-
 .../{crypto => common}/nitrox/nitrox_hal.c    |  116 ++
 .../{crypto => common}/nitrox/nitrox_hal.h    |  115 ++
 .../{crypto => common}/nitrox/nitrox_logs.c   |    0
 .../{crypto => common}/nitrox/nitrox_logs.h   |    0
 drivers/{crypto => common}/nitrox/nitrox_qp.c |   56 +-
 drivers/{crypto => common}/nitrox/nitrox_qp.h |   60 +-
 drivers/common/nitrox/version.map             |    9 +
 drivers/compress/meson.build                  |    1 +
 drivers/compress/nitrox/meson.build           |   16 +
 drivers/compress/nitrox/nitrox_comp.c         |  604 +++++++++
 drivers/compress/nitrox/nitrox_comp.h         |   35 +
 drivers/compress/nitrox/nitrox_comp_reqmgr.c  | 1194 +++++++++++++++++
 drivers/compress/nitrox/nitrox_comp_reqmgr.h  |   58 +
 drivers/crypto/nitrox/meson.build             |   11 +-
 drivers/crypto/nitrox/nitrox_sym.c            |    1 +
 drivers/meson.build                           |    1 +
 25 files changed, 2412 insertions(+), 30 deletions(-)
 create mode 100644 doc/guides/compressdevs/features/nitrox.ini
 create mode 100644 doc/guides/compressdevs/nitrox.rst
 create mode 100644 drivers/common/nitrox/meson.build
 rename drivers/{crypto => common}/nitrox/nitrox_csr.h (67%)
 rename drivers/{crypto => common}/nitrox/nitrox_device.c (77%)
 rename drivers/{crypto => common}/nitrox/nitrox_device.h (81%)
 rename drivers/{crypto => common}/nitrox/nitrox_hal.c (65%)
 rename drivers/{crypto => common}/nitrox/nitrox_hal.h (59%)
 rename drivers/{crypto => common}/nitrox/nitrox_logs.c (100%)
 rename drivers/{crypto => common}/nitrox/nitrox_logs.h (100%)
 rename drivers/{crypto => common}/nitrox/nitrox_qp.c (67%)
 rename drivers/{crypto => common}/nitrox/nitrox_qp.h (55%)
 create mode 100644 drivers/common/nitrox/version.map
 create mode 100644 drivers/compress/nitrox/meson.build
 create mode 100644 drivers/compress/nitrox/nitrox_comp.c
 create mode 100644 drivers/compress/nitrox/nitrox_comp.h
 create mode 100644 drivers/compress/nitrox/nitrox_comp_reqmgr.c
 create mode 100644 drivers/compress/nitrox/nitrox_comp_reqmgr.h

-- 
2.42.0


^ permalink raw reply	[relevance 3%]

* [PATCH 0/7] add Nitrox compress device support
@ 2024-03-01 16:25  3% Nagadheeraj Rottela
  0 siblings, 0 replies; 200+ results
From: Nagadheeraj Rottela @ 2024-03-01 16:25 UTC (permalink / raw)
  To: gakhil, fanzhang.oss, ashishg; +Cc: dev, Nagadheeraj Rottela

Add the Nitrox PMD to support Nitrox compress device.
---
v4:
* Fixed checkpatch warnings.
* Updated release notes.

v3:
* Fixed ABI compatibility issue.

v2:
* Reformatted patches to minimize number of changes.
* Removed empty file with only copyright.
* Updated all feature flags in nitrox.ini file.
* Added separate gotos in nitrox_pci_probe() function.

Nagadheeraj Rottela (7):
  crypto/nitrox: move common code
  drivers/compress: add Nitrox driver
  common/nitrox: add compress hardware queue management
  crypto/nitrox: set queue type during queue pair setup
  compress/nitrox: add software queue management
  compress/nitrox: support stateless request
  compress/nitrox: support stateful request

 MAINTAINERS                                   |    8 +
 doc/guides/compressdevs/features/nitrox.ini   |   17 +
 doc/guides/compressdevs/index.rst             |    1 +
 doc/guides/compressdevs/nitrox.rst            |   50 +
 doc/guides/rel_notes/release_24_03.rst        |    3 +
 drivers/common/nitrox/meson.build             |   19 +
 .../{crypto => common}/nitrox/nitrox_csr.h    |   12 +
 .../{crypto => common}/nitrox/nitrox_device.c |   51 +-
 .../{crypto => common}/nitrox/nitrox_device.h |    4 +-
 .../{crypto => common}/nitrox/nitrox_hal.c    |  116 ++
 .../{crypto => common}/nitrox/nitrox_hal.h    |  115 ++
 .../{crypto => common}/nitrox/nitrox_logs.c   |    0
 .../{crypto => common}/nitrox/nitrox_logs.h   |    0
 drivers/{crypto => common}/nitrox/nitrox_qp.c |   56 +-
 drivers/{crypto => common}/nitrox/nitrox_qp.h |   60 +-
 drivers/common/nitrox/version.map             |    9 +
 drivers/compress/nitrox/meson.build           |   16 +
 drivers/compress/nitrox/nitrox_comp.c         |  604 +++++++++
 drivers/compress/nitrox/nitrox_comp.h         |   35 +
 drivers/compress/nitrox/nitrox_comp_reqmgr.c  | 1194 +++++++++++++++++
 drivers/compress/nitrox/nitrox_comp_reqmgr.h  |   58 +
 drivers/crypto/nitrox/meson.build             |   11 +-
 drivers/crypto/nitrox/nitrox_sym.c            |    1 +
 drivers/meson.build                           |    1 +
 24 files changed, 2411 insertions(+), 30 deletions(-)
 create mode 100644 doc/guides/compressdevs/features/nitrox.ini
 create mode 100644 doc/guides/compressdevs/nitrox.rst
 create mode 100644 drivers/common/nitrox/meson.build
 rename drivers/{crypto => common}/nitrox/nitrox_csr.h (67%)
 rename drivers/{crypto => common}/nitrox/nitrox_device.c (77%)
 rename drivers/{crypto => common}/nitrox/nitrox_device.h (81%)
 rename drivers/{crypto => common}/nitrox/nitrox_hal.c (65%)
 rename drivers/{crypto => common}/nitrox/nitrox_hal.h (59%)
 rename drivers/{crypto => common}/nitrox/nitrox_logs.c (100%)
 rename drivers/{crypto => common}/nitrox/nitrox_logs.h (100%)
 rename drivers/{crypto => common}/nitrox/nitrox_qp.c (67%)
 rename drivers/{crypto => common}/nitrox/nitrox_qp.h (55%)
 create mode 100644 drivers/common/nitrox/version.map
 create mode 100644 drivers/compress/nitrox/meson.build
 create mode 100644 drivers/compress/nitrox/nitrox_comp.c
 create mode 100644 drivers/compress/nitrox/nitrox_comp.h
 create mode 100644 drivers/compress/nitrox/nitrox_comp_reqmgr.c
 create mode 100644 drivers/compress/nitrox/nitrox_comp_reqmgr.h

-- 
2.42.0


^ permalink raw reply	[relevance 3%]

* RE: [EXTERNAL] Re: [EXT] Re: [PATCH v2] app/dma-perf: support bi-directional transfer
  2024-03-01  9:30  0%             ` fengchengwen
@ 2024-03-01 10:59  0%               ` Amit Prakash Shukla
  0 siblings, 0 replies; 200+ results
From: Amit Prakash Shukla @ 2024-03-01 10:59 UTC (permalink / raw)
  To: fengchengwen, Cheng Jiang, Gowrishankar Muthukrishnan
  Cc: dev, Jerin Jacob, Anoob Joseph, Kevin Laatz, Bruce Richardson,
	Pavan Nikhilesh Bhagavatula

Hi Chengwen,

Please find my reply in-line.

Thanks,
Amit Shukla

> Hi Amit,
> 
> On 2024/3/1 16:31, Amit Prakash Shukla wrote:
> > Hi Chengwen,
> >
> > If I'm not wrong, your concern was about config file additions and not
> > about the test as such. If the config file is getting complicated and
> > there are better alternatives, we can minimize the config file changes
> > with this patch and just provide minimum functionality as required and
> > leave it open for future changes. For now, I can document the existing
> > behavior in documentation as "Constraints". Similar approach is
> > followed in other application such as ipsec-secgw
> > https://urldefense.proofpoint.com/v2/url?u=https-3A__doc.dpdk.org_guid
> > es_sample-5Fapp-5Fug_ipsec-5Fsecgw.html-
> 23constraints&d=DwICaQ&c=nKjWe
> >
> c2b6R0mOyPaz7xtfQ&r=ALGdXl3fZgFGR69VnJLdSnADun7zLaXG1p5Rs7pXihE
> &m=UXlZ
> >
> 1CWj8uotMMmYQ4e7wtBXj4geBwcMUirlqFw0pZzSlOIIAVjWaPgcaXtni370&
> s=haaehrX
> > QSEG6EFRW8w2sHKUTU75aJX7ML8vM-0mJsAI&e=
> 
> Yes, I prefer enable different test just by modify configuration file, and then
> limit the number of entries at the same time.
> 
> This commit is bi-direction transfer, it is fixed, maybe later we should test 3/4
> for mem2dev while 1/4 for dev2mem.

Agreed. We will add this later after the base functionality is merged. I will send next version with constraints listed. Can I assume next version is good for merge?

> 
> sometime we may need evaluate performance of one dma channel for
> mem2mem, while another channel for mem2dev, we can't do this in current
> implement (because vchan_dev is for all DMA channel).

We are okay with extending it later. As you said, we are still deciding how the configuration file should look like.

> 
> So I prefer restrict DMA non-mem2mem's config (include
> dir/type/coreid/pfid/vfid/raddr) as the dma device's private configuration.
> 
> Thanks
> 
> >
> > Constraints:
> > 1. vchan_dev config will be same for all the configured DMA devices.
> > 2. Alternate DMA device will do dev2mem and mem2dev implicitly.
> > Example:
> > xfer_mode=1
> > vchan_dev=raddr=0x200000000,coreid=1,pfid=2,vfid=3
> > lcore_dma=lcore10@0000:00:04.2, lcore11@0000:00:04.3,
> > lcore12@0000:00:04.4, lcore13@0000:00:04.5
> >
> > lcore10@0000:00:04.2, lcore12@0000:00:04.4 will do dev2mem and
> lcore11@0000:00:04.3, lcore13@0000:00:04.5 will do mem2dev.
> >
> > Thanks,
> > Amit Shukla
> >
> >> -----Original Message-----
> >> From: fengchengwen <fengchengwen@huawei.com>
> >> Sent: Friday, March 1, 2024 7:16 AM
> >> To: Amit Prakash Shukla <amitprakashs@marvell.com>; Cheng Jiang
> >> <honest.jiang@foxmail.com>; Gowrishankar Muthukrishnan
> >> <gmuthukrishn@marvell.com>
> >> Cc: dev@dpdk.org; Jerin Jacob <jerinj@marvell.com>; Anoob Joseph
> >> <anoobj@marvell.com>; Kevin Laatz <kevin.laatz@intel.com>; Bruce
> >> Richardson <bruce.richardson@intel.com>; Pavan Nikhilesh Bhagavatula
> >> <pbhagavatula@marvell.com>
> >> Subject: [EXTERNAL] Re: [EXT] Re: [PATCH v2] app/dma-perf: support
> >> bi- directional transfer
> >>
> >> Prioritize security for external emails: Confirm sender and content
> >> safety before clicking links or opening attachments
> >>
> >> ---------------------------------------------------------------------
> >> -
> >> Hi Amit,
> >>
> >> I think this commit will complicated the test, plus futer we may add
> >> more test (e.g. fill)
> >>
> >> I agree Bruce's advise in the [1], let also support "lcore_dma0/1/2",
> >>
> >> User could provide dma info by two way:
> >> 1) lcore_dma=, which seperate each dma with ", ", but a maximum of a
> >> certain number is allowed.
> >> 2) lcore_dma0/1/2/..., each dma device take one line
> >>
> >> [1] https://urldefense.proofpoint.com/v2/url?u=https-
> >> 3A__patchwork.dpdk.org_project_dpdk_patch_20231206112952.1588-
> >> 2D1-2Dvipin.varghese-
> >>
> 40amd.com_&d=DwICaQ&c=nKjWec2b6R0mOyPaz7xtfQ&r=ALGdXl3fZgFGR6
> >> 9VnJLdSnADun7zLaXG1p5Rs7pXihE&m=OwrvdPIi-
> >>
> TQ2UEH3cztfXDzT8YkOB099Pl1mfUzGaq9td0fEWrRBLQQBzAFkjQSU&s=kKin
> >> YsGoNyTxuLEyPJ0LppT17Yq64CvFBtJMirGEISI&e=
> >>
> >> Thanks
> >>
> >> On 2024/2/29 22:03, Amit Prakash Shukla wrote:
> >>> Hi Chengwen,
> >>>
> >>> I liked your suggestion and tried making changes, but encountered
> >>> parsing
> >> issue for CFG files with line greater than CFG_VALUE_LEN=256(current
> >> value set).
> >>>
> >>> There is a discussion on the similar lines in another patch set:
> >> https://urldefense.proofpoint.com/v2/url?u=https-
> >> 3A__patchwork.dpdk.org_project_dpdk_patch_20231206112952.1588-
> >> 2D1-2Dvipin.varghese-
> >>
> 40amd.com_&d=DwICaQ&c=nKjWec2b6R0mOyPaz7xtfQ&r=ALGdXl3fZgFGR6
> >> 9VnJLdSnADun7zLaXG1p5Rs7pXihE&m=OwrvdPIi-
> >>
> TQ2UEH3cztfXDzT8YkOB099Pl1mfUzGaq9td0fEWrRBLQQBzAFkjQSU&s=kKin
> >> YsGoNyTxuLEyPJ0LppT17Yq64CvFBtJMirGEISI&e= .
> >>>
> >>> I believe this patch can be taken as-is and we can come up with the
> >>> solution
> >> when we can increase the CFG_VALUE_LEN as changing CFG_VALUE_LEN in
> >> this release is causing ABI breakage.
> >>>
> >>> Thanks,
> >>> Amit Shukla
> >>>

<snip>

^ permalink raw reply	[relevance 0%]

* Re: [RFC PATCH 1/2] power: refactor core power management library
  2024-03-01  2:56  3%   ` lihuisong (C)
@ 2024-03-01 10:39  0%     ` Hunt, David
  2024-03-05  4:35  3%     ` Tummala, Sivaprasad
  1 sibling, 0 replies; 200+ results
From: Hunt, David @ 2024-03-01 10:39 UTC (permalink / raw)
  To: lihuisong (C),
	Sivaprasad Tummala, anatoly.burakov, jerinj, radu.nicolau,
	gakhil, cristian.dumitrescu, ferruh.yigit, konstantin.ananyev
  Cc: dev


On 01/03/2024 02:56, lihuisong (C) wrote:
>
> 在 2024/2/20 23:33, Sivaprasad Tummala 写道:
>> This patch introduces a comprehensive refactor to the core power
>> management library. The primary focus is on improving modularity
>> and organization by relocating specific driver implementations
>> from the 'lib/power' directory to dedicated directories within
>> 'drivers/power/core/*'. The adjustment of meson.build files
>> enables the selective activation of individual drivers.
>>
>> These changes contribute to a significant enhancement in code
>> organization, providing a clearer structure for driver implementations.
>> The refactor aims to improve overall code clarity and boost
>> maintainability. Additionally, it establishes a foundation for
>> future development, allowing for more focused work on individual
>> drivers and seamless integration of forthcoming enhancements.
>
> Good job. +1 to refacotor.
>
> <...>
>

Also a +1 from me, looks like a sensible re-organisation of the power code.

Regards,
Dave.



>> diff --git a/drivers/meson.build b/drivers/meson.build
>> index f2be71bc05..e293c3945f 100644
>> --- a/drivers/meson.build
>> +++ b/drivers/meson.build
>> @@ -28,6 +28,7 @@ subdirs = [
>>           'event',          # depends on common, bus, mempool and net.
>>           'baseband',       # depends on common and bus.
>>           'gpu',            # depends on common and bus.
>> +        'power',          # depends on common (in future).
>>   ]
>>     if meson.is_cross_build()
>> diff --git a/drivers/power/core/acpi/meson.build 
>> b/drivers/power/core/acpi/meson.build
>> new file mode 100644
>> index 0000000000..d10ec8ee94
>> --- /dev/null
>> +++ b/drivers/power/core/acpi/meson.build
>> @@ -0,0 +1,8 @@
>> +# SPDX-License-Identifier: BSD-3-Clause
>> +# Copyright(c) 2024 AMD Limited
>> +
>> +sources = files('power_acpi_cpufreq.c')
>> +
>> +headers = files('power_acpi_cpufreq.h')
>> +
>> +deps += ['power']
>> diff --git a/lib/power/power_acpi_cpufreq.c 
>> b/drivers/power/core/acpi/power_acpi_cpufreq.c
>> similarity index 95%
>> rename from lib/power/power_acpi_cpufreq.c
>> rename to drivers/power/core/acpi/power_acpi_cpufreq.c
> This file is in power lib.
> How about remove the 'power' prefix of this file name?
> like acpi_cpufreq.c, cppc_cpufreq.c.
>> index f8d978d03d..69d80ad2ae 100644
>> --- a/lib/power/power_acpi_cpufreq.c
>> +++ b/drivers/power/core/acpi/power_acpi_cpufreq.c
>> @@ -577,3 +577,22 @@ int power_acpi_get_capabilities(unsigned int 
>> lcore_id,
>>         return 0;
>>   }
>> +
>> +static struct rte_power_ops acpi_ops = {
> How about use the following structure name?
> "struct rte_power_cpufreq_ops" or "struct rte_power_core_ops"
> After all, we also have other power ops, like uncore, right?
>> +    .init = power_acpi_cpufreq_init,
>> +    .exit = power_acpi_cpufreq_exit,
>> +    .check_env_support = power_acpi_cpufreq_check_supported,
>> +    .get_avail_freqs = power_acpi_cpufreq_freqs,
>> +    .get_freq = power_acpi_cpufreq_get_freq,
>> +    .set_freq = power_acpi_cpufreq_set_freq,
>> +    .freq_down = power_acpi_cpufreq_freq_down,
>> +    .freq_up = power_acpi_cpufreq_freq_up,
>> +    .freq_max = power_acpi_cpufreq_freq_max,
>> +    .freq_min = power_acpi_cpufreq_freq_min,
>> +    .turbo_status = power_acpi_turbo_status,
>> +    .enable_turbo = power_acpi_enable_turbo,
>> +    .disable_turbo = power_acpi_disable_turbo,
>> +    .get_caps = power_acpi_get_capabilities
>> +};
>> +
>> +RTE_POWER_REGISTER_OPS(acpi_ops);
>> diff --git a/lib/power/power_acpi_cpufreq.h 
>> b/drivers/power/core/acpi/power_acpi_cpufreq.h
>> similarity index 100%
>> rename from lib/power/power_acpi_cpufreq.h
>> rename to drivers/power/core/acpi/power_acpi_cpufreq.h
>> diff --git a/drivers/power/core/amd-pstate/meson.build 
>> b/drivers/power/core/amd-pstate/meson.build
>> new file mode 100644
>> index 0000000000..8ec4c960f5
>> --- /dev/null
>> +++ b/drivers/power/core/amd-pstate/meson.build
>> @@ -0,0 +1,8 @@
>> +# SPDX-License-Identifier: BSD-3-Clause
>> +# Copyright(c) 2024 AMD Limited
>> +
>> +sources = files('power_amd_pstate_cpufreq.c')
>> +
>> +headers = files('power_amd_pstate_cpufreq.h')
>> +
>> +deps += ['power']
>> diff --git a/lib/power/power_amd_pstate_cpufreq.c 
>> b/drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.c
>> similarity index 95%
>> rename from lib/power/power_amd_pstate_cpufreq.c
>> rename to drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.c
>> index 028f84416b..9938de72a6 100644
>> --- a/lib/power/power_amd_pstate_cpufreq.c
>> +++ b/drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.c
>> @@ -700,3 +700,22 @@ power_amd_pstate_get_capabilities(unsigned int 
>> lcore_id,
>>         return 0;
>>   }
>> +
>> +static struct rte_power_ops amd_pstate_ops = {
>> +    .init = power_amd_pstate_cpufreq_init,
>> +    .exit = power_amd_pstate_cpufreq_exit,
>> +    .check_env_support = power_amd_pstate_cpufreq_check_supported,
>> +    .get_avail_freqs = power_amd_pstate_cpufreq_freqs,
>> +    .get_freq = power_amd_pstate_cpufreq_get_freq,
>> +    .set_freq = power_amd_pstate_cpufreq_set_freq,
>> +    .freq_down = power_amd_pstate_cpufreq_freq_down,
>> +    .freq_up = power_amd_pstate_cpufreq_freq_up,
>> +    .freq_max = power_amd_pstate_cpufreq_freq_max,
>> +    .freq_min = power_amd_pstate_cpufreq_freq_min,
>> +    .turbo_status = power_amd_pstate_turbo_status,
>> +    .enable_turbo = power_amd_pstate_enable_turbo,
>> +    .disable_turbo = power_amd_pstate_disable_turbo,
>> +    .get_caps = power_amd_pstate_get_capabilities
>> +};
>> +
>> +RTE_POWER_REGISTER_OPS(amd_pstate_ops);
>> diff --git a/lib/power/power_amd_pstate_cpufreq.h 
>> b/drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.h
>> similarity index 100%
>> rename from lib/power/power_amd_pstate_cpufreq.h
>> rename to drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.h
>> diff --git a/drivers/power/core/cppc/meson.build 
>> b/drivers/power/core/cppc/meson.build
>> new file mode 100644
>> index 0000000000..06f3b99bb8
>> --- /dev/null
>> +++ b/drivers/power/core/cppc/meson.build
>> @@ -0,0 +1,8 @@
>> +# SPDX-License-Identifier: BSD-3-Clause
>> +# Copyright(c) 2024 AMD Limited
>> +
>> +sources = files('power_cppc_cpufreq.c')
>> +
>> +headers = files('power_cppc_cpufreq.h')
>> +
>> +deps += ['power']
>> diff --git a/lib/power/power_cppc_cpufreq.c 
>> b/drivers/power/core/cppc/power_cppc_cpufreq.c
>> similarity index 96%
>> rename from lib/power/power_cppc_cpufreq.c
>> rename to drivers/power/core/cppc/power_cppc_cpufreq.c
>> index 3ddf39bd76..605f633309 100644
>> --- a/lib/power/power_cppc_cpufreq.c
>> +++ b/drivers/power/core/cppc/power_cppc_cpufreq.c
>> @@ -685,3 +685,22 @@ power_cppc_get_capabilities(unsigned int lcore_id,
>>         return 0;
>>   }
>> +
>> +static struct rte_power_ops cppc_ops = {
>> +    .init = power_cppc_cpufreq_init,
>> +    .exit = power_cppc_cpufreq_exit,
>> +    .check_env_support = power_cppc_cpufreq_check_supported,
>> +    .get_avail_freqs = power_cppc_cpufreq_freqs,
>> +    .get_freq = power_cppc_cpufreq_get_freq,
>> +    .set_freq = power_cppc_cpufreq_set_freq,
>> +    .freq_down = power_cppc_cpufreq_freq_down,
>> +    .freq_up = power_cppc_cpufreq_freq_up,
>> +    .freq_max = power_cppc_cpufreq_freq_max,
>> +    .freq_min = power_cppc_cpufreq_freq_min,
>> +    .turbo_status = power_cppc_turbo_status,
>> +    .enable_turbo = power_cppc_enable_turbo,
>> +    .disable_turbo = power_cppc_disable_turbo,
>> +    .get_caps = power_cppc_get_capabilities
>> +};
>> +
>> +RTE_POWER_REGISTER_OPS(cppc_ops);
>> diff --git a/lib/power/power_cppc_cpufreq.h 
>> b/drivers/power/core/cppc/power_cppc_cpufreq.h
>> similarity index 100%
>> rename from lib/power/power_cppc_cpufreq.h
>> rename to drivers/power/core/cppc/power_cppc_cpufreq.h
>> diff --git a/lib/power/guest_channel.c 
>> b/drivers/power/core/kvm-vm/guest_channel.c
>> similarity index 100%
>> rename from lib/power/guest_channel.c
>> rename to drivers/power/core/kvm-vm/guest_channel.c
>> diff --git a/lib/power/guest_channel.h 
>> b/drivers/power/core/kvm-vm/guest_channel.h
>> similarity index 100%
>> rename from lib/power/guest_channel.h
>> rename to drivers/power/core/kvm-vm/guest_channel.h
>> diff --git a/drivers/power/core/kvm-vm/meson.build 
>> b/drivers/power/core/kvm-vm/meson.build
>> new file mode 100644
>> index 0000000000..3150c6674b
>> --- /dev/null
>> +++ b/drivers/power/core/kvm-vm/meson.build
>> @@ -0,0 +1,20 @@
>> +# SPDX-License-Identifier: BSD-3-Clause
>> +# Copyright(C) 2024 AMD Limited.
>> +#
>> +
>> +if not is_linux
>> +    build = false
>> +    reason = 'only supported on Linux'
>> +    subdir_done()
>> +endif
>> +
>> +sources = files(
>> +        'guest_channel.c',
>> +        'power_kvm_vm.c',
>> +)
>> +
>> +headers = files(
>> +        'guest_channel.h',
>> +        'power_kvm_vm.h',
>> +)
>> +deps += ['power']
>> diff --git a/lib/power/power_kvm_vm.c 
>> b/drivers/power/core/kvm-vm/power_kvm_vm.c
>> similarity index 83%
>> rename from lib/power/power_kvm_vm.c
>> rename to drivers/power/core/kvm-vm/power_kvm_vm.c
>> index f15be8fac5..a5d6984d26 100644
>> --- a/lib/power/power_kvm_vm.c
>> +++ b/drivers/power/core/kvm-vm/power_kvm_vm.c
>> @@ -137,3 +137,22 @@ int power_kvm_vm_get_capabilities(__rte_unused 
>> unsigned int lcore_id,
>>       POWER_LOG(ERR, "rte_power_get_capabilities is not implemented 
>> for Virtual Machine Power Management");
>>       return -ENOTSUP;
>>   }
>> +
>> +static struct rte_power_ops kvm_vm_ops = {
>> +    .init = power_kvm_vm_init,
>> +    .exit = power_kvm_vm_exit,
>> +    .check_env_support = power_kvm_vm_check_supported,
>> +    .get_avail_freqs = power_kvm_vm_freqs,
>> +    .get_freq = power_kvm_vm_get_freq,
>> +    .set_freq = power_kvm_vm_set_freq,
>> +    .freq_down = power_kvm_vm_freq_down,
>> +    .freq_up = power_kvm_vm_freq_up,
>> +    .freq_max = power_kvm_vm_freq_max,
>> +    .freq_min = power_kvm_vm_freq_min,
>> +    .turbo_status = power_kvm_vm_turbo_status,
>> +    .enable_turbo = power_kvm_vm_enable_turbo,
>> +    .disable_turbo = power_kvm_vm_disable_turbo,
>> +    .get_caps = power_kvm_vm_get_capabilities
>> +};
>> +
>> +RTE_POWER_REGISTER_OPS(kvm_vm_ops);
>> diff --git a/lib/power/power_kvm_vm.h 
>> b/drivers/power/core/kvm-vm/power_kvm_vm.h
>> similarity index 100%
>> rename from lib/power/power_kvm_vm.h
>> rename to drivers/power/core/kvm-vm/power_kvm_vm.h
>> diff --git a/drivers/power/core/meson.build 
>> b/drivers/power/core/meson.build
>> new file mode 100644
>> index 0000000000..4081dafaa0
>> --- /dev/null
>> +++ b/drivers/power/core/meson.build
>> @@ -0,0 +1,12 @@
>> +# SPDX-License-Identifier: BSD-3-Clause
>> +# Copyright(c) 2024 AMD Limited
>> +
>> +drivers = [
>> +        'acpi',
>> +        'amd-pstate',
>> +        'cppc',
>> +        'kvm-vm',
>> +        'pstate'
>> +]
>> +
>> +std_deps = ['power']
>> diff --git a/drivers/power/core/pstate/meson.build 
>> b/drivers/power/core/pstate/meson.build
>> new file mode 100644
>> index 0000000000..1025c64e48
>> --- /dev/null
>> +++ b/drivers/power/core/pstate/meson.build
>> @@ -0,0 +1,8 @@
>> +# SPDX-License-Identifier: BSD-3-Clause
>> +# Copyright(c) 2024 AMD Limited
>> +
>> +sources = files('power_pstate_cpufreq.c')
>> +
>> +headers = files('power_pstate_cpufreq.h')
>> +
>> +deps += ['power']
>> diff --git a/lib/power/power_pstate_cpufreq.c 
>> b/drivers/power/core/pstate/power_pstate_cpufreq.c
>> similarity index 96%
>> rename from lib/power/power_pstate_cpufreq.c
>> rename to drivers/power/core/pstate/power_pstate_cpufreq.c
>> index 73138dc4e4..d4c3645ff8 100644
>> --- a/lib/power/power_pstate_cpufreq.c
>> +++ b/drivers/power/core/pstate/power_pstate_cpufreq.c
>> @@ -888,3 +888,22 @@ int power_pstate_get_capabilities(unsigned int 
>> lcore_id,
>>         return 0;
>>   }
>> +
>> +static struct rte_power_ops pstate_ops = {
>> +    .init = power_pstate_cpufreq_init,
>> +    .exit = power_pstate_cpufreq_exit,
>> +    .check_env_support = power_pstate_cpufreq_check_supported,
>> +    .get_avail_freqs = power_pstate_cpufreq_freqs,
>> +    .get_freq = power_pstate_cpufreq_get_freq,
>> +    .set_freq = power_pstate_cpufreq_set_freq,
>> +    .freq_down = power_pstate_cpufreq_freq_down,
>> +    .freq_up = power_pstate_cpufreq_freq_up,
>> +    .freq_max = power_pstate_cpufreq_freq_max,
>> +    .freq_min = power_pstate_cpufreq_freq_min,
>> +    .turbo_status = power_pstate_turbo_status,
>> +    .enable_turbo = power_pstate_enable_turbo,
>> +    .disable_turbo = power_pstate_disable_turbo,
>> +    .get_caps = power_pstate_get_capabilities
>> +};
>> +
>> +RTE_POWER_REGISTER_OPS(pstate_ops);
>> diff --git a/lib/power/power_pstate_cpufreq.h 
>> b/drivers/power/core/pstate/power_pstate_cpufreq.h
>> similarity index 100%
>> rename from lib/power/power_pstate_cpufreq.h
>> rename to drivers/power/core/pstate/power_pstate_cpufreq.h
>> diff --git a/drivers/power/meson.build b/drivers/power/meson.build
>> new file mode 100644
>> index 0000000000..7d9034c7ac
>> --- /dev/null
>> +++ b/drivers/power/meson.build
>> @@ -0,0 +1,8 @@
>> +# SPDX-License-Identifier: BSD-3-Clause
>> +# Copyright(c) 2024 AMD Limited
>> +
>> +drivers = [
>> +        'core',
>> +]
>> +
>> +std_deps = ['power']
>> diff --git a/lib/power/meson.build b/lib/power/meson.build
>> index b8426589b2..207d96d877 100644
>> --- a/lib/power/meson.build
>> +++ b/lib/power/meson.build
>> @@ -12,14 +12,8 @@ if not is_linux
>>       reason = 'only supported on Linux'
>>   endif
>>   sources = files(
>> -        'guest_channel.c',
>> -        'power_acpi_cpufreq.c',
>> -        'power_amd_pstate_cpufreq.c',
>>           'power_common.c',
>> -        'power_cppc_cpufreq.c',
>> -        'power_kvm_vm.c',
>>           'power_intel_uncore.c',
>> -        'power_pstate_cpufreq.c',
>>           'rte_power.c',
>>           'rte_power_uncore.c',
>>           'rte_power_pmd_mgmt.c',
>> diff --git a/lib/power/power_common.h b/lib/power/power_common.h
>> index 30966400ba..c90b611f4f 100644
>> --- a/lib/power/power_common.h
>> +++ b/lib/power/power_common.h
>> @@ -23,13 +23,24 @@ extern int power_logtype;
>>   #endif
>>     /* check if scaling driver matches one we want */
>> +__rte_internal
>>   int cpufreq_check_scaling_driver(const char *driver);
>> +
>> +__rte_internal
>>   int power_set_governor(unsigned int lcore_id, const char 
>> *new_governor,
>>           char *orig_governor, size_t orig_governor_len);
>> +
>> +__rte_internal
>>   int open_core_sysfs_file(FILE **f, const char *mode, const char 
>> *format, ...)
>>           __rte_format_printf(3, 4);
>> +
>> +__rte_internal
>>   int read_core_sysfs_u32(FILE *f, uint32_t *val);
>> +
>> +__rte_internal
>>   int read_core_sysfs_s(FILE *f, char *buf, unsigned int len);
>> +
>> +__rte_internal
>>   int write_core_sysfs_s(FILE *f, const char *str);
>>     #endif /* _POWER_COMMON_H_ */
>> diff --git a/lib/power/rte_power.c b/lib/power/rte_power.c
>> index 36c3f3da98..70176807f4 100644
>> --- a/lib/power/rte_power.c
>> +++ b/lib/power/rte_power.c
>> @@ -8,64 +8,80 @@
>>   #include <rte_spinlock.h>
>>     #include "rte_power.h"
>> -#include "power_acpi_cpufreq.h"
>> -#include "power_cppc_cpufreq.h"
>>   #include "power_common.h"
>> -#include "power_kvm_vm.h"
>> -#include "power_pstate_cpufreq.h"
>> -#include "power_amd_pstate_cpufreq.h"
>>     enum power_management_env global_default_env = PM_ENV_NOT_SET;
> use a pointer to save the current power cpufreq ops?
>>     static rte_spinlock_t global_env_cfg_lock = 
>> RTE_SPINLOCK_INITIALIZER;
>> +static struct rte_power_ops rte_power_ops[PM_ENV_MAX];
>>   -/* function pointers */
>> -rte_power_freqs_t rte_power_freqs  = NULL;
>> -rte_power_get_freq_t rte_power_get_freq = NULL;
>> -rte_power_set_freq_t rte_power_set_freq = NULL;
>> -rte_power_freq_change_t rte_power_freq_up = NULL;
>> -rte_power_freq_change_t rte_power_freq_down = NULL;
>> -rte_power_freq_change_t rte_power_freq_max = NULL;
>> -rte_power_freq_change_t rte_power_freq_min = NULL;
>> -rte_power_freq_change_t rte_power_turbo_status;
>> -rte_power_freq_change_t rte_power_freq_enable_turbo;
>> -rte_power_freq_change_t rte_power_freq_disable_turbo;
>> -rte_power_get_capabilities_t rte_power_get_capabilities;
>> -
>> -static void
>> -reset_power_function_ptrs(void)
>> +/* register the ops struct in rte_power_ops, return 0 on success. */
>> +int
>> +rte_power_register_ops(const struct rte_power_ops *op)
>> +{
>> +    struct rte_power_ops *ops;
>> +
>> +    if (op->env >= PM_ENV_MAX) {
>> +        POWER_LOG(ERR, "Unsupported power management environment\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    if (op->status != 0) {
>> +        POWER_LOG(ERR, "Power management env[%d] ops registered 
>> already\n",
>> +            op->env);
>> +        return -EINVAL;
>> +    }
>> +
>> +    if (!op->init || !op->exit || !op->check_env_support ||
>> +        !op->get_avail_freqs || !op->get_freq || !op->set_freq ||
>> +        !op->freq_up || !op->freq_down || !op->freq_max ||
>> +        !op->freq_min || !op->turbo_status || !op->enable_turbo ||
>> +        !op->disable_turbo || !op->get_caps) {
>> +        POWER_LOG(ERR, "Missing callbacks while registering power 
>> ops\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    ops = &rte_power_ops[op->env];
> It is better to use a global linked list instead of an array.
> And we should extract a list structure including this ops structure 
> and this ops's owner.
>> +    ops->env = op->env;
>> +    ops->init = op->init;
>> +    ops->exit = op->exit;
>> +    ops->check_env_support = op->check_env_support;
>> +    ops->get_avail_freqs = op->get_avail_freqs;
>> +    ops->get_freq = op->get_freq;
>> +    ops->set_freq = op->set_freq;
>> +    ops->freq_up = op->freq_up;
>> +    ops->freq_down = op->freq_down;
>> +    ops->freq_max = op->freq_max;
>> +    ops->freq_min = op->freq_min;
>> +    ops->turbo_status = op->turbo_status;
>> +    ops->enable_turbo = op->enable_turbo;
>> +    ops->disable_turbo = op->disable_turbo;
> *ops = *op?
>> +    ops->status = 1; /* registered */
> status --> registered?
> But if use ops linked list, this flag also can be removed.
>> +
>> +    return 0;
>> +}
>> +
>> +struct rte_power_ops *
>> +rte_power_get_ops(int ops_index)
> AFAICS, there is only one cpufreq driver on one platform and just have 
> one power_cpufreq_ops to use for user.
> We don't need user to get other power ops, and user just want to know 
> the power ops using currently, right?
> So using 'index' toget this ops is not good.
>>   {
>> -    rte_power_freqs  = NULL;
>> -    rte_power_get_freq = NULL;
>> -    rte_power_set_freq = NULL;
>> -    rte_power_freq_up = NULL;
>> -    rte_power_freq_down = NULL;
>> -    rte_power_freq_max = NULL;
>> -    rte_power_freq_min = NULL;
>> -    rte_power_turbo_status = NULL;
>> -    rte_power_freq_enable_turbo = NULL;
>> -    rte_power_freq_disable_turbo = NULL;
>> -    rte_power_get_capabilities = NULL;
>> +    RTE_VERIFY((ops_index >= PM_ENV_NOT_SET) && (ops_index < 
>> PM_ENV_MAX));
>> +    RTE_VERIFY(rte_power_ops[ops_index].status != 0);
>> +
>> +    return &rte_power_ops[ops_index];
>>   }
>>     int
>>   rte_power_check_env_supported(enum power_management_env env)
>>   {
>> -    switch (env) {
>> -    case PM_ENV_ACPI_CPUFREQ:
>> -        return power_acpi_cpufreq_check_supported();
>> -    case PM_ENV_PSTATE_CPUFREQ:
>> -        return power_pstate_cpufreq_check_supported();
>> -    case PM_ENV_KVM_VM:
>> -        return power_kvm_vm_check_supported();
>> -    case PM_ENV_CPPC_CPUFREQ:
>> -        return power_cppc_cpufreq_check_supported();
>> -    case PM_ENV_AMD_PSTATE_CPUFREQ:
>> -        return power_amd_pstate_cpufreq_check_supported();
>> -    default:
>> -        rte_errno = EINVAL;
>> -        return -1;
>> +    struct rte_power_ops *ops;
>> +
>> +    if ((env > PM_ENV_NOT_SET) && (env < PM_ENV_MAX)) {
>> +        ops = rte_power_get_ops(env);
>> +        return ops->check_env_support();
>>       }
>> +
>> +    rte_errno = EINVAL;
>> +    return -1;
>>   }
>>     int
>> @@ -80,80 +96,26 @@ rte_power_set_env(enum power_management_env env)
>>       }
>>         int ret = 0;
>> +    struct rte_power_ops *ops;
>> +
>> +    if ((env == PM_ENV_NOT_SET) || (env >= PM_ENV_MAX)) {
>> +        POWER_LOG(ERR, "Invalid Power Management Environment(%d)"
>> +                " set\n", env);
>> +        ret = -1;
>> +    }
> <...>
>> +    ops = rte_power_get_ops(env);
> To find the target ops from the global list according to the env?
>> +    if (ops->status == 0) {
>> +        POWER_LOG(ERR, WER,
>> +            "Power Management Environment(%d) not"
>> +            " registered\n", env);
>>           ret = -1;
>>       }
>>         if (ret == 0)
>>           global_default_env = env;
> It is more convenient to use a global variable to point to the default 
> power_cpufreq ops or its list node.
>> -    else {
>> +    else
>>           global_default_env = PM_ENV_NOT_SET;
>> -        reset_power_function_ptrs();
>> -    }
>>         rte_spinlock_unlock(&global_env_cfg_lock);
>>       return ret;
>> @@ -164,7 +126,6 @@ rte_power_unset_env(void)
>>   {
>>       rte_spinlock_lock(&global_env_cfg_lock);
>>       global_default_env = PM_ENV_NOT_SET;
>> -    reset_power_function_ptrs();
>>       rte_spinlock_unlock(&global_env_cfg_lock);
>>   }
>>   @@ -177,59 +138,76 @@ int
>>   rte_power_init(unsigned int lcore_id)
>>   {
>>       int ret = -1;
>> +    struct rte_power_ops *ops;
>>   -    switch (global_default_env) {
>> -    case PM_ENV_ACPI_CPUFREQ:
>> -        return power_acpi_cpufreq_init(lcore_id);
>> -    case PM_ENV_KVM_VM:
>> -        return power_kvm_vm_init(lcore_id);
>> -    case PM_ENV_PSTATE_CPUFREQ:
>> -        return power_pstate_cpufreq_init(lcore_id);
>> -    case PM_ENV_CPPC_CPUFREQ:
>> -        return power_cppc_cpufreq_init(lcore_id);
>> -    case PM_ENV_AMD_PSTATE_CPUFREQ:
>> -        return power_amd_pstate_cpufreq_init(lcore_id);
>> -    default:
>> -        POWER_LOG(INFO, "Env isn't set yet!");
>> +    if (global_default_env != PM_ENV_NOT_SET) {
>> +        ops = &rte_power_ops[global_default_env];
>> +        if (!ops->status) {
>> +            POWER_LOG(ERR, "Power management env[%d] not"
>> +                " supported\n", global_default_env);
>> +            goto out;
>> +        }
>> +        return ops->init(lcore_id);
>>       }
>> +    POWER_LOG(INFO, POWER, "Env isn't set yet!\n");
>>         /* Auto detect Environment */
>> -    POWER_LOG(INFO, "Attempting to initialise ACPI cpufreq power 
>> management...");
>> -    ret = power_acpi_cpufreq_init(lcore_id);
>> -    if (ret == 0) {
>> -        rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
>> -        goto out;
>> +    POWER_LOG(INFO, "Attempting to initialise ACPI cpufreq"
>> +            " power management...\n");
>> +    ops = &rte_power_ops[PM_ENV_ACPI_CPUFREQ];
>> +    if (ops->status) {
>> +        ret = ops->init(lcore_id);
>> +        if (ret == 0) {
>> +            rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
>> +            goto out;
>> +        }
>>       }
>>   -    POWER_LOG(INFO, "Attempting to initialise PSTAT power 
>> management...");
>> -    ret = power_pstate_cpufreq_init(lcore_id);
>> -    if (ret == 0) {
>> -        rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
>> -        goto out;
>> +    POWER_LOG(INFO, "Attempting to initialise PSTAT"
>> +            " power management...\n");
>> +    ops = &rte_power_ops[PM_ENV_PSTATE_CPUFREQ];
>> +    if (ops->status) {
>> +        ret = ops->init(lcore_id);
>> +        if (ret == 0) {
>> +            rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
>> +            goto out;
>> +        }
>>       }
>>   -    POWER_LOG(INFO, "Attempting to initialise AMD PSTATE power 
>> management...");
>> -    ret = power_amd_pstate_cpufreq_init(lcore_id);
>> -    if (ret == 0) {
>> -        rte_power_set_env(PM_ENV_AMD_PSTATE_CPUFREQ);
>> -        goto out;
>> +    POWER_LOG(INFO,    "Attempting to initialise AMD PSTATE"
>> +            " power management...\n");
>> +    ops = &rte_power_ops[PM_ENV_AMD_PSTATE_CPUFREQ];
>> +    if (ops->status) {
>> +        ret = ops->init(lcore_id);
>> +        if (ret == 0) {
>> +            rte_power_set_env(PM_ENV_AMD_PSTATE_CPUFREQ);
>> +            goto out;
>> +        }
>>       }
>>   -    POWER_LOG(INFO, "Attempting to initialise CPPC power 
>> management...");
>> -    ret = power_cppc_cpufreq_init(lcore_id);
>> -    if (ret == 0) {
>> -        rte_power_set_env(PM_ENV_CPPC_CPUFREQ);
>> -        goto out;
>> +    POWER_LOG(INFO, "Attempting to initialise CPPC power"
>> +            " management...\n");
>> +    ops = &rte_power_ops[PM_ENV_CPPC_CPUFREQ];
>> +    if (ops->status) {
>> +        ret = ops->init(lcore_id);
>> +        if (ret == 0) {
>> +            rte_power_set_env(PM_ENV_CPPC_CPUFREQ);
>> +            goto out;
>> +        }
>>       }
>>   -    POWER_LOG(INFO, "Attempting to initialise VM power 
>> management...");
>> -    ret = power_kvm_vm_init(lcore_id);
>> -    if (ret == 0) {
>> -        rte_power_set_env(PM_ENV_KVM_VM);
>> -        goto out;
>> +    POWER_LOG(INFO, "Attempting to initialise VM power"
>> +            " management...\n");
>> +    ops = &rte_power_ops[PM_ENV_KVM_VM];
>> +    if (ops->status) {
>> +        ret = ops->init(lcore_id);
>> +        if (ret == 0) {
>> +            rte_power_set_env(PM_ENV_KVM_VM);
>> +            goto out;
>> +        }
>>       }
> If we use a linked list, above code can be simpled like this:
> ->
> for_each_power_cpufreq_ops(ops, ...) {
>     ret = ops->init()
>     if (ret) {
>         ....
>     }
> }
>> -    POWER_LOG(ERR, "Unable to set Power Management Environment for 
>> lcore "
>> -            "%u", lcore_id);
>> +    POWER_LOG(ERR, "Unable to set Power Management Environment"
>> +            " for lcore %u\n", lcore_id);
>>   out:
>>       return ret;
>>   }
>> @@ -237,21 +215,14 @@ rte_power_init(unsigned int lcore_id)
>>   int
>>   rte_power_exit(unsigned int lcore_id)
>>   {
>> -    switch (global_default_env) {
>> -    case PM_ENV_ACPI_CPUFREQ:
>> -        return power_acpi_cpufreq_exit(lcore_id);
>> -    case PM_ENV_KVM_VM:
>> -        return power_kvm_vm_exit(lcore_id);
>> -    case PM_ENV_PSTATE_CPUFREQ:
>> -        return power_pstate_cpufreq_exit(lcore_id);
>> -    case PM_ENV_CPPC_CPUFREQ:
>> -        return power_cppc_cpufreq_exit(lcore_id);
>> -    case PM_ENV_AMD_PSTATE_CPUFREQ:
>> -        return power_amd_pstate_cpufreq_exit(lcore_id);
>> -    default:
>> -        POWER_LOG(ERR, "Environment has not been set, unable to exit 
>> gracefully");
>> +    struct rte_power_ops *ops;
>>   +    if (global_default_env != PM_ENV_NOT_SET) {
>> +        ops = &rte_power_ops[global_default_env];
>> +        return ops->exit(lcore_id);
>>       }
>> -    return -1;
>> +    POWER_LOG(ERR, "Environment has not been set, unable "
>> +            "to exit gracefully\n");
>>   +    return -1;
>>   }
>> diff --git a/lib/power/rte_power.h b/lib/power/rte_power.h
>> index 4fa4afe399..749bb823ab 100644
>> --- a/lib/power/rte_power.h
>> +++ b/lib/power/rte_power.h
>> @@ -1,5 +1,6 @@
>>   /* SPDX-License-Identifier: BSD-3-Clause
>>    * Copyright(c) 2010-2014 Intel Corporation
>> + * Copyright(c) 2024 AMD Limited
>>    */
>>     #ifndef _RTE_POWER_H
>> @@ -21,7 +22,7 @@ extern "C" {
>>   /* Power Management Environment State */
>>   enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, 
>> PM_ENV_KVM_VM,
>>           PM_ENV_PSTATE_CPUFREQ, PM_ENV_CPPC_CPUFREQ,
>> -        PM_ENV_AMD_PSTATE_CPUFREQ};
>> +        PM_ENV_AMD_PSTATE_CPUFREQ, PM_ENV_MAX};
> "enum power_management_env" is not good. may be like "enum 
> power_cpufreq_driver_type"?
> In previous linked list structure to be defined, may be directly use a 
> string name instead of a fixed enum is better.
> Becuase the new "PM_ENV_MAX" will  lead to break ABI when add a new 
> cpufreq driver.
>>     /**
>>    * Check if a specific power management environment type is 
>> supported on a
>> @@ -66,6 +67,97 @@ void rte_power_unset_env(void);
>>    */
>>   enum power_management_env rte_power_get_env(void);
>>   +typedef int (*rte_power_cpufreq_init_t)(unsigned int lcore_id);
>> +typedef int (*rte_power_cpufreq_exit_t)(unsigned int lcore_id);
>> +typedef int (*rte_power_check_env_support_t)(void);
>> +
>> +typedef uint32_t (*rte_power_freqs_t)(unsigned int lcore_id, 
>> uint32_t *freqs,
>> +                    uint32_t num);
>> +typedef uint32_t (*rte_power_get_freq_t)(unsigned int lcore_id);
>> +typedef int (*rte_power_set_freq_t)(unsigned int lcore_id, uint32_t 
>> index);
>> +typedef int (*rte_power_freq_change_t)(unsigned int lcore_id);
>> +
>> +/**
>> + * Function pointer definition for generic frequency change 
>> functions. Review
>> + * each environments specific documentation for usage.
>> + *
>> + * @param lcore_id
>> + *  lcore id.
>> + *
>> + * @return
>> + *  - 1 on success with frequency changed.
>> + *  - 0 on success without frequency changed.
>> + *  - Negative on error.
>> + */
>> +
>> +/**
>> + * Power capabilities summary.
>> + */
>> +struct rte_power_core_capabilities {
>> +    union {
>> +        uint64_t capabilities;
>> +        struct {
>> +            uint64_t turbo:1;       /**< Turbo can be enabled. */
>> +            uint64_t priority:1;    /**< SST-BF high freq core */
>> +        };
>> +    };
>> +};
>> +
>> +typedef int (*rte_power_get_capabilities_t)(unsigned int lcore_id,
>> +                struct rte_power_core_capabilities *caps);
>> +
>> +/** Structure defining core power operations structure */
>> +struct rte_power_ops {
>> +uint8_t status;                         /**< ops register status. */
>> +    enum power_management_env env;          /**< power mgmt env. */
>> +    rte_power_cpufreq_init_t init;    /**< Initialize power 
>> management. */
>> +    rte_power_cpufreq_exit_t exit;    /**< Exit power management. */
>> +    rte_power_check_env_support_t check_env_support; /**< verify env 
>> is supported. */
>> +    rte_power_freqs_t get_avail_freqs; /**< Get the available 
>> frequencies. */
>> +    rte_power_get_freq_t get_freq; /**< Get frequency index. */
>> +    rte_power_set_freq_t set_freq; /**< Set frequency index. */
>> +    rte_power_freq_change_t freq_up;   /**< Scale up frequency. */
>> +    rte_power_freq_change_t freq_down; /**< Scale down frequency. */
>> +    rte_power_freq_change_t freq_max;  /**< Scale up frequency to 
>> highest. */
>> +    rte_power_freq_change_t freq_min;  /**< Scale up frequency to 
>> lowest. */
>> +    rte_power_freq_change_t turbo_status; /**< Get Turbo status. */
>> +    rte_power_freq_change_t enable_turbo; /**< Enable Turbo. */
>> +    rte_power_freq_change_t disable_turbo; /**< Disable Turbo. */
>> +    rte_power_get_capabilities_t get_caps; /**< power capabilities. */
>> +} __rte_cache_aligned;
> Suggest that fix this sturcture, like:
> struct rte_power_cpufreq_list {
>     char name[];   // like "cppc_cpufreq", "pstate_cpufreq"
>     struct rte_power_cpufreq *ops;
>     struct rte_power_cpufreq_list *node;
> }
>> +
>> +/**
>> + * Register power cpu frequency operations.
>> + *
>> + * @param ops
>> + *   Pointer to an ops structure to register.
>> + * @return
>> + *   - >=0: Success; return the index of the ops struct in the table.
>> + *   - -EINVAL - error while registering ops struct.
>> + */
>> +__rte_internal
>> +int rte_power_register_ops(const struct rte_power_ops *ops);
>> +
>> +/**
>> + * Macro to statically register the ops of a cpufreq driver.
>> + */
>> +#define RTE_POWER_REGISTER_OPS(ops)        \
>> +    (RTE_INIT(power_hdlr_init_##ops)    \
>> +    {                    \
>> +        rte_power_register_ops(&ops);    \
>> +    })
>> +
>> +/**
>> + * @internal Get the power ops struct from its index.
>> + *
>> + * @param ops_index
>> + *   The index of the ops struct in the ops struct table.
>> + * @return
>> + *   The pointer to the ops struct in the table if registered.
>> + */
>> +struct rte_power_ops *
>> +rte_power_get_ops(int ops_index);
>> +
>>   /**
>>    * Initialize power management for a specific lcore. If 
>> rte_power_set_env() has
>>    * not been called then an auto-detect of the environment will 
>> start and
>> @@ -108,10 +200,14 @@ int rte_power_exit(unsigned int lcore_id);
>>    * @return
>>    *  The number of available frequencies.
>>    */
>> -typedef uint32_t (*rte_power_freqs_t)(unsigned int lcore_id, 
>> uint32_t *freqs,
>> -        uint32_t num);
>> +static inline uint32_t
>> +rte_power_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t n)
>> +{
>> +    struct rte_power_ops *ops;
>>   -extern rte_power_freqs_t rte_power_freqs;
>> +    ops = rte_power_get_ops(rte_power_get_env());
>> +    return ops->get_avail_freqs(lcore_id, freqs, n);
>> +}
> nice.
> <...>

^ permalink raw reply	[relevance 0%]

* Re: [EXTERNAL] Re: [EXT] Re: [PATCH v2] app/dma-perf: support bi-directional transfer
  2024-03-01  8:31  0%           ` [EXTERNAL] " Amit Prakash Shukla
@ 2024-03-01  9:30  0%             ` fengchengwen
  2024-03-01 10:59  0%               ` Amit Prakash Shukla
  0 siblings, 1 reply; 200+ results
From: fengchengwen @ 2024-03-01  9:30 UTC (permalink / raw)
  To: Amit Prakash Shukla, Cheng Jiang, Gowrishankar Muthukrishnan
  Cc: dev, Jerin Jacob, Anoob Joseph, Kevin Laatz, Bruce Richardson,
	Pavan Nikhilesh Bhagavatula

Hi Amit,

On 2024/3/1 16:31, Amit Prakash Shukla wrote:
> Hi Chengwen,
> 
> If I'm not wrong, your concern was about config file additions and not about the test as such. If the config file is getting complicated and there are better alternatives, we can minimize the config file changes with this patch and just provide minimum functionality as required and leave it open for future changes. For now, I can document the existing behavior in documentation as "Constraints". Similar approach is followed in other application such as ipsec-secgw https://doc.dpdk.org/guides/sample_app_ug/ipsec_secgw.html#constraints

Yes, I prefer enable different test just by modify configuration file, and then limit the number of entries at the same time.

This commit is bi-direction transfer, it is fixed, maybe later we should test 3/4 for mem2dev while 1/4 for dev2mem.

sometime we may need evaluate performance of one dma channel for mem2mem, while another channel for mem2dev, we can't do
this in current implement (because vchan_dev is for all DMA channel).

So I prefer restrict DMA non-mem2mem's config (include dir/type/coreid/pfid/vfid/raddr) as the dma device's private configuration.

Thanks

> 
> Constraints:
> 1. vchan_dev config will be same for all the configured DMA devices.
> 2. Alternate DMA device will do dev2mem and mem2dev implicitly.
> Example:
> xfer_mode=1
> vchan_dev=raddr=0x200000000,coreid=1,pfid=2,vfid=3
> lcore_dma=lcore10@0000:00:04.2, lcore11@0000:00:04.3, lcore12@0000:00:04.4, lcore13@0000:00:04.5
> 
> lcore10@0000:00:04.2, lcore12@0000:00:04.4 will do dev2mem and lcore11@0000:00:04.3, lcore13@0000:00:04.5 will do mem2dev.
> 
> Thanks,
> Amit Shukla
> 
>> -----Original Message-----
>> From: fengchengwen <fengchengwen@huawei.com>
>> Sent: Friday, March 1, 2024 7:16 AM
>> To: Amit Prakash Shukla <amitprakashs@marvell.com>; Cheng Jiang
>> <honest.jiang@foxmail.com>; Gowrishankar Muthukrishnan
>> <gmuthukrishn@marvell.com>
>> Cc: dev@dpdk.org; Jerin Jacob <jerinj@marvell.com>; Anoob Joseph
>> <anoobj@marvell.com>; Kevin Laatz <kevin.laatz@intel.com>; Bruce
>> Richardson <bruce.richardson@intel.com>; Pavan Nikhilesh Bhagavatula
>> <pbhagavatula@marvell.com>
>> Subject: [EXTERNAL] Re: [EXT] Re: [PATCH v2] app/dma-perf: support bi-
>> directional transfer
>>
>> Prioritize security for external emails: Confirm sender and content safety
>> before clicking links or opening attachments
>>
>> ----------------------------------------------------------------------
>> Hi Amit,
>>
>> I think this commit will complicated the test, plus futer we may add more test
>> (e.g. fill)
>>
>> I agree Bruce's advise in the [1], let also support "lcore_dma0/1/2",
>>
>> User could provide dma info by two way:
>> 1) lcore_dma=, which seperate each dma with ", ", but a maximum of a certain
>> number is allowed.
>> 2) lcore_dma0/1/2/..., each dma device take one line
>>
>> [1] https://urldefense.proofpoint.com/v2/url?u=https-
>> 3A__patchwork.dpdk.org_project_dpdk_patch_20231206112952.1588-
>> 2D1-2Dvipin.varghese-
>> 40amd.com_&d=DwICaQ&c=nKjWec2b6R0mOyPaz7xtfQ&r=ALGdXl3fZgFGR6
>> 9VnJLdSnADun7zLaXG1p5Rs7pXihE&m=OwrvdPIi-
>> TQ2UEH3cztfXDzT8YkOB099Pl1mfUzGaq9td0fEWrRBLQQBzAFkjQSU&s=kKin
>> YsGoNyTxuLEyPJ0LppT17Yq64CvFBtJMirGEISI&e=
>>
>> Thanks
>>
>> On 2024/2/29 22:03, Amit Prakash Shukla wrote:
>>> Hi Chengwen,
>>>
>>> I liked your suggestion and tried making changes, but encountered parsing
>> issue for CFG files with line greater than CFG_VALUE_LEN=256(current value
>> set).
>>>
>>> There is a discussion on the similar lines in another patch set:
>> https://urldefense.proofpoint.com/v2/url?u=https-
>> 3A__patchwork.dpdk.org_project_dpdk_patch_20231206112952.1588-
>> 2D1-2Dvipin.varghese-
>> 40amd.com_&d=DwICaQ&c=nKjWec2b6R0mOyPaz7xtfQ&r=ALGdXl3fZgFGR6
>> 9VnJLdSnADun7zLaXG1p5Rs7pXihE&m=OwrvdPIi-
>> TQ2UEH3cztfXDzT8YkOB099Pl1mfUzGaq9td0fEWrRBLQQBzAFkjQSU&s=kKin
>> YsGoNyTxuLEyPJ0LppT17Yq64CvFBtJMirGEISI&e= .
>>>
>>> I believe this patch can be taken as-is and we can come up with the solution
>> when we can increase the CFG_VALUE_LEN as changing CFG_VALUE_LEN in
>> this release is causing ABI breakage.
>>>
>>> Thanks,
>>> Amit Shukla
>>>
>>>> -----Original Message-----
>>>> From: Amit Prakash Shukla
>>>> Sent: Wednesday, February 28, 2024 3:08 PM
>>>> To: fengchengwen <fengchengwen@huawei.com>; Cheng Jiang
>>>> <honest.jiang@foxmail.com>; Gowrishankar Muthukrishnan
>>>> <gmuthukrishn@marvell.com>
>>>> Cc: dev@dpdk.org; Jerin Jacob <jerinj@marvell.com>; Anoob Joseph
>>>> <anoobj@marvell.com>; Kevin Laatz <kevin.laatz@intel.com>; Bruce
>>>> Richardson <bruce.richardson@intel.com>; Pavan Nikhilesh Bhagavatula
>>>> <pbhagavatula@marvell.com>
>>>> Subject: RE: [EXT] Re: [PATCH v2] app/dma-perf: support
>>>> bi-directional transfer
>>>>
>>>> Hi Chengwen,
>>>>
>>>> Please see my reply in-line.
>>>>
>>>> Thanks
>>>> Amit Shukla
>>>>
>>>>> -----Original Message-----
>>>>> From: fengchengwen <fengchengwen@huawei.com>
>>>>> Sent: Wednesday, February 28, 2024 12:34 PM
>>>>> To: Amit Prakash Shukla <amitprakashs@marvell.com>; Cheng Jiang
>>>>> <honest.jiang@foxmail.com>; Gowrishankar Muthukrishnan
>>>>> <gmuthukrishn@marvell.com>
>>>>> Cc: dev@dpdk.org; Jerin Jacob <jerinj@marvell.com>; Anoob Joseph
>>>>> <anoobj@marvell.com>; Kevin Laatz <kevin.laatz@intel.com>; Bruce
>>>>> Richardson <bruce.richardson@intel.com>; Pavan Nikhilesh Bhagavatula
>>>>> <pbhagavatula@marvell.com>
>>>>> Subject: [EXT] Re: [PATCH v2] app/dma-perf: support bi-directional
>>>>> transfer
>>>>>
>>>>> External Email
>>>>>
>>>>> --------------------------------------------------------------------
>>>>> --
>>>>> Hi Amit and Gowrishankar,
>>>>>
>>>>> It's nature to support multiple dmadev test in one testcase, and the
>>>>> original framework supports it.
>>>>> But it seem we both complicated it when adding support for non-
>>>> mem2mem
>>>>> dma test.
>>>>>
>>>>> The new added "direction" and "vchan_dev" could treat as the
>>>>> dmadev's private configure, some thing like:
>>>>>
>>>>>
>>>>
>> lcore_dma=lcore10@0000:00:04.2,vchan=0,dir=mem2dev,devtype=pcie,radd
>>>>> r=xxx,coreid=1,pfid=2,vfid=3
>>>>>
>>>>> then this bi-directional could impl only with config:
>>>>>
>>>>>
>>>>
>> lcore_dma=lcore10@0000:00:04.2,dir=mem2dev,devtype=pcie,raddr=xxx,cor
>>>>> eid=1,pfid=2,vfid=3,
>>>>>
>>>>
>> lcore11@0000:00:04.3,dir=dev2mem,devtype=pcie,raddr=xxx,coreid=1,pfid
>>>> =
>>>>> 2,vfid=3
>>>>> so that the lcore10 will do mem2dev with device 0000:00:04.2, while
>>>>> lcore11 will do dev2mem with device 0000:00:04.3.
>>>>
>>>> Thanks for the suggestion. I will make the suggested changes and send
>>>> the next version.

^ permalink raw reply	[relevance 0%]

* RE: [EXTERNAL] Re: [EXT] Re: [PATCH v2] app/dma-perf: support bi-directional transfer
  2024-03-01  1:46  0%         ` fengchengwen
@ 2024-03-01  8:31  0%           ` Amit Prakash Shukla
  2024-03-01  9:30  0%             ` fengchengwen
  0 siblings, 1 reply; 200+ results
From: Amit Prakash Shukla @ 2024-03-01  8:31 UTC (permalink / raw)
  To: fengchengwen, Cheng Jiang, Gowrishankar Muthukrishnan
  Cc: dev, Jerin Jacob, Anoob Joseph, Kevin Laatz, Bruce Richardson,
	Pavan Nikhilesh Bhagavatula

Hi Chengwen,

If I'm not wrong, your concern was about config file additions and not about the test as such. If the config file is getting complicated and there are better alternatives, we can minimize the config file changes with this patch and just provide minimum functionality as required and leave it open for future changes. For now, I can document the existing behavior in documentation as "Constraints". Similar approach is followed in other application such as ipsec-secgw https://doc.dpdk.org/guides/sample_app_ug/ipsec_secgw.html#constraints

Constraints:
1. vchan_dev config will be same for all the configured DMA devices.
2. Alternate DMA device will do dev2mem and mem2dev implicitly.
Example:
xfer_mode=1
vchan_dev=raddr=0x200000000,coreid=1,pfid=2,vfid=3
lcore_dma=lcore10@0000:00:04.2, lcore11@0000:00:04.3, lcore12@0000:00:04.4, lcore13@0000:00:04.5

lcore10@0000:00:04.2, lcore12@0000:00:04.4 will do dev2mem and lcore11@0000:00:04.3, lcore13@0000:00:04.5 will do mem2dev.

Thanks,
Amit Shukla

> -----Original Message-----
> From: fengchengwen <fengchengwen@huawei.com>
> Sent: Friday, March 1, 2024 7:16 AM
> To: Amit Prakash Shukla <amitprakashs@marvell.com>; Cheng Jiang
> <honest.jiang@foxmail.com>; Gowrishankar Muthukrishnan
> <gmuthukrishn@marvell.com>
> Cc: dev@dpdk.org; Jerin Jacob <jerinj@marvell.com>; Anoob Joseph
> <anoobj@marvell.com>; Kevin Laatz <kevin.laatz@intel.com>; Bruce
> Richardson <bruce.richardson@intel.com>; Pavan Nikhilesh Bhagavatula
> <pbhagavatula@marvell.com>
> Subject: [EXTERNAL] Re: [EXT] Re: [PATCH v2] app/dma-perf: support bi-
> directional transfer
> 
> Prioritize security for external emails: Confirm sender and content safety
> before clicking links or opening attachments
> 
> ----------------------------------------------------------------------
> Hi Amit,
> 
> I think this commit will complicated the test, plus futer we may add more test
> (e.g. fill)
> 
> I agree Bruce's advise in the [1], let also support "lcore_dma0/1/2",
> 
> User could provide dma info by two way:
> 1) lcore_dma=, which seperate each dma with ", ", but a maximum of a certain
> number is allowed.
> 2) lcore_dma0/1/2/..., each dma device take one line
> 
> [1] https://urldefense.proofpoint.com/v2/url?u=https-
> 3A__patchwork.dpdk.org_project_dpdk_patch_20231206112952.1588-
> 2D1-2Dvipin.varghese-
> 40amd.com_&d=DwICaQ&c=nKjWec2b6R0mOyPaz7xtfQ&r=ALGdXl3fZgFGR6
> 9VnJLdSnADun7zLaXG1p5Rs7pXihE&m=OwrvdPIi-
> TQ2UEH3cztfXDzT8YkOB099Pl1mfUzGaq9td0fEWrRBLQQBzAFkjQSU&s=kKin
> YsGoNyTxuLEyPJ0LppT17Yq64CvFBtJMirGEISI&e=
> 
> Thanks
> 
> On 2024/2/29 22:03, Amit Prakash Shukla wrote:
> > Hi Chengwen,
> >
> > I liked your suggestion and tried making changes, but encountered parsing
> issue for CFG files with line greater than CFG_VALUE_LEN=256(current value
> set).
> >
> > There is a discussion on the similar lines in another patch set:
> https://urldefense.proofpoint.com/v2/url?u=https-
> 3A__patchwork.dpdk.org_project_dpdk_patch_20231206112952.1588-
> 2D1-2Dvipin.varghese-
> 40amd.com_&d=DwICaQ&c=nKjWec2b6R0mOyPaz7xtfQ&r=ALGdXl3fZgFGR6
> 9VnJLdSnADun7zLaXG1p5Rs7pXihE&m=OwrvdPIi-
> TQ2UEH3cztfXDzT8YkOB099Pl1mfUzGaq9td0fEWrRBLQQBzAFkjQSU&s=kKin
> YsGoNyTxuLEyPJ0LppT17Yq64CvFBtJMirGEISI&e= .
> >
> > I believe this patch can be taken as-is and we can come up with the solution
> when we can increase the CFG_VALUE_LEN as changing CFG_VALUE_LEN in
> this release is causing ABI breakage.
> >
> > Thanks,
> > Amit Shukla
> >
> >> -----Original Message-----
> >> From: Amit Prakash Shukla
> >> Sent: Wednesday, February 28, 2024 3:08 PM
> >> To: fengchengwen <fengchengwen@huawei.com>; Cheng Jiang
> >> <honest.jiang@foxmail.com>; Gowrishankar Muthukrishnan
> >> <gmuthukrishn@marvell.com>
> >> Cc: dev@dpdk.org; Jerin Jacob <jerinj@marvell.com>; Anoob Joseph
> >> <anoobj@marvell.com>; Kevin Laatz <kevin.laatz@intel.com>; Bruce
> >> Richardson <bruce.richardson@intel.com>; Pavan Nikhilesh Bhagavatula
> >> <pbhagavatula@marvell.com>
> >> Subject: RE: [EXT] Re: [PATCH v2] app/dma-perf: support
> >> bi-directional transfer
> >>
> >> Hi Chengwen,
> >>
> >> Please see my reply in-line.
> >>
> >> Thanks
> >> Amit Shukla
> >>
> >>> -----Original Message-----
> >>> From: fengchengwen <fengchengwen@huawei.com>
> >>> Sent: Wednesday, February 28, 2024 12:34 PM
> >>> To: Amit Prakash Shukla <amitprakashs@marvell.com>; Cheng Jiang
> >>> <honest.jiang@foxmail.com>; Gowrishankar Muthukrishnan
> >>> <gmuthukrishn@marvell.com>
> >>> Cc: dev@dpdk.org; Jerin Jacob <jerinj@marvell.com>; Anoob Joseph
> >>> <anoobj@marvell.com>; Kevin Laatz <kevin.laatz@intel.com>; Bruce
> >>> Richardson <bruce.richardson@intel.com>; Pavan Nikhilesh Bhagavatula
> >>> <pbhagavatula@marvell.com>
> >>> Subject: [EXT] Re: [PATCH v2] app/dma-perf: support bi-directional
> >>> transfer
> >>>
> >>> External Email
> >>>
> >>> --------------------------------------------------------------------
> >>> --
> >>> Hi Amit and Gowrishankar,
> >>>
> >>> It's nature to support multiple dmadev test in one testcase, and the
> >>> original framework supports it.
> >>> But it seem we both complicated it when adding support for non-
> >> mem2mem
> >>> dma test.
> >>>
> >>> The new added "direction" and "vchan_dev" could treat as the
> >>> dmadev's private configure, some thing like:
> >>>
> >>>
> >>
> lcore_dma=lcore10@0000:00:04.2,vchan=0,dir=mem2dev,devtype=pcie,radd
> >>> r=xxx,coreid=1,pfid=2,vfid=3
> >>>
> >>> then this bi-directional could impl only with config:
> >>>
> >>>
> >>
> lcore_dma=lcore10@0000:00:04.2,dir=mem2dev,devtype=pcie,raddr=xxx,cor
> >>> eid=1,pfid=2,vfid=3,
> >>>
> >>
> lcore11@0000:00:04.3,dir=dev2mem,devtype=pcie,raddr=xxx,coreid=1,pfid
> >> =
> >>> 2,vfid=3
> >>> so that the lcore10 will do mem2dev with device 0000:00:04.2, while
> >>> lcore11 will do dev2mem with device 0000:00:04.3.
> >>
> >> Thanks for the suggestion. I will make the suggested changes and send
> >> the next version.

^ permalink raw reply	[relevance 0%]

* Re: [RFC PATCH 1/2] power: refactor core power management library
  @ 2024-03-01  2:56  3%   ` lihuisong (C)
  2024-03-01 10:39  0%     ` Hunt, David
  2024-03-05  4:35  3%     ` Tummala, Sivaprasad
  0 siblings, 2 replies; 200+ results
From: lihuisong (C) @ 2024-03-01  2:56 UTC (permalink / raw)
  To: Sivaprasad Tummala, david.hunt, anatoly.burakov, jerinj,
	radu.nicolau, gakhil, cristian.dumitrescu, ferruh.yigit,
	konstantin.ananyev
  Cc: dev


在 2024/2/20 23:33, Sivaprasad Tummala 写道:
> This patch introduces a comprehensive refactor to the core power
> management library. The primary focus is on improving modularity
> and organization by relocating specific driver implementations
> from the 'lib/power' directory to dedicated directories within
> 'drivers/power/core/*'. The adjustment of meson.build files
> enables the selective activation of individual drivers.
>
> These changes contribute to a significant enhancement in code
> organization, providing a clearer structure for driver implementations.
> The refactor aims to improve overall code clarity and boost
> maintainability. Additionally, it establishes a foundation for
> future development, allowing for more focused work on individual
> drivers and seamless integration of forthcoming enhancements.

Good job. +1 to refacotor.

<...>

> diff --git a/drivers/meson.build b/drivers/meson.build
> index f2be71bc05..e293c3945f 100644
> --- a/drivers/meson.build
> +++ b/drivers/meson.build
> @@ -28,6 +28,7 @@ subdirs = [
>           'event',          # depends on common, bus, mempool and net.
>           'baseband',       # depends on common and bus.
>           'gpu',            # depends on common and bus.
> +        'power',          # depends on common (in future).
>   ]
>   
>   if meson.is_cross_build()
> diff --git a/drivers/power/core/acpi/meson.build b/drivers/power/core/acpi/meson.build
> new file mode 100644
> index 0000000000..d10ec8ee94
> --- /dev/null
> +++ b/drivers/power/core/acpi/meson.build
> @@ -0,0 +1,8 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2024 AMD Limited
> +
> +sources = files('power_acpi_cpufreq.c')
> +
> +headers = files('power_acpi_cpufreq.h')
> +
> +deps += ['power']
> diff --git a/lib/power/power_acpi_cpufreq.c b/drivers/power/core/acpi/power_acpi_cpufreq.c
> similarity index 95%
> rename from lib/power/power_acpi_cpufreq.c
> rename to drivers/power/core/acpi/power_acpi_cpufreq.c
This file is in power lib.
How about remove the 'power' prefix of this file name?
like acpi_cpufreq.c, cppc_cpufreq.c.
> index f8d978d03d..69d80ad2ae 100644
> --- a/lib/power/power_acpi_cpufreq.c
> +++ b/drivers/power/core/acpi/power_acpi_cpufreq.c
> @@ -577,3 +577,22 @@ int power_acpi_get_capabilities(unsigned int lcore_id,
>   
>   	return 0;
>   }
> +
> +static struct rte_power_ops acpi_ops = {
How about use the following structure name?
"struct rte_power_cpufreq_ops" or "struct rte_power_core_ops"
After all, we also have other power ops, like uncore, right?
> +	.init = power_acpi_cpufreq_init,
> +	.exit = power_acpi_cpufreq_exit,
> +	.check_env_support = power_acpi_cpufreq_check_supported,
> +	.get_avail_freqs = power_acpi_cpufreq_freqs,
> +	.get_freq = power_acpi_cpufreq_get_freq,
> +	.set_freq = power_acpi_cpufreq_set_freq,
> +	.freq_down = power_acpi_cpufreq_freq_down,
> +	.freq_up = power_acpi_cpufreq_freq_up,
> +	.freq_max = power_acpi_cpufreq_freq_max,
> +	.freq_min = power_acpi_cpufreq_freq_min,
> +	.turbo_status = power_acpi_turbo_status,
> +	.enable_turbo = power_acpi_enable_turbo,
> +	.disable_turbo = power_acpi_disable_turbo,
> +	.get_caps = power_acpi_get_capabilities
> +};
> +
> +RTE_POWER_REGISTER_OPS(acpi_ops);
> diff --git a/lib/power/power_acpi_cpufreq.h b/drivers/power/core/acpi/power_acpi_cpufreq.h
> similarity index 100%
> rename from lib/power/power_acpi_cpufreq.h
> rename to drivers/power/core/acpi/power_acpi_cpufreq.h
> diff --git a/drivers/power/core/amd-pstate/meson.build b/drivers/power/core/amd-pstate/meson.build
> new file mode 100644
> index 0000000000..8ec4c960f5
> --- /dev/null
> +++ b/drivers/power/core/amd-pstate/meson.build
> @@ -0,0 +1,8 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2024 AMD Limited
> +
> +sources = files('power_amd_pstate_cpufreq.c')
> +
> +headers = files('power_amd_pstate_cpufreq.h')
> +
> +deps += ['power']
> diff --git a/lib/power/power_amd_pstate_cpufreq.c b/drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.c
> similarity index 95%
> rename from lib/power/power_amd_pstate_cpufreq.c
> rename to drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.c
> index 028f84416b..9938de72a6 100644
> --- a/lib/power/power_amd_pstate_cpufreq.c
> +++ b/drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.c
> @@ -700,3 +700,22 @@ power_amd_pstate_get_capabilities(unsigned int lcore_id,
>   
>   	return 0;
>   }
> +
> +static struct rte_power_ops amd_pstate_ops = {
> +	.init = power_amd_pstate_cpufreq_init,
> +	.exit = power_amd_pstate_cpufreq_exit,
> +	.check_env_support = power_amd_pstate_cpufreq_check_supported,
> +	.get_avail_freqs = power_amd_pstate_cpufreq_freqs,
> +	.get_freq = power_amd_pstate_cpufreq_get_freq,
> +	.set_freq = power_amd_pstate_cpufreq_set_freq,
> +	.freq_down = power_amd_pstate_cpufreq_freq_down,
> +	.freq_up = power_amd_pstate_cpufreq_freq_up,
> +	.freq_max = power_amd_pstate_cpufreq_freq_max,
> +	.freq_min = power_amd_pstate_cpufreq_freq_min,
> +	.turbo_status = power_amd_pstate_turbo_status,
> +	.enable_turbo = power_amd_pstate_enable_turbo,
> +	.disable_turbo = power_amd_pstate_disable_turbo,
> +	.get_caps = power_amd_pstate_get_capabilities
> +};
> +
> +RTE_POWER_REGISTER_OPS(amd_pstate_ops);
> diff --git a/lib/power/power_amd_pstate_cpufreq.h b/drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.h
> similarity index 100%
> rename from lib/power/power_amd_pstate_cpufreq.h
> rename to drivers/power/core/amd-pstate/power_amd_pstate_cpufreq.h
> diff --git a/drivers/power/core/cppc/meson.build b/drivers/power/core/cppc/meson.build
> new file mode 100644
> index 0000000000..06f3b99bb8
> --- /dev/null
> +++ b/drivers/power/core/cppc/meson.build
> @@ -0,0 +1,8 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2024 AMD Limited
> +
> +sources = files('power_cppc_cpufreq.c')
> +
> +headers = files('power_cppc_cpufreq.h')
> +
> +deps += ['power']
> diff --git a/lib/power/power_cppc_cpufreq.c b/drivers/power/core/cppc/power_cppc_cpufreq.c
> similarity index 96%
> rename from lib/power/power_cppc_cpufreq.c
> rename to drivers/power/core/cppc/power_cppc_cpufreq.c
> index 3ddf39bd76..605f633309 100644
> --- a/lib/power/power_cppc_cpufreq.c
> +++ b/drivers/power/core/cppc/power_cppc_cpufreq.c
> @@ -685,3 +685,22 @@ power_cppc_get_capabilities(unsigned int lcore_id,
>   
>   	return 0;
>   }
> +
> +static struct rte_power_ops cppc_ops = {
> +	.init = power_cppc_cpufreq_init,
> +	.exit = power_cppc_cpufreq_exit,
> +	.check_env_support = power_cppc_cpufreq_check_supported,
> +	.get_avail_freqs = power_cppc_cpufreq_freqs,
> +	.get_freq = power_cppc_cpufreq_get_freq,
> +	.set_freq = power_cppc_cpufreq_set_freq,
> +	.freq_down = power_cppc_cpufreq_freq_down,
> +	.freq_up = power_cppc_cpufreq_freq_up,
> +	.freq_max = power_cppc_cpufreq_freq_max,
> +	.freq_min = power_cppc_cpufreq_freq_min,
> +	.turbo_status = power_cppc_turbo_status,
> +	.enable_turbo = power_cppc_enable_turbo,
> +	.disable_turbo = power_cppc_disable_turbo,
> +	.get_caps = power_cppc_get_capabilities
> +};
> +
> +RTE_POWER_REGISTER_OPS(cppc_ops);
> diff --git a/lib/power/power_cppc_cpufreq.h b/drivers/power/core/cppc/power_cppc_cpufreq.h
> similarity index 100%
> rename from lib/power/power_cppc_cpufreq.h
> rename to drivers/power/core/cppc/power_cppc_cpufreq.h
> diff --git a/lib/power/guest_channel.c b/drivers/power/core/kvm-vm/guest_channel.c
> similarity index 100%
> rename from lib/power/guest_channel.c
> rename to drivers/power/core/kvm-vm/guest_channel.c
> diff --git a/lib/power/guest_channel.h b/drivers/power/core/kvm-vm/guest_channel.h
> similarity index 100%
> rename from lib/power/guest_channel.h
> rename to drivers/power/core/kvm-vm/guest_channel.h
> diff --git a/drivers/power/core/kvm-vm/meson.build b/drivers/power/core/kvm-vm/meson.build
> new file mode 100644
> index 0000000000..3150c6674b
> --- /dev/null
> +++ b/drivers/power/core/kvm-vm/meson.build
> @@ -0,0 +1,20 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(C) 2024 AMD Limited.
> +#
> +
> +if not is_linux
> +    build = false
> +    reason = 'only supported on Linux'
> +    subdir_done()
> +endif
> +
> +sources = files(
> +        'guest_channel.c',
> +        'power_kvm_vm.c',
> +)
> +
> +headers = files(
> +        'guest_channel.h',
> +        'power_kvm_vm.h',
> +)
> +deps += ['power']
> diff --git a/lib/power/power_kvm_vm.c b/drivers/power/core/kvm-vm/power_kvm_vm.c
> similarity index 83%
> rename from lib/power/power_kvm_vm.c
> rename to drivers/power/core/kvm-vm/power_kvm_vm.c
> index f15be8fac5..a5d6984d26 100644
> --- a/lib/power/power_kvm_vm.c
> +++ b/drivers/power/core/kvm-vm/power_kvm_vm.c
> @@ -137,3 +137,22 @@ int power_kvm_vm_get_capabilities(__rte_unused unsigned int lcore_id,
>   	POWER_LOG(ERR, "rte_power_get_capabilities is not implemented for Virtual Machine Power Management");
>   	return -ENOTSUP;
>   }
> +
> +static struct rte_power_ops kvm_vm_ops = {
> +	.init = power_kvm_vm_init,
> +	.exit = power_kvm_vm_exit,
> +	.check_env_support = power_kvm_vm_check_supported,
> +	.get_avail_freqs = power_kvm_vm_freqs,
> +	.get_freq = power_kvm_vm_get_freq,
> +	.set_freq = power_kvm_vm_set_freq,
> +	.freq_down = power_kvm_vm_freq_down,
> +	.freq_up = power_kvm_vm_freq_up,
> +	.freq_max = power_kvm_vm_freq_max,
> +	.freq_min = power_kvm_vm_freq_min,
> +	.turbo_status = power_kvm_vm_turbo_status,
> +	.enable_turbo = power_kvm_vm_enable_turbo,
> +	.disable_turbo = power_kvm_vm_disable_turbo,
> +	.get_caps = power_kvm_vm_get_capabilities
> +};
> +
> +RTE_POWER_REGISTER_OPS(kvm_vm_ops);
> diff --git a/lib/power/power_kvm_vm.h b/drivers/power/core/kvm-vm/power_kvm_vm.h
> similarity index 100%
> rename from lib/power/power_kvm_vm.h
> rename to drivers/power/core/kvm-vm/power_kvm_vm.h
> diff --git a/drivers/power/core/meson.build b/drivers/power/core/meson.build
> new file mode 100644
> index 0000000000..4081dafaa0
> --- /dev/null
> +++ b/drivers/power/core/meson.build
> @@ -0,0 +1,12 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2024 AMD Limited
> +
> +drivers = [
> +        'acpi',
> +        'amd-pstate',
> +        'cppc',
> +        'kvm-vm',
> +        'pstate'
> +]
> +
> +std_deps = ['power']
> diff --git a/drivers/power/core/pstate/meson.build b/drivers/power/core/pstate/meson.build
> new file mode 100644
> index 0000000000..1025c64e48
> --- /dev/null
> +++ b/drivers/power/core/pstate/meson.build
> @@ -0,0 +1,8 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2024 AMD Limited
> +
> +sources = files('power_pstate_cpufreq.c')
> +
> +headers = files('power_pstate_cpufreq.h')
> +
> +deps += ['power']
> diff --git a/lib/power/power_pstate_cpufreq.c b/drivers/power/core/pstate/power_pstate_cpufreq.c
> similarity index 96%
> rename from lib/power/power_pstate_cpufreq.c
> rename to drivers/power/core/pstate/power_pstate_cpufreq.c
> index 73138dc4e4..d4c3645ff8 100644
> --- a/lib/power/power_pstate_cpufreq.c
> +++ b/drivers/power/core/pstate/power_pstate_cpufreq.c
> @@ -888,3 +888,22 @@ int power_pstate_get_capabilities(unsigned int lcore_id,
>   
>   	return 0;
>   }
> +
> +static struct rte_power_ops pstate_ops = {
> +	.init = power_pstate_cpufreq_init,
> +	.exit = power_pstate_cpufreq_exit,
> +	.check_env_support = power_pstate_cpufreq_check_supported,
> +	.get_avail_freqs = power_pstate_cpufreq_freqs,
> +	.get_freq = power_pstate_cpufreq_get_freq,
> +	.set_freq = power_pstate_cpufreq_set_freq,
> +	.freq_down = power_pstate_cpufreq_freq_down,
> +	.freq_up = power_pstate_cpufreq_freq_up,
> +	.freq_max = power_pstate_cpufreq_freq_max,
> +	.freq_min = power_pstate_cpufreq_freq_min,
> +	.turbo_status = power_pstate_turbo_status,
> +	.enable_turbo = power_pstate_enable_turbo,
> +	.disable_turbo = power_pstate_disable_turbo,
> +	.get_caps = power_pstate_get_capabilities
> +};
> +
> +RTE_POWER_REGISTER_OPS(pstate_ops);
> diff --git a/lib/power/power_pstate_cpufreq.h b/drivers/power/core/pstate/power_pstate_cpufreq.h
> similarity index 100%
> rename from lib/power/power_pstate_cpufreq.h
> rename to drivers/power/core/pstate/power_pstate_cpufreq.h
> diff --git a/drivers/power/meson.build b/drivers/power/meson.build
> new file mode 100644
> index 0000000000..7d9034c7ac
> --- /dev/null
> +++ b/drivers/power/meson.build
> @@ -0,0 +1,8 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2024 AMD Limited
> +
> +drivers = [
> +        'core',
> +]
> +
> +std_deps = ['power']
> diff --git a/lib/power/meson.build b/lib/power/meson.build
> index b8426589b2..207d96d877 100644
> --- a/lib/power/meson.build
> +++ b/lib/power/meson.build
> @@ -12,14 +12,8 @@ if not is_linux
>       reason = 'only supported on Linux'
>   endif
>   sources = files(
> -        'guest_channel.c',
> -        'power_acpi_cpufreq.c',
> -        'power_amd_pstate_cpufreq.c',
>           'power_common.c',
> -        'power_cppc_cpufreq.c',
> -        'power_kvm_vm.c',
>           'power_intel_uncore.c',
> -        'power_pstate_cpufreq.c',
>           'rte_power.c',
>           'rte_power_uncore.c',
>           'rte_power_pmd_mgmt.c',
> diff --git a/lib/power/power_common.h b/lib/power/power_common.h
> index 30966400ba..c90b611f4f 100644
> --- a/lib/power/power_common.h
> +++ b/lib/power/power_common.h
> @@ -23,13 +23,24 @@ extern int power_logtype;
>   #endif
>   
>   /* check if scaling driver matches one we want */
> +__rte_internal
>   int cpufreq_check_scaling_driver(const char *driver);
> +
> +__rte_internal
>   int power_set_governor(unsigned int lcore_id, const char *new_governor,
>   		char *orig_governor, size_t orig_governor_len);
> +
> +__rte_internal
>   int open_core_sysfs_file(FILE **f, const char *mode, const char *format, ...)
>   		__rte_format_printf(3, 4);
> +
> +__rte_internal
>   int read_core_sysfs_u32(FILE *f, uint32_t *val);
> +
> +__rte_internal
>   int read_core_sysfs_s(FILE *f, char *buf, unsigned int len);
> +
> +__rte_internal
>   int write_core_sysfs_s(FILE *f, const char *str);
>   
>   #endif /* _POWER_COMMON_H_ */
> diff --git a/lib/power/rte_power.c b/lib/power/rte_power.c
> index 36c3f3da98..70176807f4 100644
> --- a/lib/power/rte_power.c
> +++ b/lib/power/rte_power.c
> @@ -8,64 +8,80 @@
>   #include <rte_spinlock.h>
>   
>   #include "rte_power.h"
> -#include "power_acpi_cpufreq.h"
> -#include "power_cppc_cpufreq.h"
>   #include "power_common.h"
> -#include "power_kvm_vm.h"
> -#include "power_pstate_cpufreq.h"
> -#include "power_amd_pstate_cpufreq.h"
>   
>   enum power_management_env global_default_env = PM_ENV_NOT_SET;
use a pointer to save the current power cpufreq ops?
>   
>   static rte_spinlock_t global_env_cfg_lock = RTE_SPINLOCK_INITIALIZER;
> +static struct rte_power_ops rte_power_ops[PM_ENV_MAX];
>   
> -/* function pointers */
> -rte_power_freqs_t rte_power_freqs  = NULL;
> -rte_power_get_freq_t rte_power_get_freq = NULL;
> -rte_power_set_freq_t rte_power_set_freq = NULL;
> -rte_power_freq_change_t rte_power_freq_up = NULL;
> -rte_power_freq_change_t rte_power_freq_down = NULL;
> -rte_power_freq_change_t rte_power_freq_max = NULL;
> -rte_power_freq_change_t rte_power_freq_min = NULL;
> -rte_power_freq_change_t rte_power_turbo_status;
> -rte_power_freq_change_t rte_power_freq_enable_turbo;
> -rte_power_freq_change_t rte_power_freq_disable_turbo;
> -rte_power_get_capabilities_t rte_power_get_capabilities;
> -
> -static void
> -reset_power_function_ptrs(void)
> +/* register the ops struct in rte_power_ops, return 0 on success. */
> +int
> +rte_power_register_ops(const struct rte_power_ops *op)
> +{
> +	struct rte_power_ops *ops;
> +
> +	if (op->env >= PM_ENV_MAX) {
> +		POWER_LOG(ERR, "Unsupported power management environment\n");
> +		return -EINVAL;
> +	}
> +
> +	if (op->status != 0) {
> +		POWER_LOG(ERR, "Power management env[%d] ops registered already\n",
> +			op->env);
> +		return -EINVAL;
> +	}
> +
> +	if (!op->init || !op->exit || !op->check_env_support ||
> +		!op->get_avail_freqs || !op->get_freq || !op->set_freq ||
> +		!op->freq_up || !op->freq_down || !op->freq_max ||
> +		!op->freq_min || !op->turbo_status || !op->enable_turbo ||
> +		!op->disable_turbo || !op->get_caps) {
> +		POWER_LOG(ERR, "Missing callbacks while registering power ops\n");
> +		return -EINVAL;
> +	}
> +
> +	ops = &rte_power_ops[op->env];
It is better to use a global linked list instead of an array.
And we should extract a list structure including this ops structure and 
this ops's owner.
> +	ops->env = op->env;
> +	ops->init = op->init;
> +	ops->exit = op->exit;
> +	ops->check_env_support = op->check_env_support;
> +	ops->get_avail_freqs = op->get_avail_freqs;
> +	ops->get_freq = op->get_freq;
> +	ops->set_freq = op->set_freq;
> +	ops->freq_up = op->freq_up;
> +	ops->freq_down = op->freq_down;
> +	ops->freq_max = op->freq_max;
> +	ops->freq_min = op->freq_min;
> +	ops->turbo_status = op->turbo_status;
> +	ops->enable_turbo = op->enable_turbo;
> +	ops->disable_turbo = op->disable_turbo;
*ops = *op?
> +	ops->status = 1; /* registered */
status --> registered?
But if use ops linked list, this flag also can be removed.
> +
> +	return 0;
> +}
> +
> +struct rte_power_ops *
> +rte_power_get_ops(int ops_index)
AFAICS, there is only one cpufreq driver on one platform and just have 
one power_cpufreq_ops to use for user.
We don't need user to get other power ops, and user just want to know 
the power ops using currently, right?
So using 'index' toget this ops is not good.
>   {
> -	rte_power_freqs  = NULL;
> -	rte_power_get_freq = NULL;
> -	rte_power_set_freq = NULL;
> -	rte_power_freq_up = NULL;
> -	rte_power_freq_down = NULL;
> -	rte_power_freq_max = NULL;
> -	rte_power_freq_min = NULL;
> -	rte_power_turbo_status = NULL;
> -	rte_power_freq_enable_turbo = NULL;
> -	rte_power_freq_disable_turbo = NULL;
> -	rte_power_get_capabilities = NULL;
> +	RTE_VERIFY((ops_index >= PM_ENV_NOT_SET) && (ops_index < PM_ENV_MAX));
> +	RTE_VERIFY(rte_power_ops[ops_index].status != 0);
> +
> +	return &rte_power_ops[ops_index];
>   }
>   
>   int
>   rte_power_check_env_supported(enum power_management_env env)
>   {
> -	switch (env) {
> -	case PM_ENV_ACPI_CPUFREQ:
> -		return power_acpi_cpufreq_check_supported();
> -	case PM_ENV_PSTATE_CPUFREQ:
> -		return power_pstate_cpufreq_check_supported();
> -	case PM_ENV_KVM_VM:
> -		return power_kvm_vm_check_supported();
> -	case PM_ENV_CPPC_CPUFREQ:
> -		return power_cppc_cpufreq_check_supported();
> -	case PM_ENV_AMD_PSTATE_CPUFREQ:
> -		return power_amd_pstate_cpufreq_check_supported();
> -	default:
> -		rte_errno = EINVAL;
> -		return -1;
> +	struct rte_power_ops *ops;
> +
> +	if ((env > PM_ENV_NOT_SET) && (env < PM_ENV_MAX)) {
> +		ops = rte_power_get_ops(env);
> +		return ops->check_env_support();
>   	}
> +
> +	rte_errno = EINVAL;
> +	return -1;
>   }
>   
>   int
> @@ -80,80 +96,26 @@ rte_power_set_env(enum power_management_env env)
>   	}
>   
>   	int ret = 0;
> +	struct rte_power_ops *ops;
> +
> +	if ((env == PM_ENV_NOT_SET) || (env >= PM_ENV_MAX)) {
> +		POWER_LOG(ERR, "Invalid Power Management Environment(%d)"
> +				" set\n", env);
> +		ret = -1;
> +	}
>   
<...>
> +	ops = rte_power_get_ops(env);
To find the target ops from the global list according to the env?
> +	if (ops->status == 0) {
> +		POWER_LOG(ERR, WER,
> +			"Power Management Environment(%d) not"
> +			" registered\n", env);
>   		ret = -1;
>   	}
>   
>   	if (ret == 0)
>   		global_default_env = env;
It is more convenient to use a global variable to point to the default 
power_cpufreq ops or its list node.
> -	else {
> +	else
>   		global_default_env = PM_ENV_NOT_SET;
> -		reset_power_function_ptrs();
> -	}
>   
>   	rte_spinlock_unlock(&global_env_cfg_lock);
>   	return ret;
> @@ -164,7 +126,6 @@ rte_power_unset_env(void)
>   {
>   	rte_spinlock_lock(&global_env_cfg_lock);
>   	global_default_env = PM_ENV_NOT_SET;
> -	reset_power_function_ptrs();
>   	rte_spinlock_unlock(&global_env_cfg_lock);
>   }
>   
> @@ -177,59 +138,76 @@ int
>   rte_power_init(unsigned int lcore_id)
>   {
>   	int ret = -1;
> +	struct rte_power_ops *ops;
>   
> -	switch (global_default_env) {
> -	case PM_ENV_ACPI_CPUFREQ:
> -		return power_acpi_cpufreq_init(lcore_id);
> -	case PM_ENV_KVM_VM:
> -		return power_kvm_vm_init(lcore_id);
> -	case PM_ENV_PSTATE_CPUFREQ:
> -		return power_pstate_cpufreq_init(lcore_id);
> -	case PM_ENV_CPPC_CPUFREQ:
> -		return power_cppc_cpufreq_init(lcore_id);
> -	case PM_ENV_AMD_PSTATE_CPUFREQ:
> -		return power_amd_pstate_cpufreq_init(lcore_id);
> -	default:
> -		POWER_LOG(INFO, "Env isn't set yet!");
> +	if (global_default_env != PM_ENV_NOT_SET) {
> +		ops = &rte_power_ops[global_default_env];
> +		if (!ops->status) {
> +			POWER_LOG(ERR, "Power management env[%d] not"
> +				" supported\n", global_default_env);
> +			goto out;
> +		}
> +		return ops->init(lcore_id);
>   	}
> +	POWER_LOG(INFO, POWER, "Env isn't set yet!\n");
>   
>   	/* Auto detect Environment */
> -	POWER_LOG(INFO, "Attempting to initialise ACPI cpufreq power management...");
> -	ret = power_acpi_cpufreq_init(lcore_id);
> -	if (ret == 0) {
> -		rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
> -		goto out;
> +	POWER_LOG(INFO, "Attempting to initialise ACPI cpufreq"
> +			" power management...\n");
> +	ops = &rte_power_ops[PM_ENV_ACPI_CPUFREQ];
> +	if (ops->status) {
> +		ret = ops->init(lcore_id);
> +		if (ret == 0) {
> +			rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
> +			goto out;
> +		}
>   	}
>   
> -	POWER_LOG(INFO, "Attempting to initialise PSTAT power management...");
> -	ret = power_pstate_cpufreq_init(lcore_id);
> -	if (ret == 0) {
> -		rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
> -		goto out;
> +	POWER_LOG(INFO, "Attempting to initialise PSTAT"
> +			" power management...\n");
> +	ops = &rte_power_ops[PM_ENV_PSTATE_CPUFREQ];
> +	if (ops->status) {
> +		ret = ops->init(lcore_id);
> +		if (ret == 0) {
> +			rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
> +			goto out;
> +		}
>   	}
>   
> -	POWER_LOG(INFO, "Attempting to initialise AMD PSTATE power management...");
> -	ret = power_amd_pstate_cpufreq_init(lcore_id);
> -	if (ret == 0) {
> -		rte_power_set_env(PM_ENV_AMD_PSTATE_CPUFREQ);
> -		goto out;
> +	POWER_LOG(INFO,	"Attempting to initialise AMD PSTATE"
> +			" power management...\n");
> +	ops = &rte_power_ops[PM_ENV_AMD_PSTATE_CPUFREQ];
> +	if (ops->status) {
> +		ret = ops->init(lcore_id);
> +		if (ret == 0) {
> +			rte_power_set_env(PM_ENV_AMD_PSTATE_CPUFREQ);
> +			goto out;
> +		}
>   	}
>   
> -	POWER_LOG(INFO, "Attempting to initialise CPPC power management...");
> -	ret = power_cppc_cpufreq_init(lcore_id);
> -	if (ret == 0) {
> -		rte_power_set_env(PM_ENV_CPPC_CPUFREQ);
> -		goto out;
> +	POWER_LOG(INFO, "Attempting to initialise CPPC power"
> +			" management...\n");
> +	ops = &rte_power_ops[PM_ENV_CPPC_CPUFREQ];
> +	if (ops->status) {
> +		ret = ops->init(lcore_id);
> +		if (ret == 0) {
> +			rte_power_set_env(PM_ENV_CPPC_CPUFREQ);
> +			goto out;
> +		}
>   	}
>   
> -	POWER_LOG(INFO, "Attempting to initialise VM power management...");
> -	ret = power_kvm_vm_init(lcore_id);
> -	if (ret == 0) {
> -		rte_power_set_env(PM_ENV_KVM_VM);
> -		goto out;
> +	POWER_LOG(INFO, "Attempting to initialise VM power"
> +			" management...\n");
> +	ops = &rte_power_ops[PM_ENV_KVM_VM];
> +	if (ops->status) {
> +		ret = ops->init(lcore_id);
> +		if (ret == 0) {
> +			rte_power_set_env(PM_ENV_KVM_VM);
> +			goto out;
> +		}
>   	}
If we use a linked list, above code can be simpled like this:
->
for_each_power_cpufreq_ops(ops, ...) {
     ret = ops->init()
     if (ret) {
         ....
     }
}
> -	POWER_LOG(ERR, "Unable to set Power Management Environment for lcore "
> -			"%u", lcore_id);
> +	POWER_LOG(ERR, "Unable to set Power Management Environment"
> +			" for lcore %u\n", lcore_id);
>   out:
>   	return ret;
>   }
> @@ -237,21 +215,14 @@ rte_power_init(unsigned int lcore_id)
>   int
>   rte_power_exit(unsigned int lcore_id)
>   {
> -	switch (global_default_env) {
> -	case PM_ENV_ACPI_CPUFREQ:
> -		return power_acpi_cpufreq_exit(lcore_id);
> -	case PM_ENV_KVM_VM:
> -		return power_kvm_vm_exit(lcore_id);
> -	case PM_ENV_PSTATE_CPUFREQ:
> -		return power_pstate_cpufreq_exit(lcore_id);
> -	case PM_ENV_CPPC_CPUFREQ:
> -		return power_cppc_cpufreq_exit(lcore_id);
> -	case PM_ENV_AMD_PSTATE_CPUFREQ:
> -		return power_amd_pstate_cpufreq_exit(lcore_id);
> -	default:
> -		POWER_LOG(ERR, "Environment has not been set, unable to exit gracefully");
> +	struct rte_power_ops *ops;
>   
> +	if (global_default_env != PM_ENV_NOT_SET) {
> +		ops = &rte_power_ops[global_default_env];
> +		return ops->exit(lcore_id);
>   	}
> -	return -1;
> +	POWER_LOG(ERR, "Environment has not been set, unable "
> +			"to exit gracefully\n");
>   
> +	return -1;
>   }
> diff --git a/lib/power/rte_power.h b/lib/power/rte_power.h
> index 4fa4afe399..749bb823ab 100644
> --- a/lib/power/rte_power.h
> +++ b/lib/power/rte_power.h
> @@ -1,5 +1,6 @@
>   /* SPDX-License-Identifier: BSD-3-Clause
>    * Copyright(c) 2010-2014 Intel Corporation
> + * Copyright(c) 2024 AMD Limited
>    */
>   
>   #ifndef _RTE_POWER_H
> @@ -21,7 +22,7 @@ extern "C" {
>   /* Power Management Environment State */
>   enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM,
>   		PM_ENV_PSTATE_CPUFREQ, PM_ENV_CPPC_CPUFREQ,
> -		PM_ENV_AMD_PSTATE_CPUFREQ};
> +		PM_ENV_AMD_PSTATE_CPUFREQ, PM_ENV_MAX};
"enum power_management_env" is not good. may be like "enum 
power_cpufreq_driver_type"?
In previous linked list structure to be defined, may be directly use a 
string name instead of a fixed enum is better.
Becuase the new "PM_ENV_MAX" will  lead to break ABI when add a new 
cpufreq driver.
>   
>   /**
>    * Check if a specific power management environment type is supported on a
> @@ -66,6 +67,97 @@ void rte_power_unset_env(void);
>    */
>   enum power_management_env rte_power_get_env(void);
>   
> +typedef int (*rte_power_cpufreq_init_t)(unsigned int lcore_id);
> +typedef int (*rte_power_cpufreq_exit_t)(unsigned int lcore_id);
> +typedef int (*rte_power_check_env_support_t)(void);
> +
> +typedef uint32_t (*rte_power_freqs_t)(unsigned int lcore_id, uint32_t *freqs,
> +					uint32_t num);
> +typedef uint32_t (*rte_power_get_freq_t)(unsigned int lcore_id);
> +typedef int (*rte_power_set_freq_t)(unsigned int lcore_id, uint32_t index);
> +typedef int (*rte_power_freq_change_t)(unsigned int lcore_id);
> +
> +/**
> + * Function pointer definition for generic frequency change functions. Review
> + * each environments specific documentation for usage.
> + *
> + * @param lcore_id
> + *  lcore id.
> + *
> + * @return
> + *  - 1 on success with frequency changed.
> + *  - 0 on success without frequency changed.
> + *  - Negative on error.
> + */
> +
> +/**
> + * Power capabilities summary.
> + */
> +struct rte_power_core_capabilities {
> +	union {
> +		uint64_t capabilities;
> +		struct {
> +			uint64_t turbo:1;       /**< Turbo can be enabled. */
> +			uint64_t priority:1;    /**< SST-BF high freq core */
> +		};
> +	};
> +};
> +
> +typedef int (*rte_power_get_capabilities_t)(unsigned int lcore_id,
> +				struct rte_power_core_capabilities *caps);
> +
> +/** Structure defining core power operations structure */
> +struct rte_power_ops {
> +uint8_t status;                         /**< ops register status. */
> +	enum power_management_env env;          /**< power mgmt env. */
> +	rte_power_cpufreq_init_t init;    /**< Initialize power management. */
> +	rte_power_cpufreq_exit_t exit;    /**< Exit power management. */
> +	rte_power_check_env_support_t check_env_support; /**< verify env is supported. */
> +	rte_power_freqs_t get_avail_freqs; /**< Get the available frequencies. */
> +	rte_power_get_freq_t get_freq; /**< Get frequency index. */
> +	rte_power_set_freq_t set_freq; /**< Set frequency index. */
> +	rte_power_freq_change_t freq_up;   /**< Scale up frequency. */
> +	rte_power_freq_change_t freq_down; /**< Scale down frequency. */
> +	rte_power_freq_change_t freq_max;  /**< Scale up frequency to highest. */
> +	rte_power_freq_change_t freq_min;  /**< Scale up frequency to lowest. */
> +	rte_power_freq_change_t turbo_status; /**< Get Turbo status. */
> +	rte_power_freq_change_t enable_turbo; /**< Enable Turbo. */
> +	rte_power_freq_change_t disable_turbo; /**< Disable Turbo. */
> +	rte_power_get_capabilities_t get_caps; /**< power capabilities. */
> +} __rte_cache_aligned;
Suggest that fix this sturcture, like:
struct rte_power_cpufreq_list {
     char name[];   // like "cppc_cpufreq", "pstate_cpufreq"
     struct rte_power_cpufreq *ops;
     struct rte_power_cpufreq_list *node;
}
> +
> +/**
> + * Register power cpu frequency operations.
> + *
> + * @param ops
> + *   Pointer to an ops structure to register.
> + * @return
> + *   - >=0: Success; return the index of the ops struct in the table.
> + *   - -EINVAL - error while registering ops struct.
> + */
> +__rte_internal
> +int rte_power_register_ops(const struct rte_power_ops *ops);
> +
> +/**
> + * Macro to statically register the ops of a cpufreq driver.
> + */
> +#define RTE_POWER_REGISTER_OPS(ops)		\
> +	(RTE_INIT(power_hdlr_init_##ops)	\
> +	{					\
> +		rte_power_register_ops(&ops);	\
> +	})
> +
> +/**
> + * @internal Get the power ops struct from its index.
> + *
> + * @param ops_index
> + *   The index of the ops struct in the ops struct table.
> + * @return
> + *   The pointer to the ops struct in the table if registered.
> + */
> +struct rte_power_ops *
> +rte_power_get_ops(int ops_index);
> +
>   /**
>    * Initialize power management for a specific lcore. If rte_power_set_env() has
>    * not been called then an auto-detect of the environment will start and
> @@ -108,10 +200,14 @@ int rte_power_exit(unsigned int lcore_id);
>    * @return
>    *  The number of available frequencies.
>    */
> -typedef uint32_t (*rte_power_freqs_t)(unsigned int lcore_id, uint32_t *freqs,
> -		uint32_t num);
> +static inline uint32_t
> +rte_power_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t n)
> +{
> +	struct rte_power_ops *ops;
>   
> -extern rte_power_freqs_t rte_power_freqs;
> +	ops = rte_power_get_ops(rte_power_get_env());
> +	return ops->get_avail_freqs(lcore_id, freqs, n);
> +}
nice.
<...>

^ permalink raw reply	[relevance 3%]

* Re: [EXT] Re: [PATCH v2] app/dma-perf: support bi-directional transfer
  2024-02-29 14:03  3%       ` Amit Prakash Shukla
@ 2024-03-01  1:46  0%         ` fengchengwen
  2024-03-01  8:31  0%           ` [EXTERNAL] " Amit Prakash Shukla
  0 siblings, 1 reply; 200+ results
From: fengchengwen @ 2024-03-01  1:46 UTC (permalink / raw)
  To: Amit Prakash Shukla, Cheng Jiang, Gowrishankar Muthukrishnan
  Cc: dev, Jerin Jacob, Anoob Joseph, Kevin Laatz, Bruce Richardson,
	Pavan Nikhilesh Bhagavatula

Hi Amit,

I think this commit will complicated the test, plus futer we may add more test (e.g. fill)

I agree Bruce's advise in the [1], let also support "lcore_dma0/1/2",

User could provide dma info by two way:
1) lcore_dma=, which seperate each dma with ", ", but a maximum of a certain number is allowed.
2) lcore_dma0/1/2/..., each dma device take one line

[1] https://patchwork.dpdk.org/project/dpdk/patch/20231206112952.1588-1-vipin.varghese@amd.com/

Thanks

On 2024/2/29 22:03, Amit Prakash Shukla wrote:
> Hi Chengwen,
> 
> I liked your suggestion and tried making changes, but encountered parsing issue for CFG files with line greater than CFG_VALUE_LEN=256(current value set).
> 
> There is a discussion on the similar lines in another patch set: https://patchwork.dpdk.org/project/dpdk/patch/20231206112952.1588-1-vipin.varghese@amd.com/.
> 
> I believe this patch can be taken as-is and we can come up with the solution when we can increase the CFG_VALUE_LEN as changing CFG_VALUE_LEN in this release is causing ABI breakage.
> 
> Thanks,
> Amit Shukla
> 
>> -----Original Message-----
>> From: Amit Prakash Shukla
>> Sent: Wednesday, February 28, 2024 3:08 PM
>> To: fengchengwen <fengchengwen@huawei.com>; Cheng Jiang
>> <honest.jiang@foxmail.com>; Gowrishankar Muthukrishnan
>> <gmuthukrishn@marvell.com>
>> Cc: dev@dpdk.org; Jerin Jacob <jerinj@marvell.com>; Anoob Joseph
>> <anoobj@marvell.com>; Kevin Laatz <kevin.laatz@intel.com>; Bruce
>> Richardson <bruce.richardson@intel.com>; Pavan Nikhilesh Bhagavatula
>> <pbhagavatula@marvell.com>
>> Subject: RE: [EXT] Re: [PATCH v2] app/dma-perf: support bi-directional
>> transfer
>>
>> Hi Chengwen,
>>
>> Please see my reply in-line.
>>
>> Thanks
>> Amit Shukla
>>
>>> -----Original Message-----
>>> From: fengchengwen <fengchengwen@huawei.com>
>>> Sent: Wednesday, February 28, 2024 12:34 PM
>>> To: Amit Prakash Shukla <amitprakashs@marvell.com>; Cheng Jiang
>>> <honest.jiang@foxmail.com>; Gowrishankar Muthukrishnan
>>> <gmuthukrishn@marvell.com>
>>> Cc: dev@dpdk.org; Jerin Jacob <jerinj@marvell.com>; Anoob Joseph
>>> <anoobj@marvell.com>; Kevin Laatz <kevin.laatz@intel.com>; Bruce
>>> Richardson <bruce.richardson@intel.com>; Pavan Nikhilesh Bhagavatula
>>> <pbhagavatula@marvell.com>
>>> Subject: [EXT] Re: [PATCH v2] app/dma-perf: support bi-directional
>>> transfer
>>>
>>> External Email
>>>
>>> ----------------------------------------------------------------------
>>> Hi Amit and Gowrishankar,
>>>
>>> It's nature to support multiple dmadev test in one testcase, and the
>>> original framework supports it.
>>> But it seem we both complicated it when adding support for non-
>> mem2mem
>>> dma test.
>>>
>>> The new added "direction" and "vchan_dev" could treat as the dmadev's
>>> private configure, some thing like:
>>>
>>>
>> lcore_dma=lcore10@0000:00:04.2,vchan=0,dir=mem2dev,devtype=pcie,radd
>>> r=xxx,coreid=1,pfid=2,vfid=3
>>>
>>> then this bi-directional could impl only with config:
>>>
>>>
>> lcore_dma=lcore10@0000:00:04.2,dir=mem2dev,devtype=pcie,raddr=xxx,cor
>>> eid=1,pfid=2,vfid=3,
>>>
>> lcore11@0000:00:04.3,dir=dev2mem,devtype=pcie,raddr=xxx,coreid=1,pfid=
>>> 2,vfid=3
>>> so that the lcore10 will do mem2dev with device 0000:00:04.2, while
>>> lcore11 will do dev2mem with device 0000:00:04.3.
>>
>> Thanks for the suggestion. I will make the suggested changes and send the
>> next version.

^ permalink raw reply	[relevance 0%]

* [PATCH v4 4/6] pipeline: replace zero length array with flex array
  @ 2024-02-29 22:58  4%   ` Tyler Retzlaff
  0 siblings, 0 replies; 200+ results
From: Tyler Retzlaff @ 2024-02-29 22:58 UTC (permalink / raw)
  To: dev
  Cc: Bruce Richardson, Cristian Dumitrescu, Honnappa Nagarahalli,
	Sameh Gobriel, Vladimir Medvedkin, Yipeng Wang, mb, fengchengwen,
	Tyler Retzlaff

Zero length arrays are GNU extension. Replace with
standard flex array.

Add a temporary suppression for rte_pipeline_table_entry
libabigail bug:

Bugzilla ID: https://sourceware.org/bugzilla/show_bug.cgi?id=31377

Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
Reviewed-by: Morten Brørup <mb@smartsharesystems.com>
Acked-by: Stephen Hemminger <stephen@networkplumber.org>
---
 devtools/libabigail.abignore      | 2 ++
 lib/pipeline/rte_pipeline.h       | 2 +-
 lib/pipeline/rte_port_in_action.c | 2 +-
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index 25c73a5..5292b63 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -33,6 +33,8 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Temporary exceptions till next major ABI version ;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+[suppress_type]
+	name = rte_pipeline_table_entry
 
 [suppress_type]
 	name = rte_rcu_qsbr
diff --git a/lib/pipeline/rte_pipeline.h b/lib/pipeline/rte_pipeline.h
index ec51b9b..0c7994b 100644
--- a/lib/pipeline/rte_pipeline.h
+++ b/lib/pipeline/rte_pipeline.h
@@ -220,7 +220,7 @@ struct rte_pipeline_table_entry {
 		uint32_t table_id;
 	};
 	/** Start of table entry area for user defined actions and meta-data */
-	__extension__ uint8_t action_data[0];
+	uint8_t action_data[];
 };
 
 /**
diff --git a/lib/pipeline/rte_port_in_action.c b/lib/pipeline/rte_port_in_action.c
index 5818973..ebd9b9a 100644
--- a/lib/pipeline/rte_port_in_action.c
+++ b/lib/pipeline/rte_port_in_action.c
@@ -282,7 +282,7 @@ struct rte_port_in_action_profile *
 struct rte_port_in_action {
 	struct ap_config cfg;
 	struct ap_data data;
-	uint8_t memory[0] __rte_cache_aligned;
+	uint8_t memory[] __rte_cache_aligned;
 };
 
 static __rte_always_inline void *
-- 
1.8.3.1


^ permalink raw reply	[relevance 4%]

* Re: [PATCH v3 3/3] dts: add API doc generation
       [not found]         ` <CAJvnSUCNjo0p-yhROF1MNLKhjiAw2QTyTHO2hpOaVVUn0xnJ0A@mail.gmail.com>
@ 2024-02-29 18:12  2%       ` Nicholas Pratte
  0 siblings, 0 replies; 200+ results
From: Nicholas Pratte @ 2024-02-29 18:12 UTC (permalink / raw)
  To: dev, Jeremy Spewock

Tested-by: Nicholas Pratte <npratte@iol.unh.edu>

----

The tool used to generate developer docs is Sphinx, which is already in
use in DPDK. The same configuration is used to preserve style, but it's
been augmented with doc-generating configuration. There's a change that
modifies how the sidebar displays the content hierarchy that's been put
into an if block to not interfere with regular docs.

Sphinx generates the documentation from Python docstrings. The docstring
format is the Google format [0] which requires the sphinx.ext.napoleon
extension. The other extension, sphinx.ext.intersphinx, enables linking
to object in external documentations, such as the Python documentation.

There are two requirements for building DTS docs:
* The same Python version as DTS or higher, because Sphinx imports the
  code.
* Also the same Python packages as DTS, for the same reason.

[0] https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings

Signed-off-by: Juraj Linkeš <juraj.linkes@pantheon.tech>
---
 buildtools/call-sphinx-build.py | 33 +++++++++++++++++++---------
 doc/api/doxy-api-index.md       |  3 +++
 doc/api/doxy-api.conf.in        |  2 ++
 doc/api/meson.build             | 11 +++++++---
 doc/guides/conf.py              | 39 ++++++++++++++++++++++++++++-----
 doc/guides/meson.build          |  1 +
 doc/guides/tools/dts.rst        | 34 +++++++++++++++++++++++++++-
 dts/doc/meson.build             | 27 +++++++++++++++++++++++
 dts/meson.build                 | 16 ++++++++++++++
 meson.build                     |  1 +
 10 files changed, 148 insertions(+), 19 deletions(-)
 create mode 100644 dts/doc/meson.build
 create mode 100644 dts/meson.build

diff --git a/buildtools/call-sphinx-build.py b/buildtools/call-sphinx-build.py
index 39a60d09fa..aea771a64e 100755
--- a/buildtools/call-sphinx-build.py
+++ b/buildtools/call-sphinx-build.py
@@ -3,37 +3,50 @@
 # Copyright(c) 2019 Intel Corporation
 #

+import argparse
 import sys
 import os
 from os.path import join
 from subprocess import run, PIPE, STDOUT
 from packaging.version import Version

-# assign parameters to variables
-(sphinx, version, src, dst, *extra_args) = sys.argv[1:]
+parser = argparse.ArgumentParser()
+parser.add_argument('sphinx')
+parser.add_argument('version')
+parser.add_argument('src')
+parser.add_argument('dst')
+parser.add_argument('--dts-root', default=None)
+args, extra_args = parser.parse_known_args()

 # set the version in environment for sphinx to pick up
-os.environ['DPDK_VERSION'] = version
+os.environ['DPDK_VERSION'] = args.version
+if args.dts_root:
+    os.environ['DTS_ROOT'] = args.dts_root

 # for sphinx version >= 1.7 add parallelism using "-j auto"
-ver = run([sphinx, '--version'], stdout=PIPE,
+ver = run([args.sphinx, '--version'], stdout=PIPE,
           stderr=STDOUT).stdout.decode().split()[-1]
-sphinx_cmd = [sphinx] + extra_args
+sphinx_cmd = [args.sphinx] + extra_args
 if Version(ver) >= Version('1.7'):
     sphinx_cmd += ['-j', 'auto']

 # find all the files sphinx will process so we can write them as dependencies
 srcfiles = []
-for root, dirs, files in os.walk(src):
+for root, dirs, files in os.walk(args.src):
     srcfiles.extend([join(root, f) for f in files])

+if not os.path.exists(args.dst):
+    os.makedirs(args.dst)
+
 # run sphinx, putting the html output in a "html" directory
-with open(join(dst, 'sphinx_html.out'), 'w') as out:
-    process = run(sphinx_cmd + ['-b', 'html', src, join(dst, 'html')],
-                  stdout=out)
+with open(join(args.dst, 'sphinx_html.out'), 'w') as out:
+    process = run(
+        sphinx_cmd + ['-b', 'html', args.src, join(args.dst, 'html')],
+        stdout=out
+    )

 # create a gcc format .d file giving all the dependencies of this doc build
-with open(join(dst, '.html.d'), 'w') as d:
+with open(join(args.dst, '.html.d'), 'w') as d:
     d.write('html: ' + ' '.join(srcfiles) + '\n')

 sys.exit(process.returncode)
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index a6a768bd7c..b49b24acce 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -241,3 +241,6 @@ The public API headers are grouped by topics:
   [experimental APIs](@ref rte_compat.h),
   [ABI versioning](@ref rte_function_versioning.h),
   [version](@ref rte_version.h)
+
+- **tests**:
+  [**DTS**](@dts_api_main_page)
diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in
index e94c9e4e46..d53edeba57 100644
--- a/doc/api/doxy-api.conf.in
+++ b/doc/api/doxy-api.conf.in
@@ -121,6 +121,8 @@ SEARCHENGINE            = YES
 SORT_MEMBER_DOCS        = NO
 SOURCE_BROWSER          = YES

+ALIASES                 = "dts_api_main_page=@DTS_API_MAIN_PAGE@"
+
 EXAMPLE_PATH            = @TOPDIR@/examples
 EXAMPLE_PATTERNS        = *.c
 EXAMPLE_RECURSIVE       = YES
diff --git a/doc/api/meson.build b/doc/api/meson.build
index 5b50692df9..ffc75d7b5a 100644
--- a/doc/api/meson.build
+++ b/doc/api/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Luca Boccassi <bluca@debian.org>

+doc_api_build_dir = meson.current_build_dir()
 doxygen = find_program('doxygen', required: get_option('enable_docs'))

 if not doxygen.found()
@@ -32,14 +33,18 @@ example = custom_target('examples.dox',
 # set up common Doxygen configuration
 cdata = configuration_data()
 cdata.set('VERSION', meson.project_version())
-cdata.set('API_EXAMPLES', join_paths(dpdk_build_root, 'doc', 'api',
'examples.dox'))
-cdata.set('OUTPUT', join_paths(dpdk_build_root, 'doc', 'api'))
+cdata.set('API_EXAMPLES', join_paths(doc_api_build_dir, 'examples.dox'))
+cdata.set('OUTPUT', doc_api_build_dir)
 cdata.set('TOPDIR', dpdk_source_root)
-cdata.set('STRIP_FROM_PATH', ' '.join([dpdk_source_root,
join_paths(dpdk_build_root, 'doc', 'api')]))
+cdata.set('STRIP_FROM_PATH', ' '.join([dpdk_source_root, doc_api_build_dir]))
 cdata.set('WARN_AS_ERROR', 'NO')
 if get_option('werror')
     cdata.set('WARN_AS_ERROR', 'YES')
 endif
+# A local reference must be relative to the main index.html page
+# The path below can't be taken from the DTS meson file as that would
+# require recursive subdir traversal (doc, dts, then doc again)
+cdata.set('DTS_API_MAIN_PAGE', join_paths('..', 'dts', 'html', 'index.html'))

 # configure HTML Doxygen run
 html_cdata = configuration_data()
diff --git a/doc/guides/conf.py b/doc/guides/conf.py
index 0f7ff5282d..b442a1f76c 100644
--- a/doc/guides/conf.py
+++ b/doc/guides/conf.py
@@ -7,10 +7,9 @@
 from sphinx import __version__ as sphinx_version
 from os import listdir
 from os import environ
-from os.path import basename
-from os.path import dirname
+from os.path import basename, dirname
 from os.path import join as path_join
-from sys import argv, stderr
+from sys import argv, stderr, path

 import configparser

@@ -24,6 +23,37 @@
           file=stderr)
     pass

+# Napoleon enables the Google format of Python doscstrings, used in DTS
+# Intersphinx allows linking to external projects, such as Python
docs, also used in DTS
+extensions = ['sphinx.ext.napoleon', 'sphinx.ext.intersphinx']
+
+# DTS Python docstring options
+autodoc_default_options = {
+    'members': True,
+    'member-order': 'bysource',
+    'show-inheritance': True,
+}
+autodoc_class_signature = 'separated'
+autodoc_typehints = 'both'
+autodoc_typehints_format = 'short'
+autodoc_typehints_description_target = 'documented'
+napoleon_numpy_docstring = False
+napoleon_attr_annotations = True
+napoleon_preprocess_types = True
+add_module_names = False
+toc_object_entries = True
+toc_object_entries_show_parents = 'hide'
+intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}
+
+dts_root = environ.get('DTS_ROOT')
+if dts_root:
+    path.append(dts_root)
+    # DTS Sidebar config
+    html_theme_options = {
+        'collapse_navigation': False,
+        'navigation_depth': -1,
+    }
+
 stop_on_error = ('-W' in argv)

 project = 'Data Plane Development Kit'
@@ -35,8 +65,7 @@
 html_show_copyright = False
 highlight_language = 'none'

-release = environ.setdefault('DPDK_VERSION', "None")
-version = release
+version = environ.setdefault('DPDK_VERSION', "None")

 master_doc = 'index'

diff --git a/doc/guides/meson.build b/doc/guides/meson.build
index 51f81da2e3..8933d75f6b 100644
--- a/doc/guides/meson.build
+++ b/doc/guides/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Intel Corporation

+doc_guides_source_dir = meson.current_source_dir()
 sphinx = find_program('sphinx-build', required: get_option('enable_docs'))

 if not sphinx.found()
diff --git a/doc/guides/tools/dts.rst b/doc/guides/tools/dts.rst
index 846696e14e..21d3d89fc2 100644
--- a/doc/guides/tools/dts.rst
+++ b/doc/guides/tools/dts.rst
@@ -278,7 +278,12 @@ and try not to divert much from it.
 The :ref:`DTS developer tools <dts_dev_tools>` will issue warnings
 when some of the basics are not met.

-The code must be properly documented with docstrings.
+The API documentation, which is a helpful reference when developing,
may be accessed
+in the code directly or generated with the :ref:`API docs build steps
<building_api_docs>`.
+When adding new files or modifying the directory structure, the
corresponding changes must
+be made to DTS api doc sources in ``dts/doc``.
+
+Speaking of which, the code must be properly documented with docstrings.
 The style must conform to the `Google style
 <https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings>`_.
 See an example of the style `here
@@ -413,6 +418,33 @@ the DTS code check and format script.
 Refer to the script for usage: ``devtools/dts-check-format.sh -h``.


+.. _building_api_docs:
+
+Building DTS API docs
+---------------------
+
+To build DTS API docs, install the dependencies with Poetry, then
enter its shell:
+
+.. code-block:: console
+
+   poetry install --with docs
+   poetry shell
+
+The documentation is built using the standard DPDK build system.
After executing the meson command
+and entering Poetry's shell, build the documentation with:
+
+.. code-block:: console
+
+   ninja -C build dts-doc
+
+The output is generated in ``build/doc/api/dts/html``.
+
+.. Note::
+
+   Make sure to fix any Sphinx warnings when adding or updating
docstrings. Also make sure to run
+   the ``devtools/dts-check-format.sh`` script and address any issues it finds.
+
+
 Configuration Schema
 --------------------

diff --git a/dts/doc/meson.build b/dts/doc/meson.build
new file mode 100644
index 0000000000..01b7b51034
--- /dev/null
+++ b/dts/doc/meson.build
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2023 PANTHEON.tech s.r.o.
+
+sphinx = find_program('sphinx-build', required: false)
+sphinx_apidoc = find_program('sphinx-apidoc', required: false)
+
+if not sphinx.found() or not sphinx_apidoc.found()
+    subdir_done()
+endif
+
+dts_doc_api_build_dir = join_paths(doc_api_build_dir, 'dts')
+
+extra_sphinx_args = ['-E', '-c', doc_guides_source_dir, '--dts-root', dts_dir]
+if get_option('werror')
+    extra_sphinx_args += '-W'
+endif
+
+htmldir = join_paths(get_option('datadir'), 'doc', 'dpdk', 'dts')
+dts_api_html = custom_target('dts_api_html',
+        output: 'html',
+        command: [sphinx_wrapper, sphinx, meson.project_version(),
+            meson.current_source_dir(), dts_doc_api_build_dir,
extra_sphinx_args],
+        build_by_default: false,
+        install: get_option('enable_docs'),
+        install_dir: htmldir)
+doc_targets += dts_api_html
+doc_target_names += 'DTS_API_HTML'
diff --git a/dts/meson.build b/dts/meson.build
new file mode 100644
index 0000000000..e8ce0f06ac
--- /dev/null
+++ b/dts/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2023 PANTHEON.tech s.r.o.
+
+doc_targets = []
+doc_target_names = []
+dts_dir = meson.current_source_dir()
+
+subdir('doc')
+
+if doc_targets.length() == 0
+    message = 'No docs targets found'
+else
+    message = 'Built docs:'
+endif
+run_target('dts-doc', command: [echo, message, doc_target_names],
+    depends: doc_targets)
diff --git a/meson.build b/meson.build
index 5e161f43e5..001fdcbbbf 100644
--- a/meson.build
+++ b/meson.build
@@ -87,6 +87,7 @@ subdir('app')

 # build docs
 subdir('doc')
+subdir('dts')

 # build any examples explicitly requested - useful for developers - and
 # install any example code into the appropriate install path
--
2.34.1

^ permalink raw reply	[relevance 2%]

* [PATCH] net/tap: allow more that 4 queues
@ 2024-02-29 17:56  3% Stephen Hemminger
  2024-03-06 16:14  0% ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2024-02-29 17:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The tap device needs to exchange file descriptors for tx and rx.
But the EAL MP layer has limit of 8 file descriptors per message.
The ideal resolution would be to increase the number of file
descriptors allowed for rte_mp_sendmsg(), but this would break
the ABI. Workaround the constraint by breaking into multiple messages.

Do not hide errors about MP message failures.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/tap/rte_eth_tap.c | 40 +++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 69d9da695bed..df18c328f498 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -863,21 +863,44 @@ tap_mp_req_on_rxtx(struct rte_eth_dev *dev)
 		msg.fds[fd_iterator++] = process_private->txq_fds[i];
 		msg.num_fds++;
 		request_param->txq_count++;
+
+		/* Need to break request into chunks */
+		if (fd_iterator >= RTE_MP_MAX_FD_NUM) {
+			err = rte_mp_sendmsg(&msg);
+			if (err < 0)
+				goto fail;
+
+			fd_iterator = 0;
+			msg.num_fds = 0;
+			request_param->txq_count = 0;
+		}
 	}
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
 		msg.fds[fd_iterator++] = process_private->rxq_fds[i];
 		msg.num_fds++;
 		request_param->rxq_count++;
+
+		if (fd_iterator >= RTE_MP_MAX_FD_NUM) {
+			err = rte_mp_sendmsg(&msg);
+			if (err < 0)
+				goto fail;
+
+			fd_iterator = 0;
+			msg.num_fds = 0;
+			request_param->rxq_count = 0;
+		}
 	}
 
-	err = rte_mp_sendmsg(&msg);
-	if (err < 0) {
-		TAP_LOG(ERR, "Failed to send start req to secondary %d",
-			rte_errno);
-		return -1;
+	if (msg.num_fds > 0) {
+		err = rte_mp_sendmsg(&msg);
+		if (err < 0)
+			goto fail;
 	}
 
 	return 0;
+fail:
+	TAP_LOG(ERR, "Failed to send start req to secondary %d", rte_errno);
+	return err;
 }
 
 static int
@@ -885,8 +908,11 @@ tap_dev_start(struct rte_eth_dev *dev)
 {
 	int err, i;
 
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		tap_mp_req_on_rxtx(dev);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		err = tap_mp_req_on_rxtx(dev);
+		if (err)
+			return err;
+	}
 
 	err = tap_intr_handle_set(dev, 1);
 	if (err)
-- 
2.43.0


^ permalink raw reply	[relevance 3%]

* RE: [PATCH 0/7] add Nitrox compress device support
  2024-02-15 12:48  3% [PATCH 0/7] add Nitrox compress device support Nagadheeraj Rottela
@ 2024-02-29 17:22  0% ` Akhil Goyal
  0 siblings, 0 replies; 200+ results
From: Akhil Goyal @ 2024-02-29 17:22 UTC (permalink / raw)
  To: Nagadheeraj Rottela, fanzhang.oss, Ashish Gupta; +Cc: dev, Nagadheeraj Rottela

Please add release notes for the addition of new PMD.

> -----Original Message-----
> From: Nagadheeraj Rottela <rnagadheeraj@marvell.com>
> Sent: Thursday, February 15, 2024 6:19 PM
> To: Akhil Goyal <gakhil@marvell.com>; fanzhang.oss@gmail.com; Ashish Gupta
> <ashishg@marvell.com>
> Cc: dev@dpdk.org; Nagadheeraj Rottela <rnagadheeraj@marvell.com>
> Subject: [PATCH 0/7] add Nitrox compress device support
> 
> Add the Nitrox PMD to support Nitrox compress device.
> ---
> v3:
> * Fixed ABI compatibility issue.
> 
> v2:
> * Reformatted patches to minimize number of changes.
> * Removed empty file with only copyright.
> * Updated all feature flags in nitrox.ini file.
> * Added separate gotos in nitrox_pci_probe() function.
> 
> Nagadheeraj Rottela (7):
>   crypto/nitrox: move nitrox common code to common folder
>   compress/nitrox: add nitrox compressdev driver
>   common/nitrox: add compress hardware queue management
>   crypto/nitrox: set queue type during queue pair setup
>   compress/nitrox: add software queue management
>   compress/nitrox: add stateless request support
>   compress/nitrox: add stateful request support
> 
>  MAINTAINERS                                   |    8 +
>  doc/guides/compressdevs/features/nitrox.ini   |   17 +
>  doc/guides/compressdevs/index.rst             |    1 +
>  doc/guides/compressdevs/nitrox.rst            |   50 +
>  drivers/common/nitrox/meson.build             |   19 +
>  .../{crypto => common}/nitrox/nitrox_csr.h    |   12 +
>  .../{crypto => common}/nitrox/nitrox_device.c |   51 +-
>  .../{crypto => common}/nitrox/nitrox_device.h |    4 +-
>  .../{crypto => common}/nitrox/nitrox_hal.c    |  116 ++
>  .../{crypto => common}/nitrox/nitrox_hal.h    |  115 ++
>  .../{crypto => common}/nitrox/nitrox_logs.c   |    0
>  .../{crypto => common}/nitrox/nitrox_logs.h   |    0
>  drivers/{crypto => common}/nitrox/nitrox_qp.c |   53 +-
>  drivers/{crypto => common}/nitrox/nitrox_qp.h |   37 +-
>  drivers/common/nitrox/version.map             |    9 +
>  drivers/compress/nitrox/meson.build           |   16 +
>  drivers/compress/nitrox/nitrox_comp.c         |  604 +++++++++
>  drivers/compress/nitrox/nitrox_comp.h         |   35 +
>  drivers/compress/nitrox/nitrox_comp_reqmgr.c  | 1199 +++++++++++++++++
>  drivers/compress/nitrox/nitrox_comp_reqmgr.h  |   58 +
>  drivers/crypto/nitrox/meson.build             |   11 +-
>  drivers/crypto/nitrox/nitrox_sym.c            |    1 +
>  drivers/meson.build                           |    1 +
>  23 files changed, 2396 insertions(+), 21 deletions(-)
>  create mode 100644 doc/guides/compressdevs/features/nitrox.ini
>  create mode 100644 doc/guides/compressdevs/nitrox.rst
>  create mode 100644 drivers/common/nitrox/meson.build
>  rename drivers/{crypto => common}/nitrox/nitrox_csr.h (67%)
>  rename drivers/{crypto => common}/nitrox/nitrox_device.c (77%)
>  rename drivers/{crypto => common}/nitrox/nitrox_device.h (81%)
>  rename drivers/{crypto => common}/nitrox/nitrox_hal.c (65%)
>  rename drivers/{crypto => common}/nitrox/nitrox_hal.h (59%)
>  rename drivers/{crypto => common}/nitrox/nitrox_logs.c (100%)
>  rename drivers/{crypto => common}/nitrox/nitrox_logs.h (100%)
>  rename drivers/{crypto => common}/nitrox/nitrox_qp.c (69%)
>  rename drivers/{crypto => common}/nitrox/nitrox_qp.h (75%)
>  create mode 100644 drivers/common/nitrox/version.map
>  create mode 100644 drivers/compress/nitrox/meson.build
>  create mode 100644 drivers/compress/nitrox/nitrox_comp.c
>  create mode 100644 drivers/compress/nitrox/nitrox_comp.h
>  create mode 100644 drivers/compress/nitrox/nitrox_comp_reqmgr.c
>  create mode 100644 drivers/compress/nitrox/nitrox_comp_reqmgr.h
> 
> --
> 2.42.0


^ permalink raw reply	[relevance 0%]

* RE: [EXT] Re: [PATCH v2] app/dma-perf: support bi-directional transfer
  @ 2024-02-29 14:03  3%       ` Amit Prakash Shukla
  2024-03-01  1:46  0%         ` fengchengwen
  0 siblings, 1 reply; 200+ results
From: Amit Prakash Shukla @ 2024-02-29 14:03 UTC (permalink / raw)
  To: fengchengwen, Cheng Jiang, Gowrishankar Muthukrishnan
  Cc: dev, Jerin Jacob, Anoob Joseph, Kevin Laatz, Bruce Richardson,
	Pavan Nikhilesh Bhagavatula

Hi Chengwen,

I liked your suggestion and tried making changes, but encountered parsing issue for CFG files with line greater than CFG_VALUE_LEN=256(current value set).

There is a discussion on the similar lines in another patch set: https://patchwork.dpdk.org/project/dpdk/patch/20231206112952.1588-1-vipin.varghese@amd.com/.

I believe this patch can be taken as-is and we can come up with the solution when we can increase the CFG_VALUE_LEN as changing CFG_VALUE_LEN in this release is causing ABI breakage.

Thanks,
Amit Shukla

> -----Original Message-----
> From: Amit Prakash Shukla
> Sent: Wednesday, February 28, 2024 3:08 PM
> To: fengchengwen <fengchengwen@huawei.com>; Cheng Jiang
> <honest.jiang@foxmail.com>; Gowrishankar Muthukrishnan
> <gmuthukrishn@marvell.com>
> Cc: dev@dpdk.org; Jerin Jacob <jerinj@marvell.com>; Anoob Joseph
> <anoobj@marvell.com>; Kevin Laatz <kevin.laatz@intel.com>; Bruce
> Richardson <bruce.richardson@intel.com>; Pavan Nikhilesh Bhagavatula
> <pbhagavatula@marvell.com>
> Subject: RE: [EXT] Re: [PATCH v2] app/dma-perf: support bi-directional
> transfer
> 
> Hi Chengwen,
> 
> Please see my reply in-line.
> 
> Thanks
> Amit Shukla
> 
> > -----Original Message-----
> > From: fengchengwen <fengchengwen@huawei.com>
> > Sent: Wednesday, February 28, 2024 12:34 PM
> > To: Amit Prakash Shukla <amitprakashs@marvell.com>; Cheng Jiang
> > <honest.jiang@foxmail.com>; Gowrishankar Muthukrishnan
> > <gmuthukrishn@marvell.com>
> > Cc: dev@dpdk.org; Jerin Jacob <jerinj@marvell.com>; Anoob Joseph
> > <anoobj@marvell.com>; Kevin Laatz <kevin.laatz@intel.com>; Bruce
> > Richardson <bruce.richardson@intel.com>; Pavan Nikhilesh Bhagavatula
> > <pbhagavatula@marvell.com>
> > Subject: [EXT] Re: [PATCH v2] app/dma-perf: support bi-directional
> > transfer
> >
> > External Email
> >
> > ----------------------------------------------------------------------
> > Hi Amit and Gowrishankar,
> >
> > It's nature to support multiple dmadev test in one testcase, and the
> > original framework supports it.
> > But it seem we both complicated it when adding support for non-
> mem2mem
> > dma test.
> >
> > The new added "direction" and "vchan_dev" could treat as the dmadev's
> > private configure, some thing like:
> >
> >
> lcore_dma=lcore10@0000:00:04.2,vchan=0,dir=mem2dev,devtype=pcie,radd
> > r=xxx,coreid=1,pfid=2,vfid=3
> >
> > then this bi-directional could impl only with config:
> >
> >
> lcore_dma=lcore10@0000:00:04.2,dir=mem2dev,devtype=pcie,raddr=xxx,cor
> > eid=1,pfid=2,vfid=3,
> >
> lcore11@0000:00:04.3,dir=dev2mem,devtype=pcie,raddr=xxx,coreid=1,pfid=
> > 2,vfid=3
> > so that the lcore10 will do mem2dev with device 0000:00:04.2, while
> > lcore11 will do dev2mem with device 0000:00:04.3.
> 
> Thanks for the suggestion. I will make the suggested changes and send the
> next version.

^ permalink raw reply	[relevance 3%]

* Re: [PATCH v4 1/7] ethdev: support report register names and filter
  2024-02-26  3:07  8%   ` [PATCH v4 1/7] ethdev: support report register names and filter Jie Hai
  2024-02-26  8:01  0%     ` fengchengwen
@ 2024-02-29  9:52  3%     ` Thomas Monjalon
  2024-03-05  7:45  5%       ` Jie Hai
  1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2024-02-29  9:52 UTC (permalink / raw)
  To: ferruh.yigit, Jie Hai
  Cc: dev, lihuisong, fengchengwen, liuyonglong, huangdengdui

26/02/2024 04:07, Jie Hai:
> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
> structure. Names of registers in data fields can be reported and
> the registers can be filtered by their names.
> 
> The new API rte_eth_dev_get_reg_info_ext() is added to support
> reporting names and filtering by names. And the original API
> rte_eth_dev_get_reg_info() does not use the name and filter fields.
> A local variable is used in rte_eth_dev_get_reg_info for
> compatibility. If the drivers does not report the names, set them
> to "offset_XXX".

Isn't it possible to implement filtering in the original function?
What would it break?

> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>  	uint32_t length; /**< Number of registers to fetch */
>  	uint32_t width; /**< Size of device register */
>  	uint32_t version; /**< Device version */
> +	/**
> +	 * Filter for target subset of registers.
> +	 * This field could affects register selection for data/length/names.
> +	 */
> +	const char *filter;
> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>  };

I suppose this is an ABI break?
Confirmed: http://mails.dpdk.org/archives/test-report/2024-February/587314.html



^ permalink raw reply	[relevance 3%]

* RE: release candidate 24.03-rc1
  @ 2024-02-29  9:18  4% ` Xu, HailinX
  0 siblings, 0 replies; 200+ results
From: Xu, HailinX @ 2024-02-29  9:18 UTC (permalink / raw)
  To: Thomas Monjalon, dev
  Cc: Kovacevic, Marko, Mcnamara, John, Richardson, Bruce,
	Ferruh Yigit, Puttaswamy, Rajesh T, Cui, KaixinX

> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Thursday, February 22, 2024 3:36 PM
> To: announce@dpdk.org
> Subject: release candidate 24.03-rc1
> 
> A new DPDK release candidate is ready for testing:
> 	https://git.dpdk.org/dpdk/tag/?id=v24.03-rc1
> 
> There are 521 new patches in this snapshot.
> 
> Release notes:
> 	https://doc.dpdk.org/guides/rel_notes/release_24_03.html
> 
> Highlights of 24.03-rc1:
> 	- argument parsing library
> 	- dynamic logging standardized
> 	- HiSilicon UACCE bus
> 	- Tx queue query
> 	- flow matching with random and field comparison
> 	- flow action NAT64
> 	- more cleanups to prepare MSVC build
> 
> Please test and report issues on bugs.dpdk.org.
> 
> DPDK 24.03-rc2 will be out as soon as possible.
> Priority is on features announced in the roadmap:
> 	https://core.dpdk.org/roadmap/
> 
> Thank you everyone
> 
Update the test status for Intel part. dpdk24.03-rc1 all test is done. found three new issues.

New issues:
1. Bug 1386 - [dpdk-24.03] [ABI][meson test] driver-tests/link_bonding_autotest test failed: Segmentation fault when do ABI testing  -> not fix yet
2. Bug 1387 - [dpdk24.03] cbdma: Failed to launch dpdk-dma app  -> has fix patch
3. dcf_lifecycle/test_one_testpmd_dcf_reset_port: Failed to manually reset vf when use dcf  -> Intel dev is under investigating

# Basic Intel(R) NIC testing
* Build or compile:  
 *Build: cover the build test combination with latest GCC/Clang version and the popular OS revision such as Ubuntu23.10, Ubuntu22.04.3, Fedora39, RHEL8.9/9.2, Centos7.9, FreeBSD14.0, SUSE15, OpenAnolis8.8, CBL-Mariner2.0 etc.
  - All test passed.
 *Compile: cover the CFLAGES(O0/O1/O2/O3) with popular OS such as Ubuntu22.04.3 and RHEL9.2.
  - All test passed with latest dpdk.
* PF/VF(i40e, ixgbe): test scenarios including PF/VF-RTE_FLOW/TSO/Jumboframe/checksum offload/VLAN/VXLAN, etc. 
	- All test case is done. No new issue is found.
* PF/VF(ice): test scenarios including Switch features/Package Management/Flow Director/Advanced Tx/Advanced RSS/ACL/DCF/Flexible Descriptor, etc.
	- Execution rate is done. found the third issue.
* Intel NIC single core/NIC performance: test scenarios including PF/VF single core performance test, RFC2544 Zero packet loss performance test, etc.
	- Execution rate is done. No new issue is found.
* Power and IPsec: 
 * Power: test scenarios including bi-direction/Telemetry/Empty Poll Lib/Priority Base Frequency, etc. 
	- Execution rate is done. No new issue is found.
 * IPsec: test scenarios including ipsec/ipsec-gw/ipsec library basic test - QAT&SW/FIB library, etc.
	- Execution rate is done. No new issue is found. 
# Basic cryptodev and virtio testing
* Virtio: both function and performance test are covered. Such as PVP/Virtio_loopback/virtio-user loopback/virtio-net VM2VM perf testing/VMAWARE ESXI 8.0U1, etc.
	- Execution rate is done. found the second issue.
* Cryptodev: 
 *Function test: test scenarios including Cryptodev API testing/CompressDev ISA-L/QAT/ZLIB PMD Testing/FIPS, etc.
	- Execution rate is done. No new issue is found. 
 *Performance test: test scenarios including Throughput Performance /Cryptodev Latency, etc.
	- Execution rate is done. No performance drop.


Regards,
Xu, Hailin

^ permalink raw reply	[relevance 4%]

* Re: [PATCH v6 20/23] mbuf: remove and stop using rte marker fields
  2024-02-28 15:01  4%       ` Morten Brørup
@ 2024-02-28 15:33  3%         ` David Marchand
  0 siblings, 0 replies; 200+ results
From: David Marchand @ 2024-02-28 15:33 UTC (permalink / raw)
  To: Morten Brørup
  Cc: Tyler Retzlaff, dev, Ajit Khaparde, Andrew Boyer,
	Andrew Rybchenko, Bruce Richardson, Chenbo Xia, Chengwen Feng,
	Dariusz Sosnowski, David Christensen, Hyong Youb Kim,
	Jerin Jacob, Jie Hai, Jingjing Wu, John Daley, Kevin Laatz,
	Kiran Kumar K, Konstantin Ananyev, Maciej Czekaj, Matan Azrad,
	Maxime Coquelin, Nithin Dabilpuram, Ori Kam, Ruifeng Wang,
	Satha Rao, Somnath Kotur, Suanming Mou, Sunil Kumar Kori,
	Viacheslav Ovsiienko, Yisen Zhuang, Yuying Zhang,
	Thomas Monjalon

On Wed, Feb 28, 2024 at 4:01 PM Morten Brørup <mb@smartsharesystems.com> wrote:
>
> > From: David Marchand [mailto:david.marchand@redhat.com]
> > Sent: Wednesday, 28 February 2024 15.19
> >
> > On Tue, Feb 27, 2024 at 6:44 AM Tyler Retzlaff
> > <roretzla@linux.microsoft.com> wrote:
> > >
> > > RTE_MARKER typedefs are a GCC extension unsupported by MSVC. Remove
> > > RTE_MARKER fields from rte_mbuf struct.
> > >
> > > Maintain alignment of fields after removed cacheline1 marker by placing
> > > C11 alignas(RTE_CACHE_LINE_MIN_SIZE).
> > >
> > > Update implementation of rte_mbuf_prefetch_part1() and
> > > rte_mbuf_prefetch_part2() inline functions calculate pointer for
> > > prefetch of cachline0 and cachline1 without using removed markers.
> > >
> > > Update static_assert of rte_mbuf struct fields to reference data_off and
> > > packet_type fields that occupy the original offsets of the marker
> > > fields.
> > >
> > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> > > ---
> > >  doc/guides/rel_notes/release_24_03.rst |  9 ++++++++
> > >  lib/mbuf/rte_mbuf.h                    |  4 ++--
> > >  lib/mbuf/rte_mbuf_core.h               | 39 +++++++++++++------------------
> > ---
> > >  3 files changed, 26 insertions(+), 26 deletions(-)
> > >
> > > diff --git a/doc/guides/rel_notes/release_24_03.rst
> > b/doc/guides/rel_notes/release_24_03.rst
> > > index 879bb49..67750f2 100644
> > > --- a/doc/guides/rel_notes/release_24_03.rst
> > > +++ b/doc/guides/rel_notes/release_24_03.rst
> > > @@ -156,6 +156,15 @@ Removed Items
> > >    The application reserved statically defined logtypes
> > ``RTE_LOGTYPE_USER1..RTE_LOGTYPE_USER8``
> > >    are still defined.
> > >
> > > +* mbuf: ``RTE_MARKER`` fields ``cacheline0`` ``cacheline1``
> > > +  ``rx_descriptor_fields1`` and ``RTE_MARKER64`` field ``rearm_data``
> > > +  have been removed from ``struct rte_mbuf``.
> > > +  Prefetch of ``cacheline0`` and ``cacheline1`` may be achieved through
> > > +  ``rte_mbuf_prefetch_part1()`` and ``rte_mbuf_prefetch_part2()`` inline
> > > +  functions respectively.
> > > +  Access to ``rearm_data`` and ``rx_descriptor_fields1`` should be
> > > +  through new inline functions ``rte_mbuf_rearm_data()`` and
> > > +  ``rte_mbuf_rx_descriptor_fields1()`` respectively.
> > >
> > >  API Changes
> > >  -----------
> > > diff --git a/lib/mbuf/rte_mbuf.h b/lib/mbuf/rte_mbuf.h
> > > index aa7495b..61cda20 100644
> > > --- a/lib/mbuf/rte_mbuf.h
> > > +++ b/lib/mbuf/rte_mbuf.h
> > > @@ -108,7 +108,7 @@
> > >  static inline void
> > >  rte_mbuf_prefetch_part1(struct rte_mbuf *m)
> > >  {
> > > -       rte_prefetch0(&m->cacheline0);
> > > +       rte_prefetch0(m);
> > >  }
> > >
> > >  /**
> > > @@ -126,7 +126,7 @@
> > >  rte_mbuf_prefetch_part2(struct rte_mbuf *m)
> > >  {
> > >  #if RTE_CACHE_LINE_SIZE == 64
> > > -       rte_prefetch0(&m->cacheline1);
> > > +       rte_prefetch0(RTE_PTR_ADD(m, RTE_CACHE_LINE_MIN_SIZE));
> > >  #else
> > >         RTE_SET_USED(m);
> > >  #endif
> > > diff --git a/lib/mbuf/rte_mbuf_core.h b/lib/mbuf/rte_mbuf_core.h
> > > index 36551c2..4e06f15 100644
> > > --- a/lib/mbuf/rte_mbuf_core.h
> > > +++ b/lib/mbuf/rte_mbuf_core.h
> > > @@ -18,6 +18,7 @@
> > >
> > >  #include <assert.h>
> > >  #include <stddef.h>
> > > +#include <stdalign.h>
> > >  #include <stdint.h>
> > >
> > >  #include <rte_common.h>
> > > @@ -467,8 +468,6 @@ enum {
> > >   * The generic rte_mbuf, containing a packet mbuf.
> > >   */
> > >  struct rte_mbuf {
> > > -       RTE_MARKER cacheline0;
> > > -
> > >         void *buf_addr;           /**< Virtual address of segment buffer. */
> > >  #if RTE_IOVA_IN_MBUF
> > >         /**
> > > @@ -495,7 +494,6 @@ struct rte_mbuf {
> > >          * To obtain a pointer to rearm_data use the rte_mbuf_rearm_data()
> > >          * accessor instead of directly referencing through the data_off
> > field.
> > >          */
> > > -       RTE_MARKER64 rearm_data;
> > >         uint16_t data_off;
> >
> > One subtile change of removing the marker is that fields may not be
> > aligned as before.
> >
> > #if RTE_IOVA_IN_MBUF
> >         /**
> >          * Physical address of segment buffer.
> >          * This field is undefined if the build is configured to use only
> >          * virtual address as IOVA (i.e. RTE_IOVA_IN_MBUF is 0).
> >          * Force alignment to 8-bytes, so as to ensure we have the exact
> >          * same mbuf cacheline0 layout for 32-bit and 64-bit. This makes
> >          * working on vector drivers easier.
> >          */
> >         rte_iova_t buf_iova __rte_aligned(sizeof(rte_iova_t));
> > #else
> >         /**
> >          * Next segment of scattered packet.
> >          * This field is valid when physical address field is undefined.
> >          * Otherwise next pointer in the second cache line will be used.
> >          */
> >         struct rte_mbuf *next;
> > #endif
> >
> > When building ! RTE_IOVA_IN_MBUF on a 32 bits arch, the next pointer
> > is not force aligned to 64bits.
> > Which has a cascade effect on data_off alignement.
> >
> > In file included from ../lib/mbuf/rte_mbuf_core.h:19,
> >                  from ../lib/mbuf/rte_mbuf.h:42,
> >                  from ../lib/mbuf/rte_mbuf_dyn.c:18:
> > ../lib/mbuf/rte_mbuf_core.h:676:1: error: static assertion failed: "data_off"
> >   676 | static_assert(!(offsetof(struct rte_mbuf, data_off) !=
> >       | ^~~~~~~~~~~~~
> >
> >
> > I hope reviewers pay attention to the alignment changes when removing
> > those markers.
> > This is not trivial to catch in the CI.
>
> Good catch, David.
>
> I wonder about the reason for 64 bit aligning the rearm_data group of fields? Perhaps it's there for (64 bit arch) vector instruction purposes?
>
> Regardless, it's an ABI break, so padding or an alignment attribute must be added to avoid ABI breakage. If there is no valid reason for the 64 bit alignment, it could be noted that the padding (or alignment attribute) is there for 32 bit arch ABI compatibility reasons only.
>
> Please note that only RTE_MARKER64 is affected by this. The other marker types have arch bit-width (or smaller) alignment, i.e. RTE_MARKER is 8 byte aligned on 64 bit arch and 4 byte aligned on 32 bit arch.

Well, strictly speaking other RTE_MARKER users *may* be affected,
depending on the alignement for the following fields.
For example, I think removing the rxq_fastpath_data_end RTE_MARKER in
struct nicvf_rxq
(https://git.dpdk.org/dpdk/tree/drivers/net/thunderx/nicvf_struct.h#n72)
impacts rx_drop_en alignment and subsequent fields.

Now, in practice and focusing only on what this series touches, either
the markers were coupled with an explicit alignment constraint
(__rte_cache*_aligned) which is preserved by the series, or the
alignement constraint is stronger than that of the marker.
So there is probably only this ABI breakage I reported.


-- 
David Marchand


^ permalink raw reply	[relevance 3%]

* RE: [PATCH v6 20/23] mbuf: remove and stop using rte marker fields
  @ 2024-02-28 15:01  4%       ` Morten Brørup
  2024-02-28 15:33  3%         ` David Marchand
  0 siblings, 1 reply; 200+ results
From: Morten Brørup @ 2024-02-28 15:01 UTC (permalink / raw)
  To: David Marchand, Tyler Retzlaff
  Cc: dev, Ajit Khaparde, Andrew Boyer, Andrew Rybchenko,
	Bruce Richardson, Chenbo Xia, Chengwen Feng, Dariusz Sosnowski,
	David Christensen, Hyong Youb Kim, Jerin Jacob, Jie Hai,
	Jingjing Wu, John Daley, Kevin Laatz, Kiran Kumar K,
	Konstantin Ananyev, Maciej Czekaj, Matan Azrad, Maxime Coquelin,
	Nithin Dabilpuram, Ori Kam, Ruifeng Wang, Satha Rao,
	Somnath Kotur, Suanming Mou, Sunil Kumar Kori,
	Viacheslav Ovsiienko, Yisen Zhuang, Yuying Zhang,
	Thomas Monjalon

> From: David Marchand [mailto:david.marchand@redhat.com]
> Sent: Wednesday, 28 February 2024 15.19
> 
> On Tue, Feb 27, 2024 at 6:44 AM Tyler Retzlaff
> <roretzla@linux.microsoft.com> wrote:
> >
> > RTE_MARKER typedefs are a GCC extension unsupported by MSVC. Remove
> > RTE_MARKER fields from rte_mbuf struct.
> >
> > Maintain alignment of fields after removed cacheline1 marker by placing
> > C11 alignas(RTE_CACHE_LINE_MIN_SIZE).
> >
> > Update implementation of rte_mbuf_prefetch_part1() and
> > rte_mbuf_prefetch_part2() inline functions calculate pointer for
> > prefetch of cachline0 and cachline1 without using removed markers.
> >
> > Update static_assert of rte_mbuf struct fields to reference data_off and
> > packet_type fields that occupy the original offsets of the marker
> > fields.
> >
> > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> > ---
> >  doc/guides/rel_notes/release_24_03.rst |  9 ++++++++
> >  lib/mbuf/rte_mbuf.h                    |  4 ++--
> >  lib/mbuf/rte_mbuf_core.h               | 39 +++++++++++++------------------
> ---
> >  3 files changed, 26 insertions(+), 26 deletions(-)
> >
> > diff --git a/doc/guides/rel_notes/release_24_03.rst
> b/doc/guides/rel_notes/release_24_03.rst
> > index 879bb49..67750f2 100644
> > --- a/doc/guides/rel_notes/release_24_03.rst
> > +++ b/doc/guides/rel_notes/release_24_03.rst
> > @@ -156,6 +156,15 @@ Removed Items
> >    The application reserved statically defined logtypes
> ``RTE_LOGTYPE_USER1..RTE_LOGTYPE_USER8``
> >    are still defined.
> >
> > +* mbuf: ``RTE_MARKER`` fields ``cacheline0`` ``cacheline1``
> > +  ``rx_descriptor_fields1`` and ``RTE_MARKER64`` field ``rearm_data``
> > +  have been removed from ``struct rte_mbuf``.
> > +  Prefetch of ``cacheline0`` and ``cacheline1`` may be achieved through
> > +  ``rte_mbuf_prefetch_part1()`` and ``rte_mbuf_prefetch_part2()`` inline
> > +  functions respectively.
> > +  Access to ``rearm_data`` and ``rx_descriptor_fields1`` should be
> > +  through new inline functions ``rte_mbuf_rearm_data()`` and
> > +  ``rte_mbuf_rx_descriptor_fields1()`` respectively.
> >
> >  API Changes
> >  -----------
> > diff --git a/lib/mbuf/rte_mbuf.h b/lib/mbuf/rte_mbuf.h
> > index aa7495b..61cda20 100644
> > --- a/lib/mbuf/rte_mbuf.h
> > +++ b/lib/mbuf/rte_mbuf.h
> > @@ -108,7 +108,7 @@
> >  static inline void
> >  rte_mbuf_prefetch_part1(struct rte_mbuf *m)
> >  {
> > -       rte_prefetch0(&m->cacheline0);
> > +       rte_prefetch0(m);
> >  }
> >
> >  /**
> > @@ -126,7 +126,7 @@
> >  rte_mbuf_prefetch_part2(struct rte_mbuf *m)
> >  {
> >  #if RTE_CACHE_LINE_SIZE == 64
> > -       rte_prefetch0(&m->cacheline1);
> > +       rte_prefetch0(RTE_PTR_ADD(m, RTE_CACHE_LINE_MIN_SIZE));
> >  #else
> >         RTE_SET_USED(m);
> >  #endif
> > diff --git a/lib/mbuf/rte_mbuf_core.h b/lib/mbuf/rte_mbuf_core.h
> > index 36551c2..4e06f15 100644
> > --- a/lib/mbuf/rte_mbuf_core.h
> > +++ b/lib/mbuf/rte_mbuf_core.h
> > @@ -18,6 +18,7 @@
> >
> >  #include <assert.h>
> >  #include <stddef.h>
> > +#include <stdalign.h>
> >  #include <stdint.h>
> >
> >  #include <rte_common.h>
> > @@ -467,8 +468,6 @@ enum {
> >   * The generic rte_mbuf, containing a packet mbuf.
> >   */
> >  struct rte_mbuf {
> > -       RTE_MARKER cacheline0;
> > -
> >         void *buf_addr;           /**< Virtual address of segment buffer. */
> >  #if RTE_IOVA_IN_MBUF
> >         /**
> > @@ -495,7 +494,6 @@ struct rte_mbuf {
> >          * To obtain a pointer to rearm_data use the rte_mbuf_rearm_data()
> >          * accessor instead of directly referencing through the data_off
> field.
> >          */
> > -       RTE_MARKER64 rearm_data;
> >         uint16_t data_off;
> 
> One subtile change of removing the marker is that fields may not be
> aligned as before.
> 
> #if RTE_IOVA_IN_MBUF
>         /**
>          * Physical address of segment buffer.
>          * This field is undefined if the build is configured to use only
>          * virtual address as IOVA (i.e. RTE_IOVA_IN_MBUF is 0).
>          * Force alignment to 8-bytes, so as to ensure we have the exact
>          * same mbuf cacheline0 layout for 32-bit and 64-bit. This makes
>          * working on vector drivers easier.
>          */
>         rte_iova_t buf_iova __rte_aligned(sizeof(rte_iova_t));
> #else
>         /**
>          * Next segment of scattered packet.
>          * This field is valid when physical address field is undefined.
>          * Otherwise next pointer in the second cache line will be used.
>          */
>         struct rte_mbuf *next;
> #endif
> 
> When building ! RTE_IOVA_IN_MBUF on a 32 bits arch, the next pointer
> is not force aligned to 64bits.
> Which has a cascade effect on data_off alignement.
> 
> In file included from ../lib/mbuf/rte_mbuf_core.h:19,
>                  from ../lib/mbuf/rte_mbuf.h:42,
>                  from ../lib/mbuf/rte_mbuf_dyn.c:18:
> ../lib/mbuf/rte_mbuf_core.h:676:1: error: static assertion failed: "data_off"
>   676 | static_assert(!(offsetof(struct rte_mbuf, data_off) !=
>       | ^~~~~~~~~~~~~
> 
> 
> I hope reviewers pay attention to the alignment changes when removing
> those markers.
> This is not trivial to catch in the CI.

Good catch, David.

I wonder about the reason for 64 bit aligning the rearm_data group of fields? Perhaps it's there for (64 bit arch) vector instruction purposes?

Regardless, it's an ABI break, so padding or an alignment attribute must be added to avoid ABI breakage. If there is no valid reason for the 64 bit alignment, it could be noted that the padding (or alignment attribute) is there for 32 bit arch ABI compatibility reasons only.

Please note that only RTE_MARKER64 is affected by this. The other marker types have arch bit-width (or smaller) alignment, i.e. RTE_MARKER is 8 byte aligned on 64 bit arch and 4 byte aligned on 32 bit arch.

And RTE_MARKER64 is only used in the rte_mbuf structure.


^ permalink raw reply	[relevance 4%]

* Re: [PATCH v6 20/23] mbuf: remove and stop using rte marker fields
  2024-02-27 15:18  4%     ` David Marchand
  2024-02-27 16:04  3%       ` Morten Brørup
  2024-02-27 17:23  4%       ` Tyler Retzlaff
@ 2024-02-28 14:03  3%       ` Dodji Seketeli
  2 siblings, 0 replies; 200+ results
From: Dodji Seketeli @ 2024-02-28 14:03 UTC (permalink / raw)
  To: David Marchand
  Cc: Dodji Seketeli, dev, Ajit Khaparde, Andrew Boyer,
	Andrew Rybchenko, Bruce Richardson, Chenbo Xia, Chengwen Feng,
	Dariusz Sosnowski, David Christensen, Hyong Youb Kim,
	Jerin Jacob, Jie Hai, Jingjing Wu, John Daley, Kevin Laatz,
	Kiran Kumar K, Konstantin Ananyev, Maciej Czekaj, Matan Azrad,
	Maxime Coquelin, Nithin Dabilpuram, Ori Kam, Ruifeng Wang,
	Satha Rao, Somnath Kotur, Suanming Mou, Sunil Kumar Kori,
	Viacheslav Ovsiienko, Yisen Zhuang, Yuying Zhang, mb,
	Tyler Retzlaff

Hello,

David Marchand <david.marchand@redhat.com> writes:

> Hello Dodji,

o/

[...]


> This change is reported as a potential ABI change.
>
> For the context, this patch
> https://patchwork.dpdk.org/project/dpdk/patch/1709012499-12813-21-git-send-email-roretzla@linux.microsoft.com/
> removes null-sized markers (those fields were using RTE_MARKER, see
> https://git.dpdk.org/dpdk/tree/lib/eal/include/rte_common.h#n583) from
> the rte_mbuf struct.

Thank you for the context.

[...]


> As reported by the CI:

[...]

>   [C] 'function const rte_eth_rxtx_callback*
> rte_eth_add_first_rx_callback(uint16_t, uint16_t, rte_rx_callback_fn,
> void*)' at rte_ethdev.c:5768:1 has some indirect sub-type changes:
>     parameter 3 of type 'typedef rte_rx_callback_fn' has sub-type changes:

[...]

>               in pointed to type 'struct rte_mbuf' at rte_mbuf_core.h:470:1:
>                 type size hasn't changed
>                 4 data member deletions:
>                   'RTE_MARKER cacheline0', at offset 0 (in bits) at
> rte_mbuf_core.h:467:1
>                   'RTE_MARKER64 rearm_data', at offset 128 (in bits)
> at rte_mbuf_core.h:490:1
>                   'RTE_MARKER rx_descriptor_fields1', at offset 256
> (in bits) at rte_mbuf_core.h:517:1
>                   'RTE_MARKER cacheline1', at offset 512 (in bits) at
> rte_mbuf_core.h:598:1
>                 no data member change (1 filtered);

[...]

> I would argue this change do not impact ABI as the layout of the mbuf
> object is not impacted.

I agree that on the /particular platform/ that the checker runs on,
there is no incompatible ABI change because no data member offset from
the 'struct rte_mbuf' type got modified and the size of the type hasn't
changed either.


>
> Error: ABI issue reported for abidiff --suppr
> /home/runner/work/dpdk/dpdk/devtools/libabigail.abignore
> --no-added-syms --headers-dir1 reference/usr/local/include
> --headers-dir2 install/usr/local/include
> reference/usr/local/lib/librte_ethdev.so.24.0
> install/usr/local/lib/librte_ethdev.so.24.1
> ABIDIFF_ABI_CHANGE, this change requires a review (abidiff flagged
> this as a potential issue).
>
> Opinions?
>
> Btw, I see no way to suppress this (except a global [suppress_type]
> name = rte_mbuf)...

Right.

To avoid having subsequent changes to that type from being "overly"
suppressed, maybe do something like:

    [suppress_type]
     name = rte_mbuf
     has_size_change = no
     has_data_member = {cacheline0, rearm_data, rx_descriptor_fields1, cacheline1}

That way, only size-impacting changes to struct rte_mbuf in its form
that predates this patch would be suppressed, hopefully.

[...]

Cheers,

-- 
		Dodji


^ permalink raw reply	[relevance 3%]

* Re: [PATCH v6 20/23] mbuf: remove and stop using rte marker fields
  2024-02-27 17:23  4%       ` Tyler Retzlaff
@ 2024-02-28 10:42  3%         ` David Marchand
  0 siblings, 0 replies; 200+ results
From: David Marchand @ 2024-02-28 10:42 UTC (permalink / raw)
  To: Tyler Retzlaff, Thomas Monjalon
  Cc: Dodji Seketeli, dev, Ajit Khaparde, Andrew Boyer,
	Andrew Rybchenko, Bruce Richardson, Chenbo Xia, Chengwen Feng,
	Dariusz Sosnowski, David Christensen, Hyong Youb Kim,
	Jerin Jacob, Jie Hai, Jingjing Wu, John Daley, Kevin Laatz,
	Kiran Kumar K, Konstantin Ananyev, Maciej Czekaj, Matan Azrad,
	Maxime Coquelin, Nithin Dabilpuram, Ori Kam, Ruifeng Wang,
	Satha Rao, Somnath Kotur, Suanming Mou, Sunil Kumar Kori,
	Viacheslav Ovsiienko, Yisen Zhuang, Yuying Zhang, mb, ci

On Tue, Feb 27, 2024 at 6:23 PM Tyler Retzlaff
<roretzla@linux.microsoft.com> wrote:
>
> On Tue, Feb 27, 2024 at 04:18:10PM +0100, David Marchand wrote:
> > Hello Dodji,
> >
> > On Tue, Feb 27, 2024 at 6:44 AM Tyler Retzlaff
> > <roretzla@linux.microsoft.com> wrote:
> > >
> > > RTE_MARKER typedefs are a GCC extension unsupported by MSVC. Remove
> > > RTE_MARKER fields from rte_mbuf struct.
> > >
> > > Maintain alignment of fields after removed cacheline1 marker by placing
> > > C11 alignas(RTE_CACHE_LINE_MIN_SIZE).
> > >
> > > Update implementation of rte_mbuf_prefetch_part1() and
> > > rte_mbuf_prefetch_part2() inline functions calculate pointer for
> > > prefetch of cachline0 and cachline1 without using removed markers.
> > >
> > > Update static_assert of rte_mbuf struct fields to reference data_off and
> > > packet_type fields that occupy the original offsets of the marker
> > > fields.
> > >
> > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> >
> > This change is reported as a potential ABI change.
> >
> > For the context, this patch
> > https://patchwork.dpdk.org/project/dpdk/patch/1709012499-12813-21-git-send-email-roretzla@linux.microsoft.com/
> > removes null-sized markers (those fields were using RTE_MARKER, see
> > https://git.dpdk.org/dpdk/tree/lib/eal/include/rte_common.h#n583) from
> > the rte_mbuf struct.
> > I would argue this change do not impact ABI as the layout of the mbuf
> > object is not impacted.
>
> It isn't a surprise that the change got flagged because the 0 sized
> fields being removed probably not something the checker understands.
> So no ABI change just API break (as was requested).
>
> > As reported by the CI:
> >
> >   [C] 'function const rte_eth_rxtx_callback*
> > rte_eth_add_first_rx_callback(uint16_t, uint16_t, rte_rx_callback_fn,
> > void*)' at rte_ethdev.c:5768:1 has some indirect sub-type changes:
> >     parameter 3 of type 'typedef rte_rx_callback_fn' has sub-type changes:
> >       underlying type 'typedef uint16_t (typedef uint16_t, typedef
> > uint16_t, rte_mbuf**, typedef uint16_t, typedef uint16_t, void*)*'
> > changed:
> >         in pointed to type 'function type typedef uint16_t (typedef
> > uint16_t, typedef uint16_t, rte_mbuf**, typedef uint16_t, typedef
> > uint16_t, void*)':
> >           parameter 3 of type 'rte_mbuf**' has sub-type changes:
> >             in pointed to type 'rte_mbuf*':
> >               in pointed to type 'struct rte_mbuf' at rte_mbuf_core.h:470:1:
> >                 type size hasn't changed
> >                 4 data member deletions:
> >                   'RTE_MARKER cacheline0', at offset 0 (in bits) at
> > rte_mbuf_core.h:467:1
> >                   'RTE_MARKER64 rearm_data', at offset 128 (in bits)
> > at rte_mbuf_core.h:490:1
> >                   'RTE_MARKER rx_descriptor_fields1', at offset 256
> > (in bits) at rte_mbuf_core.h:517:1
> >                   'RTE_MARKER cacheline1', at offset 512 (in bits) at
> > rte_mbuf_core.h:598:1
> >                 no data member change (1 filtered);
> >
> > Error: ABI issue reported for abidiff --suppr
> > /home/runner/work/dpdk/dpdk/devtools/libabigail.abignore
> > --no-added-syms --headers-dir1 reference/usr/local/include
> > --headers-dir2 install/usr/local/include
> > reference/usr/local/lib/librte_ethdev.so.24.0
> > install/usr/local/lib/librte_ethdev.so.24.1
> > ABIDIFF_ABI_CHANGE, this change requires a review (abidiff flagged
> > this as a potential issue).
> >
> > Opinions?
> >
> > Btw, I see no way to suppress this (except a global [suppress_type]
> > name = rte_mbuf)...
>
> I am unfamiliar with the ABI checker I'm afraid i have no suggestion to
> offer. Maybe we can just ignore the failure for this one series when we
> decide it is ready to be merged and don't suppress the checker?

The ABI check compares a current build with a (cached) reference build.
There is no "let's ignore this specific error" mechanism at the moment.
And I suspect it would be non-trivial to add (parsing abidiff text
output... brrr).

Changing the check so that it compares against origin/main (for
example) every time is doable *on paper*, but it would consume a lot
of cpu for maintainers (like Thomas, Ferruh or me) and the CI.
CI scripts would have to be updated too.


Fow now, one thing we can do is to change the reference to point at
the exact commit that introduces a change we know safe.
This requires a little sync between people (maintainers / users of
test-meson-builds.h) and UNH CI, but this is doable.

On the other hand, by the time we merge this series, libabigail may
have fixed this for us already? ;-)


-- 
David Marchand


^ permalink raw reply	[relevance 3%]

* [DPDK/ethdev Bug 1386] [dpdk-24.03] [ABI][meson test] driver-tests/link_bonding_autotest test failed: Segmentation fault when do ABI testing
@ 2024-02-28  3:18  9% bugzilla
  0 siblings, 0 replies; 200+ results
From: bugzilla @ 2024-02-28  3:18 UTC (permalink / raw)
  To: dev

[-- Attachment #1: Type: text/plain, Size: 4592 bytes --]

https://bugs.dpdk.org/show_bug.cgi?id=1386

            Bug ID: 1386
           Summary: [dpdk-24.03] [ABI][meson test]
                    driver-tests/link_bonding_autotest test failed:
                    Segmentation fault when do ABI testing
           Product: DPDK
           Version: unspecified
          Hardware: All
                OS: All
            Status: UNCONFIRMED
          Severity: normal
          Priority: Normal
         Component: ethdev
          Assignee: dev@dpdk.org
          Reporter: yux.jiang@intel.com
  Target Milestone: ---

[Environment]

DPDK version: 92c0ad70ca version: 24.03-rc1
OS: RHEL9.0/5.14.0-70.13.1.el9_0.x86_64
Compiler: gcc version 11.2.1
Hardware platform: Intel(R) Xeon(R) Platinum 8180 CPU @ 2.50GHz
NIC hardware: Ethernet Controller XL710 for 40GbE QSFP+ 1583
NIC firmware: 
driver: i40e
version: 2.24.6
firmware-version: 9.40 0x8000ece4 1.3429.0

[Test Setup]
Steps to reproduce
List the steps to reproduce the issue.

1, Build latest main dpdk24.03-rc1
rm -rf x86_64-native-linuxapp-gcc
CC=gcc meson -Denable_kmods=True -Dlibdir=lib  --default-library=shared
x86_64-native-linuxapp-gcc
ninja -C x86_64-native-linuxapp-gcc
rm -rf /root/tmp/dpdk_share_lib /root/shared_lib_dpdk
DESTDIR=/root/tmp/dpdk_share_lib ninja -C x86_64-native-linuxapp-gcc -j 110
install
mv /root/tmp/dpdk_share_lib/usr/local/lib /root/shared_lib_dpdk
ll /root/shared_lib_dpdk
cat /root/.bashrc | grep LD_LIBRARY_PATH
sed -i 's#export LD_LIBRARY_PATH=.*#export
LD_LIBRARY_PATH=/root/shared_lib_dpdk#g' /root/.bashrc

2, Build LTS dpdk23.11.0
rm /root/dpdk
tar zxvf dpdk_abi.tar.gz -C ~
cd ~/dpdk/
rm -rf x86_64-native-linuxapp-gcc
CC=gcc meson -Denable_kmods=True -Dlibdir=lib  --default-library=shared
x86_64-native-linuxapp-gcc
ninja -C x86_64-native-linuxapp-gcc
rm -rf x86_64-native-linuxapp-gcc/lib
rm -rf x86_64-native-linuxapp-gcc/drivers

3, Bind nic
rmmod vfio_pci
rmmod vfio_iommu_type1
rmmod vfio
modprobe vfio
modprobe vfio-pci
usertools/dpdk-devbind.py --force --bind=vfio-pci 0000:18:00.0 0000:1a:00.0

4, Launch dpdk-test and run link_bonding_autotest
x86_64-native-linuxapp-gcc/app/dpdk-test -c 0xff -d /root/shared_lib_dpdk -a
0000:18:00.0 -a 0000:1a:00.0
RTE>>link_bonding_autotest

Show the output from the previous commands.
[root@ABI-80 dpdk]# x86_64-native-linuxapp-gcc/app/dpdk-test -c 0xff -d
/root/shared_lib_dpdk -a 0000:18:00.0 -a 0000:1a:00.0
EAL: Detected CPU lcores: 112
EAL: Detected NUMA nodes: 2
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
EAL: VFIO support initialized
EAL: Using IOMMU type 1 (Type 1)
EAL: Ignore mapping IO port bar(1)
EAL: Ignore mapping IO port bar(4)
EAL: Probe PCI driver: net_i40e (8086:1583) device: 0000:18:00.0 (socket 0)
i40e_GLQF_reg_init(): i40e device 0000:18:00.0 changed global register
[0x002689a0]. original: 0x00000021, new: 0x00000029
EAL: Ignore mapping IO port bar(1)
EAL: Ignore mapping IO port bar(4)
EAL: Probe PCI driver: net_i40e (8086:1583) device: 0000:1a:00.0 (socket 0)
i40e_GLQF_reg_init(): i40e device 0000:1a:00.0 changed global register
[0x002689a0]. original: 0x00000021, new: 0x00000029
TELEMETRY: No legacy callbacks, legacy socket not created
APP: HPET is not enabled, using TSC as default timer
RTE>>link_bonding_autotest
 + ------------------------------------------------------- +
 + Test Suite : Link Bonding Unit Test Suite
Segmentation fault (core dumped)

[Expected Result]
Test ok.

[Regression]
Is this issue a regression: (Y/N) Y
The first bad commit:
commit d4b9235f95de4f46f368627af256ed8080f20d65
Author: Jerin Jacob <jerinj@marvell.com>
Date:   Thu Jan 18 15:17:42 2024 +0530

    ethdev: add Tx queue used count query

    Introduce a new API to retrieve the number of used descriptors
    in a Tx queue. Applications can leverage this API in the fast path to
    inspect the Tx queue occupancy and take appropriate actions based on the
    available free descriptors.

    A notable use case could be implementing Random Early Discard (RED)
    in software based on Tx queue occupancy.

    Signed-off-by: Jerin Jacob <jerinj@marvell.com>
    Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
    Acked-by: Morten Brørup <mb@smartsharesystems.com>
    Acked-by: Konstantin Ananyev <konstantin.ananyev@huawei.com>
    Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>

-- 
You are receiving this mail because:
You are the assignee for the bug.

[-- Attachment #2: Type: text/html, Size: 6869 bytes --]

^ permalink raw reply	[relevance 9%]

* [PATCH v3 4/6] pipeline: replace zero length array with flex array
  @ 2024-02-27 23:56  4%   ` Tyler Retzlaff
  0 siblings, 0 replies; 200+ results
From: Tyler Retzlaff @ 2024-02-27 23:56 UTC (permalink / raw)
  To: dev
  Cc: Bruce Richardson, Cristian Dumitrescu, Honnappa Nagarahalli,
	Sameh Gobriel, Vladimir Medvedkin, Yipeng Wang, mb, fengchengwen,
	Tyler Retzlaff

Zero length arrays are GNU extension. Replace with
standard flex array.

Add a temporary suppression for rte_pipeline_table_entry
libabigail bug:

Bugzilla ID: https://sourceware.org/bugzilla/show_bug.cgi?id=31377

Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
Reviewed-by: Morten Brørup <mb@smartsharesystems.com>
Acked-by: Stephen Hemminger <stephen@networkplumber.org>
---
 devtools/libabigail.abignore      | 2 ++
 lib/pipeline/rte_pipeline.h       | 2 +-
 lib/pipeline/rte_port_in_action.c | 2 +-
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index 645d289..2a23d53 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -33,6 +33,8 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Temporary exceptions till next major ABI version ;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+[suppress_type]
+	name = rte_pipeline_table_entry
 
 [suppress_type]
 	name = rte_eth_fp_ops
diff --git a/lib/pipeline/rte_pipeline.h b/lib/pipeline/rte_pipeline.h
index ec51b9b..0c7994b 100644
--- a/lib/pipeline/rte_pipeline.h
+++ b/lib/pipeline/rte_pipeline.h
@@ -220,7 +220,7 @@ struct rte_pipeline_table_entry {
 		uint32_t table_id;
 	};
 	/** Start of table entry area for user defined actions and meta-data */
-	__extension__ uint8_t action_data[0];
+	uint8_t action_data[];
 };
 
 /**
diff --git a/lib/pipeline/rte_port_in_action.c b/lib/pipeline/rte_port_in_action.c
index 5818973..ebd9b9a 100644
--- a/lib/pipeline/rte_port_in_action.c
+++ b/lib/pipeline/rte_port_in_action.c
@@ -282,7 +282,7 @@ struct rte_port_in_action_profile *
 struct rte_port_in_action {
 	struct ap_config cfg;
 	struct ap_data data;
-	uint8_t memory[0] __rte_cache_aligned;
+	uint8_t memory[] __rte_cache_aligned;
 };
 
 static __rte_always_inline void *
-- 
1.8.3.1


^ permalink raw reply	[relevance 4%]

* Re: [PATCH v6 20/23] mbuf: remove and stop using rte marker fields
  2024-02-27 15:18  4%     ` David Marchand
  2024-02-27 16:04  3%       ` Morten Brørup
@ 2024-02-27 17:23  4%       ` Tyler Retzlaff
  2024-02-28 10:42  3%         ` David Marchand
  2024-02-28 14:03  3%       ` Dodji Seketeli
  2 siblings, 1 reply; 200+ results
From: Tyler Retzlaff @ 2024-02-27 17:23 UTC (permalink / raw)
  To: David Marchand
  Cc: Dodji Seketeli, dev, Ajit Khaparde, Andrew Boyer,
	Andrew Rybchenko, Bruce Richardson, Chenbo Xia, Chengwen Feng,
	Dariusz Sosnowski, David Christensen, Hyong Youb Kim,
	Jerin Jacob, Jie Hai, Jingjing Wu, John Daley, Kevin Laatz,
	Kiran Kumar K, Konstantin Ananyev, Maciej Czekaj, Matan Azrad,
	Maxime Coquelin, Nithin Dabilpuram, Ori Kam, Ruifeng Wang,
	Satha Rao, Somnath Kotur, Suanming Mou, Sunil Kumar Kori,
	Viacheslav Ovsiienko, Yisen Zhuang, Yuying Zhang, mb

On Tue, Feb 27, 2024 at 04:18:10PM +0100, David Marchand wrote:
> Hello Dodji,
> 
> On Tue, Feb 27, 2024 at 6:44 AM Tyler Retzlaff
> <roretzla@linux.microsoft.com> wrote:
> >
> > RTE_MARKER typedefs are a GCC extension unsupported by MSVC. Remove
> > RTE_MARKER fields from rte_mbuf struct.
> >
> > Maintain alignment of fields after removed cacheline1 marker by placing
> > C11 alignas(RTE_CACHE_LINE_MIN_SIZE).
> >
> > Update implementation of rte_mbuf_prefetch_part1() and
> > rte_mbuf_prefetch_part2() inline functions calculate pointer for
> > prefetch of cachline0 and cachline1 without using removed markers.
> >
> > Update static_assert of rte_mbuf struct fields to reference data_off and
> > packet_type fields that occupy the original offsets of the marker
> > fields.
> >
> > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> 
> This change is reported as a potential ABI change.
> 
> For the context, this patch
> https://patchwork.dpdk.org/project/dpdk/patch/1709012499-12813-21-git-send-email-roretzla@linux.microsoft.com/
> removes null-sized markers (those fields were using RTE_MARKER, see
> https://git.dpdk.org/dpdk/tree/lib/eal/include/rte_common.h#n583) from
> the rte_mbuf struct.
> I would argue this change do not impact ABI as the layout of the mbuf
> object is not impacted.

It isn't a surprise that the change got flagged because the 0 sized
fields being removed probably not something the checker understands.
So no ABI change just API break (as was requested).

> As reported by the CI:
> 
>   [C] 'function const rte_eth_rxtx_callback*
> rte_eth_add_first_rx_callback(uint16_t, uint16_t, rte_rx_callback_fn,
> void*)' at rte_ethdev.c:5768:1 has some indirect sub-type changes:
>     parameter 3 of type 'typedef rte_rx_callback_fn' has sub-type changes:
>       underlying type 'typedef uint16_t (typedef uint16_t, typedef
> uint16_t, rte_mbuf**, typedef uint16_t, typedef uint16_t, void*)*'
> changed:
>         in pointed to type 'function type typedef uint16_t (typedef
> uint16_t, typedef uint16_t, rte_mbuf**, typedef uint16_t, typedef
> uint16_t, void*)':
>           parameter 3 of type 'rte_mbuf**' has sub-type changes:
>             in pointed to type 'rte_mbuf*':
>               in pointed to type 'struct rte_mbuf' at rte_mbuf_core.h:470:1:
>                 type size hasn't changed
>                 4 data member deletions:
>                   'RTE_MARKER cacheline0', at offset 0 (in bits) at
> rte_mbuf_core.h:467:1
>                   'RTE_MARKER64 rearm_data', at offset 128 (in bits)
> at rte_mbuf_core.h:490:1
>                   'RTE_MARKER rx_descriptor_fields1', at offset 256
> (in bits) at rte_mbuf_core.h:517:1
>                   'RTE_MARKER cacheline1', at offset 512 (in bits) at
> rte_mbuf_core.h:598:1
>                 no data member change (1 filtered);
> 
> Error: ABI issue reported for abidiff --suppr
> /home/runner/work/dpdk/dpdk/devtools/libabigail.abignore
> --no-added-syms --headers-dir1 reference/usr/local/include
> --headers-dir2 install/usr/local/include
> reference/usr/local/lib/librte_ethdev.so.24.0
> install/usr/local/lib/librte_ethdev.so.24.1
> ABIDIFF_ABI_CHANGE, this change requires a review (abidiff flagged
> this as a potential issue).
> 
> Opinions?
> 
> Btw, I see no way to suppress this (except a global [suppress_type]
> name = rte_mbuf)...

I am unfamiliar with the ABI checker I'm afraid i have no suggestion to
offer. Maybe we can just ignore the failure for this one series when we
decide it is ready to be merged and don't suppress the checker?

> 
> 
> -- 
> David Marchand

^ permalink raw reply	[relevance 4%]

* RE: [PATCH v6 20/23] mbuf: remove and stop using rte marker fields
  2024-02-27 15:18  4%     ` David Marchand
@ 2024-02-27 16:04  3%       ` Morten Brørup
  2024-02-27 17:23  4%       ` Tyler Retzlaff
  2024-02-28 14:03  3%       ` Dodji Seketeli
  2 siblings, 0 replies; 200+ results
From: Morten Brørup @ 2024-02-27 16:04 UTC (permalink / raw)
  To: David Marchand, Dodji Seketeli
  Cc: dev, Ajit Khaparde, Andrew Boyer, Andrew Rybchenko,
	Bruce Richardson, Chenbo Xia, Chengwen Feng, Dariusz Sosnowski,
	David Christensen, Hyong Youb Kim, Jerin Jacob, Jie Hai,
	Jingjing Wu, John Daley, Kevin Laatz, Kiran Kumar K,
	Konstantin Ananyev, Maciej Czekaj, Matan Azrad, Maxime Coquelin,
	Nithin Dabilpuram, Ori Kam, Ruifeng Wang, Satha Rao,
	Somnath Kotur, Suanming Mou, Sunil Kumar Kori,
	Viacheslav Ovsiienko, Yisen Zhuang, Yuying Zhang, Tyler Retzlaff

> From: David Marchand [mailto:david.marchand@redhat.com]
> Sent: Tuesday, 27 February 2024 16.18
> 
> Hello Dodji,
> 
> On Tue, Feb 27, 2024 at 6:44 AM Tyler Retzlaff
> <roretzla@linux.microsoft.com> wrote:
> >
> > RTE_MARKER typedefs are a GCC extension unsupported by MSVC. Remove
> > RTE_MARKER fields from rte_mbuf struct.
> >
> > Maintain alignment of fields after removed cacheline1 marker by
> placing
> > C11 alignas(RTE_CACHE_LINE_MIN_SIZE).
> >
> > Update implementation of rte_mbuf_prefetch_part1() and
> > rte_mbuf_prefetch_part2() inline functions calculate pointer for
> > prefetch of cachline0 and cachline1 without using removed markers.
> >
> > Update static_assert of rte_mbuf struct fields to reference data_off
> and
> > packet_type fields that occupy the original offsets of the marker
> > fields.
> >
> > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> 
> This change is reported as a potential ABI change.
> 
> For the context, this patch
> https://patchwork.dpdk.org/project/dpdk/patch/1709012499-12813-21-git-
> send-email-roretzla@linux.microsoft.com/
> removes null-sized markers (those fields were using RTE_MARKER, see
> https://git.dpdk.org/dpdk/tree/lib/eal/include/rte_common.h#n583) from
> the rte_mbuf struct.
> I would argue this change do not impact ABI as the layout of the mbuf
> object is not impacted.
> 
> As reported by the CI:
> 
>   [C] 'function const rte_eth_rxtx_callback*
> rte_eth_add_first_rx_callback(uint16_t, uint16_t, rte_rx_callback_fn,
> void*)' at rte_ethdev.c:5768:1 has some indirect sub-type changes:
>     parameter 3 of type 'typedef rte_rx_callback_fn' has sub-type
> changes:
>       underlying type 'typedef uint16_t (typedef uint16_t, typedef
> uint16_t, rte_mbuf**, typedef uint16_t, typedef uint16_t, void*)*'
> changed:
>         in pointed to type 'function type typedef uint16_t (typedef
> uint16_t, typedef uint16_t, rte_mbuf**, typedef uint16_t, typedef
> uint16_t, void*)':
>           parameter 3 of type 'rte_mbuf**' has sub-type changes:
>             in pointed to type 'rte_mbuf*':
>               in pointed to type 'struct rte_mbuf' at
> rte_mbuf_core.h:470:1:
>                 type size hasn't changed
>                 4 data member deletions:
>                   'RTE_MARKER cacheline0', at offset 0 (in bits) at
> rte_mbuf_core.h:467:1
>                   'RTE_MARKER64 rearm_data', at offset 128 (in bits)
> at rte_mbuf_core.h:490:1
>                   'RTE_MARKER rx_descriptor_fields1', at offset 256
> (in bits) at rte_mbuf_core.h:517:1
>                   'RTE_MARKER cacheline1', at offset 512 (in bits) at
> rte_mbuf_core.h:598:1
>                 no data member change (1 filtered);
> 
> Error: ABI issue reported for abidiff --suppr
> /home/runner/work/dpdk/dpdk/devtools/libabigail.abignore
> --no-added-syms --headers-dir1 reference/usr/local/include
> --headers-dir2 install/usr/local/include
> reference/usr/local/lib/librte_ethdev.so.24.0
> install/usr/local/lib/librte_ethdev.so.24.1
> ABIDIFF_ABI_CHANGE, this change requires a review (abidiff flagged
> this as a potential issue).
> 
> Opinions?

Agree: Not an ABI change, only API change.

> 
> Btw, I see no way to suppress this (except a global [suppress_type]
> name = rte_mbuf)...
> 
> 
> --
> David Marchand


^ permalink raw reply	[relevance 3%]

* Re: [PATCH v6 20/23] mbuf: remove and stop using rte marker fields
  @ 2024-02-27 15:18  4%     ` David Marchand
  2024-02-27 16:04  3%       ` Morten Brørup
                         ` (2 more replies)
    1 sibling, 3 replies; 200+ results
From: David Marchand @ 2024-02-27 15:18 UTC (permalink / raw)
  To: Dodji Seketeli
  Cc: dev, Ajit Khaparde, Andrew Boyer, Andrew Rybchenko,
	Bruce Richardson, Chenbo Xia, Chengwen Feng, Dariusz Sosnowski,
	David Christensen, Hyong Youb Kim, Jerin Jacob, Jie Hai,
	Jingjing Wu, John Daley, Kevin Laatz, Kiran Kumar K,
	Konstantin Ananyev, Maciej Czekaj, Matan Azrad, Maxime Coquelin,
	Nithin Dabilpuram, Ori Kam, Ruifeng Wang, Satha Rao,
	Somnath Kotur, Suanming Mou, Sunil Kumar Kori,
	Viacheslav Ovsiienko, Yisen Zhuang, Yuying Zhang, mb,
	Tyler Retzlaff

Hello Dodji,

On Tue, Feb 27, 2024 at 6:44 AM Tyler Retzlaff
<roretzla@linux.microsoft.com> wrote:
>
> RTE_MARKER typedefs are a GCC extension unsupported by MSVC. Remove
> RTE_MARKER fields from rte_mbuf struct.
>
> Maintain alignment of fields after removed cacheline1 marker by placing
> C11 alignas(RTE_CACHE_LINE_MIN_SIZE).
>
> Update implementation of rte_mbuf_prefetch_part1() and
> rte_mbuf_prefetch_part2() inline functions calculate pointer for
> prefetch of cachline0 and cachline1 without using removed markers.
>
> Update static_assert of rte_mbuf struct fields to reference data_off and
> packet_type fields that occupy the original offsets of the marker
> fields.
>
> Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>

This change is reported as a potential ABI change.

For the context, this patch
https://patchwork.dpdk.org/project/dpdk/patch/1709012499-12813-21-git-send-email-roretzla@linux.microsoft.com/
removes null-sized markers (those fields were using RTE_MARKER, see
https://git.dpdk.org/dpdk/tree/lib/eal/include/rte_common.h#n583) from
the rte_mbuf struct.
I would argue this change do not impact ABI as the layout of the mbuf
object is not impacted.

As reported by the CI:

  [C] 'function const rte_eth_rxtx_callback*
rte_eth_add_first_rx_callback(uint16_t, uint16_t, rte_rx_callback_fn,
void*)' at rte_ethdev.c:5768:1 has some indirect sub-type changes:
    parameter 3 of type 'typedef rte_rx_callback_fn' has sub-type changes:
      underlying type 'typedef uint16_t (typedef uint16_t, typedef
uint16_t, rte_mbuf**, typedef uint16_t, typedef uint16_t, void*)*'
changed:
        in pointed to type 'function type typedef uint16_t (typedef
uint16_t, typedef uint16_t, rte_mbuf**, typedef uint16_t, typedef
uint16_t, void*)':
          parameter 3 of type 'rte_mbuf**' has sub-type changes:
            in pointed to type 'rte_mbuf*':
              in pointed to type 'struct rte_mbuf' at rte_mbuf_core.h:470:1:
                type size hasn't changed
                4 data member deletions:
                  'RTE_MARKER cacheline0', at offset 0 (in bits) at
rte_mbuf_core.h:467:1
                  'RTE_MARKER64 rearm_data', at offset 128 (in bits)
at rte_mbuf_core.h:490:1
                  'RTE_MARKER rx_descriptor_fields1', at offset 256
(in bits) at rte_mbuf_core.h:517:1
                  'RTE_MARKER cacheline1', at offset 512 (in bits) at
rte_mbuf_core.h:598:1
                no data member change (1 filtered);

Error: ABI issue reported for abidiff --suppr
/home/runner/work/dpdk/dpdk/devtools/libabigail.abignore
--no-added-syms --headers-dir1 reference/usr/local/include
--headers-dir2 install/usr/local/include
reference/usr/local/lib/librte_ethdev.so.24.0
install/usr/local/lib/librte_ethdev.so.24.1
ABIDIFF_ABI_CHANGE, this change requires a review (abidiff flagged
this as a potential issue).

Opinions?

Btw, I see no way to suppress this (except a global [suppress_type]
name = rte_mbuf)...


-- 
David Marchand


^ permalink raw reply	[relevance 4%]

* RE: [PATCH v6 27/39] mempool: use C11 alignas
  2024-02-26 18:25  3%   ` [PATCH v6 27/39] mempool: " Tyler Retzlaff
@ 2024-02-27  9:42  0%     ` Konstantin Ananyev
  0 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2024-02-27  9:42 UTC (permalink / raw)
  To: Tyler Retzlaff, dev
  Cc: Andrew Rybchenko, Bruce Richardson, Fengchengwen,
	Cristian Dumitrescu, David Christensen, David Hunt, Ferruh Yigit,
	Honnappa Nagarahalli, Jasvinder Singh, Jerin Jacob, Kevin Laatz,
	Konstantin Ananyev, Min Zhou, Ruifeng Wang, Sameh Gobriel,
	Stanislaw Kardach, Thomas Monjalon, Vladimir Medvedkin,
	Yipeng Wang



> Subject: [PATCH v6 27/39] mempool: use C11 alignas
> 
> The current location used for __rte_aligned(a) for alignment of types
> and variables is not compatible with MSVC. There is only a single
> location accepted by both toolchains.
> 
> For variables standard C11 offers alignas(a) supported by conformant
> compilers i.e. both MSVC and GCC.
> 
> For types the standard offers no alignment facility that compatibly
> interoperates with C and C++ but may be achieved by relocating the
> placement of __rte_aligned(a) to the aforementioned location accepted
> by all currently supported toolchains.
> 
> To allow alignment for both compilers do the following:
> 
> * Move __rte_aligned from the end of {struct,union} definitions to
>   be between {struct,union} and tag.
> 
>   The placement between {struct,union} and the tag allows the desired
>   alignment to be imparted on the type regardless of the toolchain being
>   used for all of GCC, LLVM, MSVC compilers building both C and C++.
> 
> * Replace use of __rte_aligned(a) on variables/fields with alignas(a).
> 
> Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> Acked-by: Morten Brørup <mb@smartsharesystems.com>
> ---
>  lib/mempool/rte_mempool.h | 27 ++++++++++++++-------------
>  1 file changed, 14 insertions(+), 13 deletions(-)
> 
> diff --git a/lib/mempool/rte_mempool.h b/lib/mempool/rte_mempool.h
> index 6fa4d48..23fd5c8 100644
> --- a/lib/mempool/rte_mempool.h
> +++ b/lib/mempool/rte_mempool.h
> @@ -34,6 +34,7 @@
>   * user cache created with rte_mempool_cache_create().
>   */
> 
> +#include <stdalign.h>
>  #include <stdio.h>
>  #include <stdint.h>
>  #include <inttypes.h>
> @@ -66,7 +67,7 @@
>   * captured since they can be calculated from other stats.
>   * For example: put_cache_objs = put_objs - put_common_pool_objs.
>   */
> -struct rte_mempool_debug_stats {
> +struct __rte_cache_aligned rte_mempool_debug_stats {
>  	uint64_t put_bulk;             /**< Number of puts. */
>  	uint64_t put_objs;             /**< Number of objects successfully put. */
>  	uint64_t put_common_pool_bulk; /**< Number of bulks enqueued in common pool. */
> @@ -80,13 +81,13 @@ struct rte_mempool_debug_stats {
>  	uint64_t get_success_blks;     /**< Successful allocation number of contiguous blocks. */
>  	uint64_t get_fail_blks;        /**< Failed allocation number of contiguous blocks. */
>  	RTE_CACHE_GUARD;
> -} __rte_cache_aligned;
> +};
>  #endif
> 
>  /**
>   * A structure that stores a per-core object cache.
>   */
> -struct rte_mempool_cache {
> +struct __rte_cache_aligned rte_mempool_cache {
>  	uint32_t size;	      /**< Size of the cache */
>  	uint32_t flushthresh; /**< Threshold before we flush excess elements */
>  	uint32_t len;	      /**< Current cache count */
> @@ -109,8 +110,8 @@ struct rte_mempool_cache {
>  	 * Cache is allocated to this size to allow it to overflow in certain
>  	 * cases to avoid needless emptying of cache.
>  	 */
> -	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2] __rte_cache_aligned;
> -} __rte_cache_aligned;
> +	alignas(RTE_CACHE_LINE_SIZE) void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2];
> +};
> 
>  /**
>   * A structure that stores the size of mempool elements.
> @@ -218,15 +219,15 @@ struct rte_mempool_memhdr {
>   * The structure is cache-line aligned to avoid ABI breakages in
>   * a number of cases when something small is added.
>   */
> -struct rte_mempool_info {
> +struct __rte_cache_aligned rte_mempool_info {
>  	/** Number of objects in the contiguous block */
>  	unsigned int contig_block_size;
> -} __rte_cache_aligned;
> +};
> 
>  /**
>   * The RTE mempool structure.
>   */
> -struct rte_mempool {
> +struct __rte_cache_aligned rte_mempool {
>  	char name[RTE_MEMPOOL_NAMESIZE]; /**< Name of mempool. */
>  	union {
>  		void *pool_data;         /**< Ring or pool to store objects. */
> @@ -268,7 +269,7 @@ struct rte_mempool {
>  	 */
>  	struct rte_mempool_debug_stats stats[RTE_MAX_LCORE + 1];
>  #endif
> -}  __rte_cache_aligned;
> +};
> 
>  /** Spreading among memory channels not required. */
>  #define RTE_MEMPOOL_F_NO_SPREAD		0x0001
> @@ -688,7 +689,7 @@ typedef int (*rte_mempool_get_info_t)(const struct rte_mempool *mp,
> 
> 
>  /** Structure defining mempool operations structure */
> -struct rte_mempool_ops {
> +struct __rte_cache_aligned rte_mempool_ops {
>  	char name[RTE_MEMPOOL_OPS_NAMESIZE]; /**< Name of mempool ops struct. */
>  	rte_mempool_alloc_t alloc;       /**< Allocate private data. */
>  	rte_mempool_free_t free;         /**< Free the external pool. */
> @@ -713,7 +714,7 @@ struct rte_mempool_ops {
>  	 * Dequeue a number of contiguous object blocks.
>  	 */
>  	rte_mempool_dequeue_contig_blocks_t dequeue_contig_blocks;
> -} __rte_cache_aligned;
> +};
> 
>  #define RTE_MEMPOOL_MAX_OPS_IDX 16  /**< Max registered ops structs */
> 
> @@ -726,14 +727,14 @@ struct rte_mempool_ops {
>   * any function pointers stored directly in the mempool struct would not be.
>   * This results in us simply having "ops_index" in the mempool struct.
>   */
> -struct rte_mempool_ops_table {
> +struct __rte_cache_aligned rte_mempool_ops_table {
>  	rte_spinlock_t sl;     /**< Spinlock for add/delete. */
>  	uint32_t num_ops;      /**< Number of used ops structs in the table. */
>  	/**
>  	 * Storage for all possible ops structs.
>  	 */
>  	struct rte_mempool_ops ops[RTE_MEMPOOL_MAX_OPS_IDX];
> -} __rte_cache_aligned;
> +};
> 
>  /** Array of registered ops structs. */
>  extern struct rte_mempool_ops_table rte_mempool_ops_table;
> --

Acked-by: Konstantin Ananyev <konstantin.ananyev@huawei.com>

> 1.8.3.1


^ permalink raw reply	[relevance 0%]

* [PATCH v6 27/39] mempool: use C11 alignas
  @ 2024-02-26 18:25  3%   ` Tyler Retzlaff
  2024-02-27  9:42  0%     ` Konstantin Ananyev
  0 siblings, 1 reply; 200+ results
From: Tyler Retzlaff @ 2024-02-26 18:25 UTC (permalink / raw)
  To: dev
  Cc: Andrew Rybchenko, Bruce Richardson, Chengwen Feng,
	Cristian Dumitrescu, David Christensen, David Hunt, Ferruh Yigit,
	Honnappa Nagarahalli, Jasvinder Singh, Jerin Jacob, Kevin Laatz,
	Konstantin Ananyev, Min Zhou, Ruifeng Wang, Sameh Gobriel,
	Stanislaw Kardach, Thomas Monjalon, Vladimir Medvedkin,
	Yipeng Wang, Tyler Retzlaff

The current location used for __rte_aligned(a) for alignment of types
and variables is not compatible with MSVC. There is only a single
location accepted by both toolchains.

For variables standard C11 offers alignas(a) supported by conformant
compilers i.e. both MSVC and GCC.

For types the standard offers no alignment facility that compatibly
interoperates with C and C++ but may be achieved by relocating the
placement of __rte_aligned(a) to the aforementioned location accepted
by all currently supported toolchains.

To allow alignment for both compilers do the following:

* Move __rte_aligned from the end of {struct,union} definitions to
  be between {struct,union} and tag.

  The placement between {struct,union} and the tag allows the desired
  alignment to be imparted on the type regardless of the toolchain being
  used for all of GCC, LLVM, MSVC compilers building both C and C++.

* Replace use of __rte_aligned(a) on variables/fields with alignas(a).

Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
Acked-by: Morten Brørup <mb@smartsharesystems.com>
---
 lib/mempool/rte_mempool.h | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/lib/mempool/rte_mempool.h b/lib/mempool/rte_mempool.h
index 6fa4d48..23fd5c8 100644
--- a/lib/mempool/rte_mempool.h
+++ b/lib/mempool/rte_mempool.h
@@ -34,6 +34,7 @@
  * user cache created with rte_mempool_cache_create().
  */
 
+#include <stdalign.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <inttypes.h>
@@ -66,7 +67,7 @@
  * captured since they can be calculated from other stats.
  * For example: put_cache_objs = put_objs - put_common_pool_objs.
  */
-struct rte_mempool_debug_stats {
+struct __rte_cache_aligned rte_mempool_debug_stats {
 	uint64_t put_bulk;             /**< Number of puts. */
 	uint64_t put_objs;             /**< Number of objects successfully put. */
 	uint64_t put_common_pool_bulk; /**< Number of bulks enqueued in common pool. */
@@ -80,13 +81,13 @@ struct rte_mempool_debug_stats {
 	uint64_t get_success_blks;     /**< Successful allocation number of contiguous blocks. */
 	uint64_t get_fail_blks;        /**< Failed allocation number of contiguous blocks. */
 	RTE_CACHE_GUARD;
-} __rte_cache_aligned;
+};
 #endif
 
 /**
  * A structure that stores a per-core object cache.
  */
-struct rte_mempool_cache {
+struct __rte_cache_aligned rte_mempool_cache {
 	uint32_t size;	      /**< Size of the cache */
 	uint32_t flushthresh; /**< Threshold before we flush excess elements */
 	uint32_t len;	      /**< Current cache count */
@@ -109,8 +110,8 @@ struct rte_mempool_cache {
 	 * Cache is allocated to this size to allow it to overflow in certain
 	 * cases to avoid needless emptying of cache.
 	 */
-	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2] __rte_cache_aligned;
-} __rte_cache_aligned;
+	alignas(RTE_CACHE_LINE_SIZE) void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2];
+};
 
 /**
  * A structure that stores the size of mempool elements.
@@ -218,15 +219,15 @@ struct rte_mempool_memhdr {
  * The structure is cache-line aligned to avoid ABI breakages in
  * a number of cases when something small is added.
  */
-struct rte_mempool_info {
+struct __rte_cache_aligned rte_mempool_info {
 	/** Number of objects in the contiguous block */
 	unsigned int contig_block_size;
-} __rte_cache_aligned;
+};
 
 /**
  * The RTE mempool structure.
  */
-struct rte_mempool {
+struct __rte_cache_aligned rte_mempool {
 	char name[RTE_MEMPOOL_NAMESIZE]; /**< Name of mempool. */
 	union {
 		void *pool_data;         /**< Ring or pool to store objects. */
@@ -268,7 +269,7 @@ struct rte_mempool {
 	 */
 	struct rte_mempool_debug_stats stats[RTE_MAX_LCORE + 1];
 #endif
-}  __rte_cache_aligned;
+};
 
 /** Spreading among memory channels not required. */
 #define RTE_MEMPOOL_F_NO_SPREAD		0x0001
@@ -688,7 +689,7 @@ typedef int (*rte_mempool_get_info_t)(const struct rte_mempool *mp,
 
 
 /** Structure defining mempool operations structure */
-struct rte_mempool_ops {
+struct __rte_cache_aligned rte_mempool_ops {
 	char name[RTE_MEMPOOL_OPS_NAMESIZE]; /**< Name of mempool ops struct. */
 	rte_mempool_alloc_t alloc;       /**< Allocate private data. */
 	rte_mempool_free_t free;         /**< Free the external pool. */
@@ -713,7 +714,7 @@ struct rte_mempool_ops {
 	 * Dequeue a number of contiguous object blocks.
 	 */
 	rte_mempool_dequeue_contig_blocks_t dequeue_contig_blocks;
-} __rte_cache_aligned;
+};
 
 #define RTE_MEMPOOL_MAX_OPS_IDX 16  /**< Max registered ops structs */
 
@@ -726,14 +727,14 @@ struct rte_mempool_ops {
  * any function pointers stored directly in the mempool struct would not be.
  * This results in us simply having "ops_index" in the mempool struct.
  */
-struct rte_mempool_ops_table {
+struct __rte_cache_aligned rte_mempool_ops_table {
 	rte_spinlock_t sl;     /**< Spinlock for add/delete. */
 	uint32_t num_ops;      /**< Number of used ops structs in the table. */
 	/**
 	 * Storage for all possible ops structs.
 	 */
 	struct rte_mempool_ops ops[RTE_MEMPOOL_MAX_OPS_IDX];
-} __rte_cache_aligned;
+};
 
 /** Array of registered ops structs. */
 extern struct rte_mempool_ops_table rte_mempool_ops_table;
-- 
1.8.3.1


^ permalink raw reply	[relevance 3%]

* Re: [PATCH v4 1/7] ethdev: support report register names and filter
  2024-02-26  3:07  8%   ` [PATCH v4 1/7] ethdev: support report register names and filter Jie Hai
@ 2024-02-26  8:01  0%     ` fengchengwen
  2024-03-06  7:22  0%       ` Jie Hai
  2024-02-29  9:52  3%     ` Thomas Monjalon
  1 sibling, 1 reply; 200+ results
From: fengchengwen @ 2024-02-26  8:01 UTC (permalink / raw)
  To: Jie Hai, dev; +Cc: lihuisong, liuyonglong, huangdengdui, ferruh.yigit

Hi Jie,

On 2024/2/26 11:07, Jie Hai wrote:
> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
> structure. Names of registers in data fields can be reported and
> the registers can be filtered by their names.
> 
> The new API rte_eth_dev_get_reg_info_ext() is added to support
> reporting names and filtering by names. And the original API
> rte_eth_dev_get_reg_info() does not use the name and filter fields.
> A local variable is used in rte_eth_dev_get_reg_info for
> compatibility. If the drivers does not report the names, set them
> to "offset_XXX".
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>  doc/guides/rel_notes/release_24_03.rst |  8 ++++++
>  lib/ethdev/rte_dev_info.h              | 11 +++++++++
>  lib/ethdev/rte_ethdev.c                | 34 ++++++++++++++++++++++++++
>  lib/ethdev/rte_ethdev.h                | 28 +++++++++++++++++++++
>  lib/ethdev/version.map                 |  1 +
>  5 files changed, 82 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
> index 32d0ad8cf6a7..fa46da427dca 100644
> --- a/doc/guides/rel_notes/release_24_03.rst
> +++ b/doc/guides/rel_notes/release_24_03.rst
> @@ -132,6 +132,11 @@ New Features
>      to support TLS v1.2, TLS v1.3 and DTLS v1.2.
>    * Added PMD API to allow raw submission of instructions to CPT.
>  
> +  * **Added support for dumping registers with names and filter.**
> +
> +    * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
> +      the registers by their names and get the information of registers(names,
> +      values and other attributes).
>  
>  Removed Items
>  -------------
> @@ -197,6 +202,9 @@ ABI Changes
>  
>  * No ABI change that would break compatibility with 23.11.
>  
> +* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
> +  structure for reporting names of registers and filtering them by names.
> +
>  
>  Known Issues
>  ------------
> diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
> index 67cf0ae52668..0ad4a43b9526 100644
> --- a/lib/ethdev/rte_dev_info.h
> +++ b/lib/ethdev/rte_dev_info.h
> @@ -11,6 +11,11 @@ extern "C" {
>  
>  #include <stdint.h>
>  
> +#define RTE_ETH_REG_NAME_SIZE 128

Almost all stats name size is 64, why not keep consistent?

> +struct rte_eth_reg_name {
> +	char name[RTE_ETH_REG_NAME_SIZE];
> +};
> +
>  /*
>   * Placeholder for accessing device registers
>   */
> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>  	uint32_t length; /**< Number of registers to fetch */
>  	uint32_t width; /**< Size of device register */
>  	uint32_t version; /**< Device version */
> +	/**
> +	 * Filter for target subset of registers.
> +	 * This field could affects register selection for data/length/names.
> +	 */
> +	const char *filter;
> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>  };
>  
>  /*
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index f1c658f49e80..9ef50c633ce3 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -6388,8 +6388,37 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
>  
>  int
>  rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
> +{
> +	struct rte_dev_reg_info reg_info = { 0 };
> +	int ret;
> +
> +	if (info == NULL) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +			"Cannot get ethdev port %u register info to NULL",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
> +	reg_info.length = info->length;
> +	reg_info.data = info->data;
> +
> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
> +	if (ret != 0)
> +		return ret;
> +
> +	info->length = reg_info.length;
> +	info->width = reg_info.width;
> +	info->version = reg_info.version;
> +	info->offset = reg_info.offset;
> +
> +	return 0;
> +}
> +
> +int
> +rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
>  {
>  	struct rte_eth_dev *dev;
> +	uint32_t i;
>  	int ret;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> @@ -6408,6 +6437,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>  
>  	rte_ethdev_trace_get_reg_info(port_id, info, ret);
>  
> +	/* Report the default names if drivers not report. */
> +	if (info->names != NULL && strlen(info->names[0].name) == 0)
> +		for (i = 0; i < info->length; i++)
> +			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
> +				"offset_%x", info->offset + i * info->width);

%x has no prefix "0x", may lead to confused.
How about use %u ?

Another question, if app don't zero names' memory, then its value is random, so it will not enter this logic.
Suggest memset item[0]'s name memory before invoke PMD ops.

>  	return ret;
>  }
>  
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index ed27360447a3..09e2d5fdb49b 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -5066,6 +5066,34 @@ __rte_experimental
>  int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
>  		struct rte_power_monitor_cond *pmc);
>  
> +/**
> + * Retrieve the filtered device registers (values and names) and
> + * register attributes (number of registers and register size)
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param info
> + *   Pointer to rte_dev_reg_info structure to fill in.
> + *   If info->filter is not NULL and the driver does not support names or
> + *   filter, return error. If info->filter is NULL, return info for all
> + *   registers (seen as filter none).
> + *   If info->data is NULL, the function fills in the width and length fields.
> + *   If non-NULL, ethdev considers there are enough spaces to store the
> + *   registers, and the values of registers whose name contains the filter
> + *   string are put into the buffer pointed at by the data field. Do the same
> + *   for the names of registers if info->names is not NULL. If drivers do not
> + *   report names, default names are given by ethdev.

It's a little hard to understand. Suggest use '-' for each field, just like rte_eth_remove_tx_callback

> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-EINVAL) if bad parameter.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - (-EIO) if device is removed.
> + *   - others depends on the specific operations implementation.
> + */
> +__rte_experimental
> +int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
> +
>  /**
>   * Retrieve device registers and register attributes (number of registers and
>   * register size)
> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
> index 17e4eac8a4cc..c41a64e404db 100644
> --- a/lib/ethdev/version.map
> +++ b/lib/ethdev/version.map
> @@ -325,6 +325,7 @@ EXPERIMENTAL {
>  	rte_flow_template_table_resizable;
>  	rte_flow_template_table_resize;
>  	rte_flow_template_table_resize_complete;
> +	rte_eth_dev_get_reg_info_ext;

should place with alphabetical order.

Thanks

>  };
>  
>  INTERNAL {
> 

^ permalink raw reply	[relevance 0%]

* [PATCH v4 1/7] ethdev: support report register names and filter
  @ 2024-02-26  3:07  8%   ` Jie Hai
  2024-02-26  8:01  0%     ` fengchengwen
  2024-02-29  9:52  3%     ` Thomas Monjalon
  0 siblings, 2 replies; 200+ results
From: Jie Hai @ 2024-02-26  3:07 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch adds "filter" and "names" fields to "rte_dev_reg_info"
structure. Names of registers in data fields can be reported and
the registers can be filtered by their names.

The new API rte_eth_dev_get_reg_info_ext() is added to support
reporting names and filtering by names. And the original API
rte_eth_dev_get_reg_info() does not use the name and filter fields.
A local variable is used in rte_eth_dev_get_reg_info for
compatibility. If the drivers does not report the names, set them
to "offset_XXX".

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 doc/guides/rel_notes/release_24_03.rst |  8 ++++++
 lib/ethdev/rte_dev_info.h              | 11 +++++++++
 lib/ethdev/rte_ethdev.c                | 34 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 28 +++++++++++++++++++++
 lib/ethdev/version.map                 |  1 +
 5 files changed, 82 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 32d0ad8cf6a7..fa46da427dca 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -132,6 +132,11 @@ New Features
     to support TLS v1.2, TLS v1.3 and DTLS v1.2.
   * Added PMD API to allow raw submission of instructions to CPT.
 
+  * **Added support for dumping registers with names and filter.**
+
+    * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
+      the registers by their names and get the information of registers(names,
+      values and other attributes).
 
 Removed Items
 -------------
@@ -197,6 +202,9 @@ ABI Changes
 
 * No ABI change that would break compatibility with 23.11.
 
+* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
+  structure for reporting names of registers and filtering them by names.
+
 
 Known Issues
 ------------
diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
index 67cf0ae52668..0ad4a43b9526 100644
--- a/lib/ethdev/rte_dev_info.h
+++ b/lib/ethdev/rte_dev_info.h
@@ -11,6 +11,11 @@ extern "C" {
 
 #include <stdint.h>
 
+#define RTE_ETH_REG_NAME_SIZE 128
+struct rte_eth_reg_name {
+	char name[RTE_ETH_REG_NAME_SIZE];
+};
+
 /*
  * Placeholder for accessing device registers
  */
@@ -20,6 +25,12 @@ struct rte_dev_reg_info {
 	uint32_t length; /**< Number of registers to fetch */
 	uint32_t width; /**< Size of device register */
 	uint32_t version; /**< Device version */
+	/**
+	 * Filter for target subset of registers.
+	 * This field could affects register selection for data/length/names.
+	 */
+	const char *filter;
+	struct rte_eth_reg_name *names; /**< Registers name saver */
 };
 
 /*
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f1c658f49e80..9ef50c633ce3 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6388,8 +6388,37 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
+{
+	struct rte_dev_reg_info reg_info = { 0 };
+	int ret;
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Cannot get ethdev port %u register info to NULL",
+			port_id);
+		return -EINVAL;
+	}
+
+	reg_info.length = info->length;
+	reg_info.data = info->data;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0)
+		return ret;
+
+	info->length = reg_info.length;
+	info->width = reg_info.width;
+	info->version = reg_info.version;
+	info->offset = reg_info.offset;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
 {
 	struct rte_eth_dev *dev;
+	uint32_t i;
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -6408,6 +6437,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 
 	rte_ethdev_trace_get_reg_info(port_id, info, ret);
 
+	/* Report the default names if drivers not report. */
+	if (info->names != NULL && strlen(info->names[0].name) == 0)
+		for (i = 0; i < info->length; i++)
+			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
+				"offset_%x", info->offset + i * info->width);
 	return ret;
 }
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index ed27360447a3..09e2d5fdb49b 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5066,6 +5066,34 @@ __rte_experimental
 int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 		struct rte_power_monitor_cond *pmc);
 
+/**
+ * Retrieve the filtered device registers (values and names) and
+ * register attributes (number of registers and register size)
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param info
+ *   Pointer to rte_dev_reg_info structure to fill in.
+ *   If info->filter is not NULL and the driver does not support names or
+ *   filter, return error. If info->filter is NULL, return info for all
+ *   registers (seen as filter none).
+ *   If info->data is NULL, the function fills in the width and length fields.
+ *   If non-NULL, ethdev considers there are enough spaces to store the
+ *   registers, and the values of registers whose name contains the filter
+ *   string are put into the buffer pointed at by the data field. Do the same
+ *   for the names of registers if info->names is not NULL. If drivers do not
+ *   report names, default names are given by ethdev.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EIO) if device is removed.
+ *   - others depends on the specific operations implementation.
+ */
+__rte_experimental
+int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
+
 /**
  * Retrieve device registers and register attributes (number of registers and
  * register size)
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 17e4eac8a4cc..c41a64e404db 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -325,6 +325,7 @@ EXPERIMENTAL {
 	rte_flow_template_table_resizable;
 	rte_flow_template_table_resize;
 	rte_flow_template_table_resize_complete;
+	rte_eth_dev_get_reg_info_ext;
 };
 
 INTERNAL {
-- 
2.30.0


^ permalink raw reply	[relevance 8%]

* [PATCH v5 27/39] mempool: use C11 alignas
  @ 2024-02-23 19:04  3%   ` Tyler Retzlaff
  0 siblings, 0 replies; 200+ results
From: Tyler Retzlaff @ 2024-02-23 19:04 UTC (permalink / raw)
  To: dev
  Cc: Andrew Rybchenko, Bruce Richardson, Chengwen Feng,
	Cristian Dumitrescu, David Christensen, David Hunt, Ferruh Yigit,
	Honnappa Nagarahalli, Jasvinder Singh, Jerin Jacob, Kevin Laatz,
	Konstantin Ananyev, Min Zhou, Ruifeng Wang, Sameh Gobriel,
	Stanislaw Kardach, Thomas Monjalon, Vladimir Medvedkin,
	Yipeng Wang, Tyler Retzlaff

The current location used for __rte_aligned(a) for alignment of types
and variables is not compatible with MSVC. There is only a single
location accepted by both toolchains.

For variables standard C11 offers alignas(a) supported by conformant
compilers i.e. both MSVC and GCC.

For types the standard offers no alignment facility that compatibly
interoperates with C and C++ but may be achieved by relocating the
placement of __rte_aligned(a) to the aforementioned location accepted
by all currently supported toolchains.

To allow alignment for both compilers do the following:

* Move __rte_aligned from the end of {struct,union} definitions to
  be between {struct,union} and tag.

  The placement between {struct,union} and the tag allows the desired
  alignment to be imparted on the type regardless of the toolchain being
  used for all of GCC, LLVM, MSVC compilers building both C and C++.

* Replace use of __rte_aligned(a) on variables/fields with alignas(a).

Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
Acked-by: Morten Brørup <mb@smartsharesystems.com>
---
 lib/mempool/rte_mempool.h | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/lib/mempool/rte_mempool.h b/lib/mempool/rte_mempool.h
index 6fa4d48..23fd5c8 100644
--- a/lib/mempool/rte_mempool.h
+++ b/lib/mempool/rte_mempool.h
@@ -34,6 +34,7 @@
  * user cache created with rte_mempool_cache_create().
  */
 
+#include <stdalign.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <inttypes.h>
@@ -66,7 +67,7 @@
  * captured since they can be calculated from other stats.
  * For example: put_cache_objs = put_objs - put_common_pool_objs.
  */
-struct rte_mempool_debug_stats {
+struct __rte_cache_aligned rte_mempool_debug_stats {
 	uint64_t put_bulk;             /**< Number of puts. */
 	uint64_t put_objs;             /**< Number of objects successfully put. */
 	uint64_t put_common_pool_bulk; /**< Number of bulks enqueued in common pool. */
@@ -80,13 +81,13 @@ struct rte_mempool_debug_stats {
 	uint64_t get_success_blks;     /**< Successful allocation number of contiguous blocks. */
 	uint64_t get_fail_blks;        /**< Failed allocation number of contiguous blocks. */
 	RTE_CACHE_GUARD;
-} __rte_cache_aligned;
+};
 #endif
 
 /**
  * A structure that stores a per-core object cache.
  */
-struct rte_mempool_cache {
+struct __rte_cache_aligned rte_mempool_cache {
 	uint32_t size;	      /**< Size of the cache */
 	uint32_t flushthresh; /**< Threshold before we flush excess elements */
 	uint32_t len;	      /**< Current cache count */
@@ -109,8 +110,8 @@ struct rte_mempool_cache {
 	 * Cache is allocated to this size to allow it to overflow in certain
 	 * cases to avoid needless emptying of cache.
 	 */
-	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2] __rte_cache_aligned;
-} __rte_cache_aligned;
+	alignas(RTE_CACHE_LINE_SIZE) void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2];
+};
 
 /**
  * A structure that stores the size of mempool elements.
@@ -218,15 +219,15 @@ struct rte_mempool_memhdr {
  * The structure is cache-line aligned to avoid ABI breakages in
  * a number of cases when something small is added.
  */
-struct rte_mempool_info {
+struct __rte_cache_aligned rte_mempool_info {
 	/** Number of objects in the contiguous block */
 	unsigned int contig_block_size;
-} __rte_cache_aligned;
+};
 
 /**
  * The RTE mempool structure.
  */
-struct rte_mempool {
+struct __rte_cache_aligned rte_mempool {
 	char name[RTE_MEMPOOL_NAMESIZE]; /**< Name of mempool. */
 	union {
 		void *pool_data;         /**< Ring or pool to store objects. */
@@ -268,7 +269,7 @@ struct rte_mempool {
 	 */
 	struct rte_mempool_debug_stats stats[RTE_MAX_LCORE + 1];
 #endif
-}  __rte_cache_aligned;
+};
 
 /** Spreading among memory channels not required. */
 #define RTE_MEMPOOL_F_NO_SPREAD		0x0001
@@ -688,7 +689,7 @@ typedef int (*rte_mempool_get_info_t)(const struct rte_mempool *mp,
 
 
 /** Structure defining mempool operations structure */
-struct rte_mempool_ops {
+struct __rte_cache_aligned rte_mempool_ops {
 	char name[RTE_MEMPOOL_OPS_NAMESIZE]; /**< Name of mempool ops struct. */
 	rte_mempool_alloc_t alloc;       /**< Allocate private data. */
 	rte_mempool_free_t free;         /**< Free the external pool. */
@@ -713,7 +714,7 @@ struct rte_mempool_ops {
 	 * Dequeue a number of contiguous object blocks.
 	 */
 	rte_mempool_dequeue_contig_blocks_t dequeue_contig_blocks;
-} __rte_cache_aligned;
+};
 
 #define RTE_MEMPOOL_MAX_OPS_IDX 16  /**< Max registered ops structs */
 
@@ -726,14 +727,14 @@ struct rte_mempool_ops {
  * any function pointers stored directly in the mempool struct would not be.
  * This results in us simply having "ops_index" in the mempool struct.
  */
-struct rte_mempool_ops_table {
+struct __rte_cache_aligned rte_mempool_ops_table {
 	rte_spinlock_t sl;     /**< Spinlock for add/delete. */
 	uint32_t num_ops;      /**< Number of used ops structs in the table. */
 	/**
 	 * Storage for all possible ops structs.
 	 */
 	struct rte_mempool_ops ops[RTE_MEMPOOL_MAX_OPS_IDX];
-} __rte_cache_aligned;
+};
 
 /** Array of registered ops structs. */
 extern struct rte_mempool_ops_table rte_mempool_ops_table;
-- 
1.8.3.1


^ permalink raw reply	[relevance 3%]

* [PATCH v2 1/4] ethdev: add function to check representor port
  @ 2024-02-23  2:42  2%   ` Chaoyong He
  0 siblings, 0 replies; 200+ results
From: Chaoyong He @ 2024-02-23  2:42 UTC (permalink / raw)
  To: dev; +Cc: oss-drivers, Long Wu, Chaoyong He, Peng Zhang

From: Long Wu <long.wu@corigine.com>

Add a function to check if a device is representor port, also
modified the related codes for PMDs.

Signed-off-by: Long Wu <long.wu@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Peng Zhang <peng.zhang@corigine.com>
---
 doc/guides/rel_notes/release_24_03.rst     |  3 +++
 drivers/net/bnxt/bnxt.h                    |  3 ---
 drivers/net/bnxt/bnxt_ethdev.c             |  4 ++--
 drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c | 12 ++++++------
 drivers/net/bnxt/tf_ulp/bnxt_ulp.c         |  4 ++--
 drivers/net/bnxt/tf_ulp/ulp_def_rules.c    |  4 ++--
 drivers/net/cpfl/cpfl_representor.c        |  2 +-
 drivers/net/enic/enic.h                    |  5 -----
 drivers/net/enic/enic_ethdev.c             |  2 +-
 drivers/net/enic/enic_fm_flow.c            | 20 ++++++++++----------
 drivers/net/enic/enic_main.c               |  4 ++--
 drivers/net/i40e/i40e_ethdev.c             |  2 +-
 drivers/net/ice/ice_dcf_ethdev.c           |  2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c           |  2 +-
 drivers/net/nfp/flower/nfp_flower_flow.c   |  2 +-
 drivers/net/nfp/nfp_mtr.c                  |  2 +-
 drivers/net/nfp/nfp_net_common.c           |  4 ++--
 drivers/net/nfp/nfp_net_flow.c             |  2 +-
 lib/ethdev/ethdev_driver.h                 | 17 +++++++++++++++++
 19 files changed, 54 insertions(+), 42 deletions(-)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 879bb4944c..8178417b98 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -185,6 +185,9 @@ API Changes
 * ethdev: Renamed structure ``rte_flow_action_modify_data`` to be
   ``rte_flow_field_data`` for more generic usage.
 
+* ethdev: Add new function ``rte_eth_dev_is_repr()`` to check if a device is
+  representor port.
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index fcf2b8be97..82036a16a1 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -1204,9 +1204,6 @@ extern const struct rte_flow_ops bnxt_flow_meter_ops;
 	} \
 } while (0)
 
-#define	BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)	\
-		((eth_dev)->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
-
 extern int bnxt_logtype_driver;
 #define RTE_LOGTYPE_BNXT bnxt_logtype_driver
 #define PMD_DRV_LOG_RAW(level, fmt, args...) \
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index f8d83662f4..825e9c1941 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -3525,7 +3525,7 @@ bnxt_flow_ops_get_op(struct rte_eth_dev *dev,
 	if (!bp)
 		return -EIO;
 
-	if (BNXT_ETH_DEV_IS_REPRESENTOR(dev)) {
+	if (rte_eth_dev_is_repr(dev)) {
 		struct bnxt_representor *vfr = dev->data->dev_private;
 		bp = vfr->parent_dev->data->dev_private;
 		/* parent is deleted while children are still valid */
@@ -6781,7 +6781,7 @@ static int bnxt_pci_remove(struct rte_pci_device *pci_dev)
 
 	PMD_DRV_LOG(DEBUG, "BNXT Port:%d pci remove\n", eth_dev->data->port_id);
 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		if (eth_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
+		if (rte_eth_dev_is_repr(eth_dev))
 			return rte_eth_dev_destroy(eth_dev,
 						   bnxt_representor_uninit);
 		else
diff --git a/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c b/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c
index 239191e14e..96d61c3ed2 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_tf_pmd_shim.c
@@ -202,7 +202,7 @@ bnxt_pmd_get_svif(uint16_t port_id, bool func_svif,
 	struct bnxt *bp;
 
 	eth_dev = &rte_eth_devices[port_id];
-	if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
+	if (rte_eth_dev_is_repr(eth_dev)) {
 		struct bnxt_representor *vfr = eth_dev->data->dev_private;
 		if (!vfr)
 			return 0;
@@ -260,7 +260,7 @@ bnxt_pmd_get_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type)
 	struct bnxt *bp;
 
 	eth_dev = &rte_eth_devices[port];
-	if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
+	if (rte_eth_dev_is_repr(eth_dev)) {
 		struct bnxt_representor *vfr = eth_dev->data->dev_private;
 		if (!vfr)
 			return 0;
@@ -285,7 +285,7 @@ bnxt_pmd_get_fw_func_id(uint16_t port, enum bnxt_ulp_intf_type type)
 	struct bnxt *bp;
 
 	eth_dev = &rte_eth_devices[port];
-	if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
+	if (rte_eth_dev_is_repr(eth_dev)) {
 		struct bnxt_representor *vfr = eth_dev->data->dev_private;
 		if (!vfr)
 			return 0;
@@ -308,7 +308,7 @@ bnxt_pmd_get_interface_type(uint16_t port)
 	struct bnxt *bp;
 
 	eth_dev = &rte_eth_devices[port];
-	if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev))
+	if (rte_eth_dev_is_repr(eth_dev))
 		return BNXT_ULP_INTF_TYPE_VF_REP;
 
 	bp = eth_dev->data->dev_private;
@@ -330,7 +330,7 @@ bnxt_pmd_get_phy_port_id(uint16_t port_id)
 	struct bnxt *bp;
 
 	eth_dev = &rte_eth_devices[port_id];
-	if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
+	if (rte_eth_dev_is_repr(eth_dev)) {
 		vfr = eth_dev->data->dev_private;
 		if (!vfr)
 			return 0;
@@ -350,7 +350,7 @@ bnxt_pmd_get_parif(uint16_t port_id, enum bnxt_ulp_intf_type type)
 	struct bnxt *bp;
 
 	eth_dev = &rte_eth_devices[port_id];
-	if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
+	if (rte_eth_dev_is_repr(eth_dev)) {
 		struct bnxt_representor *vfr = eth_dev->data->dev_private;
 		if (!vfr)
 			return 0;
diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
index 274e935a1f..33028c470f 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp.c
@@ -1559,7 +1559,7 @@ bnxt_ulp_destroy_vfr_default_rules(struct bnxt *bp, bool global)
 	struct rte_eth_dev *vfr_eth_dev;
 	struct bnxt_representor *vfr_bp;
 
-	if (!BNXT_TRUFLOW_EN(bp) || BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev))
+	if (!BNXT_TRUFLOW_EN(bp) || rte_eth_dev_is_repr(bp->eth_dev))
 		return;
 
 	if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
@@ -2316,7 +2316,7 @@ bnxt_ulp_eth_dev_ptr2_cntxt_get(struct rte_eth_dev	*dev)
 {
 	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
 
-	if (BNXT_ETH_DEV_IS_REPRESENTOR(dev)) {
+	if (rte_eth_dev_is_repr(dev)) {
 		struct bnxt_representor *vfr = dev->data->dev_private;
 
 		bp = vfr->parent_dev->data->dev_private;
diff --git a/drivers/net/bnxt/tf_ulp/ulp_def_rules.c b/drivers/net/bnxt/tf_ulp/ulp_def_rules.c
index fe1f65deb9..8237dbd294 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_def_rules.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_def_rules.c
@@ -449,7 +449,7 @@ bnxt_ulp_destroy_df_rules(struct bnxt *bp, bool global)
 	uint16_t port_id;
 
 	if (!BNXT_TRUFLOW_EN(bp) ||
-	    BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev))
+	    rte_eth_dev_is_repr(bp->eth_dev))
 		return;
 
 	if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
@@ -514,7 +514,7 @@ bnxt_ulp_create_df_rules(struct bnxt *bp)
 	int rc = 0;
 
 	if (!BNXT_TRUFLOW_EN(bp) ||
-	    BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev) || !bp->ulp_ctx)
+	    rte_eth_dev_is_repr(bp->eth_dev) || !bp->ulp_ctx)
 		return 0;
 
 	port_id = bp->eth_dev->data->port_id;
diff --git a/drivers/net/cpfl/cpfl_representor.c b/drivers/net/cpfl/cpfl_representor.c
index e2ed9eda04..60b72b5ec1 100644
--- a/drivers/net/cpfl/cpfl_representor.c
+++ b/drivers/net/cpfl/cpfl_representor.c
@@ -339,7 +339,7 @@ cpfl_repr_link_update(struct rte_eth_dev *ethdev,
 	struct cpfl_vport_id vi;
 	int ret;
 
-	if (!(ethdev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)) {
+	if (!rte_eth_dev_is_repr(ethdev)) {
 		PMD_INIT_LOG(ERR, "This ethdev is not representor.");
 		return -EINVAL;
 	}
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 78778704f2..f46903ea9e 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -233,11 +233,6 @@ struct enic_vf_representor {
 #define VF_ENIC_TO_VF_REP(vf_enic) \
 	container_of(vf_enic, struct enic_vf_representor, enic)
 
-static inline int enic_is_vf_rep(struct enic *enic)
-{
-	return !!(enic->rte_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR);
-}
-
 /* Compute ethdev's max packet size from MTU */
 static inline uint32_t enic_mtu_to_max_rx_pktlen(uint32_t mtu)
 {
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 7e040c36c4..cad8db2f6f 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -1386,7 +1386,7 @@ static int eth_enic_pci_remove(struct rte_pci_device *pci_dev)
 	ethdev = rte_eth_dev_allocated(pci_dev->device.name);
 	if (!ethdev)
 		return -ENODEV;
-	if (ethdev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
+	if (rte_eth_dev_is_repr(ethdev))
 		return rte_eth_dev_destroy(ethdev, enic_vf_representor_uninit);
 	else
 		return rte_eth_dev_destroy(ethdev, eth_enic_dev_uninit);
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 90027dc676..8988148454 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -1535,14 +1535,14 @@ vf_egress_port_id_action(struct enic_flowman *fm,
 	ENICPMD_FUNC_TRACE();
 	src_enic = fm->user_enic;
 	dst_enic = pmd_priv(dst_dev);
-	if (!(src_enic->rte_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)) {
+	if (!rte_eth_dev_is_repr(src_enic->rte_dev)) {
 		return rte_flow_error_set(error, EINVAL,
 			RTE_FLOW_ERROR_TYPE_ACTION,
 			NULL, "source port is not VF representor");
 	}
 
 	/* VF -> PF uplink. dst is not VF representor */
-	if (!(dst_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)) {
+	if (!rte_eth_dev_is_repr(dst_dev)) {
 		/* PF is the VF's PF? Then nothing to do */
 		vf = VF_ENIC_TO_VF_REP(src_enic);
 		if (vf->pf == dst_enic) {
@@ -1954,7 +1954,7 @@ enic_fm_copy_action(struct enic_flowman *fm,
 	if (!(overlap & (FATE | PASSTHRU | COUNT | PORT_ID)))
 		goto unsupported;
 	/* Egress from VF: need implicit WQ match */
-	if (enic_is_vf_rep(enic) && !ingress) {
+	if (rte_eth_dev_is_repr(enic->rte_dev) && !ingress) {
 		fmt->ftm_data.fk_wq_id = 0;
 		fmt->ftm_mask.fk_wq_id = 0xffff;
 		fmt->ftm_data.fk_wq_vnic = enic->fm_vnic_handle;
@@ -3226,7 +3226,7 @@ enic_fm_init(struct enic *enic)
 		return 0;
 	ENICPMD_FUNC_TRACE();
 	/* Get vnic handle and save for port-id action */
-	if (enic_is_vf_rep(enic))
+	if (rte_eth_dev_is_repr(enic->rte_dev))
 		addr = &VF_ENIC_TO_VF_REP(enic)->bdf;
 	else
 		addr = &RTE_ETH_DEV_TO_PCI(enic->rte_dev)->addr;
@@ -3240,7 +3240,7 @@ enic_fm_init(struct enic *enic)
 	enic->fm_vnic_uif = vnic_dev_uif(enic->vdev);
 	ENICPMD_LOG(DEBUG, "uif %u", enic->fm_vnic_uif);
 	/* Nothing else to do for representor. It will share the PF flowman */
-	if (enic_is_vf_rep(enic))
+	if (rte_eth_dev_is_repr(enic->rte_dev))
 		return 0;
 	fm = calloc(1, sizeof(*fm));
 	if (fm == NULL) {
@@ -3321,7 +3321,7 @@ enic_fm_destroy(struct enic *enic)
 	struct enic_fm_fet *fet;
 
 	ENICPMD_FUNC_TRACE();
-	if (enic_is_vf_rep(enic)) {
+	if (rte_eth_dev_is_repr(enic->rte_dev)) {
 		delete_rep_flows(enic);
 		return;
 	}
@@ -3358,7 +3358,7 @@ enic_fm_allocate_switch_domain(struct enic *pf)
 	int ret;
 
 	ENICPMD_FUNC_TRACE();
-	if (enic_is_vf_rep(pf))
+	if (rte_eth_dev_is_repr(pf->rte_dev))
 		return -EINVAL;
 	cur = pf;
 	cur_a = &RTE_ETH_DEV_TO_PCI(cur->rte_dev)->addr;
@@ -3367,7 +3367,7 @@ enic_fm_allocate_switch_domain(struct enic *pf)
 		dev = &rte_eth_devices[pid];
 		if (!dev_is_enic(dev))
 			continue;
-		if (dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
+		if (rte_eth_dev_is_repr(dev))
 			continue;
 		if (dev == cur->rte_dev)
 			continue;
@@ -3597,7 +3597,7 @@ delete_rep_flows(struct enic *enic)
 	struct rte_eth_dev *dev;
 	uint32_t i;
 
-	RTE_ASSERT(enic_is_vf_rep(enic));
+	RTE_ASSERT(rte_eth_dev_is_repr(enic->rte_dev));
 	vf = VF_ENIC_TO_VF_REP(enic);
 	dev = vf->pf->rte_dev;
 	for (i = 0; i < ARRAY_SIZE(vf->vf2rep_flow); i++) {
@@ -3617,7 +3617,7 @@ begin_fm(struct enic *enic)
 	struct enic_flowman *fm;
 
 	/* Representor uses PF flowman */
-	if (enic_is_vf_rep(enic)) {
+	if (rte_eth_dev_is_repr(enic->rte_dev)) {
 		vf = VF_ENIC_TO_VF_REP(enic);
 		fm = vf->pf->fm;
 	} else {
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index a6aaa760ca..2f681315b6 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -824,7 +824,7 @@ int enic_alloc_rq(struct enic *enic, uint16_t queue_idx,
 	 * Representor uses a reserved PF queue. Translate representor
 	 * queue number to PF queue number.
 	 */
-	if (enic_is_vf_rep(enic)) {
+	if (rte_eth_dev_is_repr(enic->rte_dev)) {
 		RTE_ASSERT(queue_idx == 0);
 		vf = VF_ENIC_TO_VF_REP(enic);
 		sop_queue_idx = vf->pf_rq_sop_idx;
@@ -1053,7 +1053,7 @@ int enic_alloc_wq(struct enic *enic, uint16_t queue_idx,
 	 * Representor uses a reserved PF queue. Translate representor
 	 * queue number to PF queue number.
 	 */
-	if (enic_is_vf_rep(enic)) {
+	if (rte_eth_dev_is_repr(enic->rte_dev)) {
 		RTE_ASSERT(queue_idx == 0);
 		vf = VF_ENIC_TO_VF_REP(enic);
 		queue_idx = vf->pf_wq_idx;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 4d21341382..ddbc2962bc 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -706,7 +706,7 @@ static int eth_i40e_pci_remove(struct rte_pci_device *pci_dev)
 	if (!ethdev)
 		return 0;
 
-	if (ethdev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
+	if (rte_eth_dev_is_repr(ethdev))
 		return rte_eth_dev_pci_generic_remove(pci_dev,
 					i40e_vf_representor_uninit);
 	else
diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c
index bebf356f4d..d58ec9d907 100644
--- a/drivers/net/ice/ice_dcf_ethdev.c
+++ b/drivers/net/ice/ice_dcf_ethdev.c
@@ -2131,7 +2131,7 @@ eth_ice_dcf_pci_remove(struct rte_pci_device *pci_dev)
 	if (!eth_dev)
 		return 0;
 
-	if (eth_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
+	if (rte_eth_dev_is_repr(eth_dev))
 		return rte_eth_dev_pci_generic_remove(pci_dev,
 						      ice_dcf_vf_repr_uninit);
 	else
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 0cd3d0b105..c61c52b296 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1842,7 +1842,7 @@ static int eth_ixgbe_pci_remove(struct rte_pci_device *pci_dev)
 	if (!ethdev)
 		return 0;
 
-	if (ethdev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
+	if (rte_eth_dev_is_repr(ethdev))
 		return rte_eth_dev_pci_generic_remove(pci_dev,
 					ixgbe_vf_representor_uninit);
 	else
diff --git a/drivers/net/nfp/flower/nfp_flower_flow.c b/drivers/net/nfp/flower/nfp_flower_flow.c
index e26be30d18..501a8d87bd 100644
--- a/drivers/net/nfp/flower/nfp_flower_flow.c
+++ b/drivers/net/nfp/flower/nfp_flower_flow.c
@@ -4321,7 +4321,7 @@ int
 nfp_flow_ops_get(struct rte_eth_dev *dev,
 		const struct rte_flow_ops **ops)
 {
-	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) == 0) {
+	if (!rte_eth_dev_is_repr(dev)) {
 		*ops = NULL;
 		PMD_DRV_LOG(ERR, "Port is not a representor.");
 		return -EINVAL;
diff --git a/drivers/net/nfp/nfp_mtr.c b/drivers/net/nfp/nfp_mtr.c
index 255977ec22..6abc6dc9bc 100644
--- a/drivers/net/nfp/nfp_mtr.c
+++ b/drivers/net/nfp/nfp_mtr.c
@@ -1066,7 +1066,7 @@ static const struct rte_mtr_ops nfp_mtr_ops = {
 int
 nfp_net_mtr_ops_get(struct rte_eth_dev *dev, void *arg)
 {
-	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) == 0) {
+	if (!rte_eth_dev_is_repr(dev)) {
 		PMD_DRV_LOG(ERR, "Port is not a representor");
 		return -EINVAL;
 	}
diff --git a/drivers/net/nfp/nfp_net_common.c b/drivers/net/nfp/nfp_net_common.c
index 99c319eb2d..0ee2811926 100644
--- a/drivers/net/nfp/nfp_net_common.c
+++ b/drivers/net/nfp/nfp_net_common.c
@@ -241,7 +241,7 @@ nfp_net_get_hw(const struct rte_eth_dev *dev)
 {
 	struct nfp_net_hw *hw;
 
-	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0) {
+	if (rte_eth_dev_is_repr(dev)) {
 		struct nfp_flower_representor *repr;
 		repr = dev->data->dev_private;
 		hw = repr->app_fw_flower->pf_hw;
@@ -2143,7 +2143,7 @@ nfp_net_firmware_version_get(struct rte_eth_dev *dev,
 
 	hw = nfp_net_get_hw(dev);
 
-	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0) {
+	if (rte_eth_dev_is_repr(dev)) {
 		snprintf(vnic_version, FW_VER_LEN, "%d.%d.%d.%d",
 			hw->ver.extend, hw->ver.class,
 			hw->ver.major, hw->ver.minor);
diff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c
index 98e8499756..3b33f3b6e9 100644
--- a/drivers/net/nfp/nfp_net_flow.c
+++ b/drivers/net/nfp/nfp_net_flow.c
@@ -932,7 +932,7 @@ nfp_net_flow_ops_get(struct rte_eth_dev *dev,
 {
 	struct nfp_net_hw *hw;
 
-	if ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0) {
+	if (rte_eth_dev_is_repr(dev)) {
 		*ops = NULL;
 		PMD_DRV_LOG(ERR, "Port is a representor.");
 		return -EINVAL;
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index 0e4c1f0743..f46c102558 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -2120,6 +2120,23 @@ struct rte_eth_fdir_conf {
 	struct rte_eth_fdir_flex_conf flex_conf;
 };
 
+/**
+ * @internal
+ * Check if the ethdev is a representor port.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ *
+ * @return
+ *  false the ethdev is not a representor port.
+ *  true  the ethdev is a representor port.
+ */
+static inline bool
+rte_eth_dev_is_repr(const struct rte_eth_dev *dev)
+{
+	return ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0);
+}
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.39.1


^ permalink raw reply	[relevance 2%]

* Re: [PATCH v3 10/11] eventdev: clarify docs on event object fields and op types
  2024-02-20 17:39  3%         ` Bruce Richardson
@ 2024-02-21  9:31  0%           ` Jerin Jacob
  0 siblings, 0 replies; 200+ results
From: Jerin Jacob @ 2024-02-21  9:31 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, jerinj, mattias.ronnblom, abdullah.sevincer, sachin.saxena,
	hemant.agrawal, pbhagavatula, pravin.pathak

On Tue, Feb 20, 2024 at 11:09 PM Bruce Richardson
<bruce.richardson@intel.com> wrote:
>
> On Fri, Feb 09, 2024 at 02:44:04PM +0530, Jerin Jacob wrote:
> > On Fri, Feb 2, 2024 at 6:11 PM Bruce Richardson
> > <bruce.richardson@intel.com> wrote:
> > >
> > > Clarify the meaning of the NEW, FORWARD and RELEASE event types.
> > > For the fields in "rte_event" struct, enhance the comments on each to
> > > clarify the field's use, and whether it is preserved between enqueue and
> > > dequeue, and it's role, if any, in scheduling.
> > >
> > > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > > ---
> > > V3: updates following review
> > > ---
> > >  lib/eventdev/rte_eventdev.h | 161 +++++++++++++++++++++++++-----------
> > >  1 file changed, 111 insertions(+), 50 deletions(-)
> > >
> > > diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h
> > > index 8d72765ae7..58219e027e 100644
> > > --- a/lib/eventdev/rte_eventdev.h
> > > +++ b/lib/eventdev/rte_eventdev.h
> > > @@ -1463,47 +1463,54 @@ struct rte_event_vector {
> > >
> > >  /* Event enqueue operations */
> > >  #define RTE_EVENT_OP_NEW                0
> > > -/**< The event producers use this operation to inject a new event to the
> > > - * event device.
> > > +/**< The @ref rte_event.op field must be set to this operation type to inject a new event,
> > > + * i.e. one not previously dequeued, into the event device, to be scheduled
> > > + * for processing.
> > >   */
> > >  #define RTE_EVENT_OP_FORWARD            1
> > > -/**< The CPU use this operation to forward the event to different event queue or
> > > - * change to new application specific flow or schedule type to enable
> > > - * pipelining.
> > > +/**< The application must set the @ref rte_event.op field to this operation type to return a
> > > + * previously dequeued event to the event device to be scheduled for further processing.
> > >   *
> > > - * This operation must only be enqueued to the same port that the
> > > + * This event *must* be enqueued to the same port that the
> > >   * event to be forwarded was dequeued from.
> > > + *
> > > + * The event's fields, including (but not limited to) flow_id, scheduling type,
> > > + * destination queue, and event payload e.g. mbuf pointer, may all be updated as
> > > + * desired by the application, but the @ref rte_event.impl_opaque field must
> > > + * be kept to the same value as was present when the event was dequeued.
> > >   */
> > >  #define RTE_EVENT_OP_RELEASE            2
> > >  /**< Release the flow context associated with the schedule type.
> > >   *
> > > - * If current flow's scheduler type method is *RTE_SCHED_TYPE_ATOMIC*
> > > - * then this function hints the scheduler that the user has completed critical
> > > - * section processing in the current atomic context.
> > > - * The scheduler is now allowed to schedule events from the same flow from
> > > - * an event queue to another port. However, the context may be still held
> > > - * until the next rte_event_dequeue_burst() call, this call allows but does not
> > > - * force the scheduler to release the context early.
> > > - *
> > > - * Early atomic context release may increase parallelism and thus system
> > > + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_ATOMIC
> > > + * then this operation type hints the scheduler that the user has completed critical
> > > + * section processing for this event in the current atomic context, and that the
> > > + * scheduler may unlock any atomic locks held for this event.
> > > + * If this is the last event from an atomic flow, i.e. all flow locks are released,
> >
> >
> > Similar comment as other email
> > [Jerin] When there are multiple atomic events dequeue from @ref
> > rte_event_dequeue_burst()
> > for the same event queue, and it has same flow id then the lock is ....
> >
> > [Mattias]
> > Yes, or maybe describing the whole lock/unlock state.
> >
> > "The conceptual per-queue-per-flow lock is in a locked state as long
> > (and only as long) as one or more events pertaining to that flow were
> > scheduled to the port in question, but are not yet released."
> >
> > Maybe it needs to be more meaty, describing what released means. I don't
> > have the full context of the documentation in my head when I'm writing this.
> >
>
> Will take a look to reword a bit
>
> >
> > > + * the scheduler is now allowed to schedule events from that flow from to another port.
> > > + * However, the atomic locks may be still held until the next rte_event_dequeue_burst()
> > > + * call; enqueuing an event with opt type @ref RTE_EVENT_OP_RELEASE allows,
> >
> > Is ";" intended?
> >
> > > + * but does not force, the scheduler to release the atomic locks early.
> >
> > instead of "not force", can use the term _hint_ the driver and reword.
>
> Ok.
> >
> > > + *
> > > + * Early atomic lock release may increase parallelism and thus system
> > >   * performance, but the user needs to design carefully the split into critical
> > >   * vs non-critical sections.
> > >   *
> > > - * If current flow's scheduler type method is *RTE_SCHED_TYPE_ORDERED*
> > > - * then this function hints the scheduler that the user has done all that need
> > > - * to maintain event order in the current ordered context.
> > > - * The scheduler is allowed to release the ordered context of this port and
> > > - * avoid reordering any following enqueues.
> > > - *
> > > - * Early ordered context release may increase parallelism and thus system
> > > - * performance.
> > > + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_ORDERED
> > > + * then this operation type informs the scheduler that the current event has
> > > + * completed processing and will not be returned to the scheduler, i.e.
> > > + * it has been dropped, and so the reordering context for that event
> > > + * should be considered filled.
> > >   *
> > > - * If current flow's scheduler type method is *RTE_SCHED_TYPE_PARALLEL*
> > > - * or no scheduling context is held then this function may be an NOOP,
> > > - * depending on the implementation.
> > > + * Events with this operation type must only be enqueued to the same port that the
> > > + * event to be released was dequeued from. The @ref rte_event.impl_opaque
> > > + * field in the release event must have the same value as that in the original dequeued event.
> > >   *
> > > - * This operation must only be enqueued to the same port that the
> > > - * event to be released was dequeued from.
> > > + * If a dequeued event is re-enqueued with operation type of @ref RTE_EVENT_OP_RELEASE,
> > > + * then any subsequent enqueue of that event - or a copy of it - must be done as event of type
> > > + * @ref RTE_EVENT_OP_NEW, not @ref RTE_EVENT_OP_FORWARD. This is because any context for
> > > + * the originally dequeued event, i.e. atomic locks, or reorder buffer entries, will have
> > > + * been removed or invalidated by the release operation.
> > >   */
> > >
> > >  /**
> > > @@ -1517,56 +1524,110 @@ struct rte_event {
> > >                 /** Event attributes for dequeue or enqueue operation */
> > >                 struct {
> > >                         uint32_t flow_id:20;
> > > -                       /**< Targeted flow identifier for the enqueue and
> > > -                        * dequeue operation.
> > > -                        * The value must be in the range of
> > > -                        * [0, nb_event_queue_flows - 1] which
> > > -                        * previously supplied to rte_event_dev_configure().
> > > +                       /**< Target flow identifier for the enqueue and dequeue operation.
> > > +                        *
> > > +                        * For @ref RTE_SCHED_TYPE_ATOMIC, this field is used to identify a
> > > +                        * flow for atomicity within a queue & priority level, such that events
> > > +                        * from each individual flow will only be scheduled to one port at a time.
> > > +                        *
> > > +                        * This field is preserved between enqueue and dequeue when
> > > +                        * a device reports the @ref RTE_EVENT_DEV_CAP_CARRY_FLOW_ID
> > > +                        * capability. Otherwise the value is implementation dependent
> > > +                        * on dequeue.
> > >                          */
> > >                         uint32_t sub_event_type:8;
> > >                         /**< Sub-event types based on the event source.
> > > +                        *
> > > +                        * This field is preserved between enqueue and dequeue.
> > > +                        * This field is for application or event adapter use,
> > > +                        * and is not considered in scheduling decisions.
> >
> >
> > cnxk driver is considering this for scheduling decision to
> > differentiate the producer i.e event adapters.
> > If other drivers are not then we can change the language around it is
> > implementation defined.
> >
> How does the event type influence the scheduling decision? I can drop the

For cnxk, From HW POV, the flow ID is 32 bit which is divided between
flow_id(20 bit), sub event type(8bit) and
event type(4bit)

> last line here

Yes. Please


 > but it seems strange to me that the type of event could affect
> things. I would have thought that with the eventdev API only the queue,
> flow id, and priority would be factors in scheduling?

>
> >
> > > +                        *
> > >                          * @see RTE_EVENT_TYPE_CPU
> > >                          */
> > >                         uint32_t event_type:4;
> > > -                       /**< Event type to classify the event source.
> > > -                        * @see RTE_EVENT_TYPE_ETHDEV, (RTE_EVENT_TYPE_*)
> > > +                       /**< Event type to classify the event source. (RTE_EVENT_TYPE_*)
> > > +                        *
> > > +                        * This field is preserved between enqueue and dequeue
> > > +                        * This field is for application or event adapter use,
> > > +                        * and is not considered in scheduling decisions.
> >
> >
> > cnxk driver is considering this for scheduling decision to
> > differentiate the producer i.e event adapters.
> > If other drivers are not then we can change the language around it is
> > implementation defined.
> >
> > >                          */
> > >                         uint8_t op:2;
> > > -                       /**< The type of event enqueue operation - new/forward/
> > > -                        * etc.This field is not preserved across an instance
> > > -                        * and is undefined on dequeue.
> > > -                        * @see RTE_EVENT_OP_NEW, (RTE_EVENT_OP_*)
> > > +                       /**< The type of event enqueue operation - new/forward/ etc.
> > > +                        *
> > > +                        * This field is *not* preserved across an instance
> > > +                        * and is implementation dependent on dequeue.
> > > +                        *
> > > +                        * @see RTE_EVENT_OP_NEW
> > > +                        * @see RTE_EVENT_OP_FORWARD
> > > +                        * @see RTE_EVENT_OP_RELEASE
> > >                          */
> > >                         uint8_t rsvd:4;
> > > -                       /**< Reserved for future use */
> > > +                       /**< Reserved for future use.
> > > +                        *
> > > +                        * Should be set to zero on enqueue.
> >
> > I am worried about some application explicitly start setting this to
> > zero on every enqueue.
> > Instead, can we say application should not touch the field, Since every eventdev
> > operations starts with dequeue() driver can fill to the correct value.
> >
>
> I'll set this to zero on "NEW", or untouched on FORWARD/RELEASE.

OK

> If we don't state that it should be zeroed on NEW or untouched
> otherwise we cannot use the space in future without ABI break.
>
> > > +                        */
> > >                         uint8_t sched_type:2;
> > >                         /**< Scheduler synchronization type (RTE_SCHED_TYPE_*)
> > >                          * associated with flow id on a given event queue
> > >                          * for the enqueue and dequeue operation.
> > > +                        *
> > > +                        * This field is used to determine the scheduling type
> > > +                        * for events sent to queues where @ref RTE_EVENT_QUEUE_CFG_ALL_TYPES
> > > +                        * is configured.
> > > +                        * For queues where only a single scheduling type is available,
> > > +                        * this field must be set to match the configured scheduling type.
> > > +                        *
> > > +                        * This field is preserved between enqueue and dequeue.
> > > +                        *
> > > +                        * @see RTE_SCHED_TYPE_ORDERED
> > > +                        * @see RTE_SCHED_TYPE_ATOMIC
> > > +                        * @see RTE_SCHED_TYPE_PARALLEL
> > >                          */
> > >                         uint8_t queue_id;
> > >                         /**< Targeted event queue identifier for the enqueue or
> > >                          * dequeue operation.
> > > -                        * The value must be in the range of
> > > -                        * [0, nb_event_queues - 1] which previously supplied to
> > > -                        * rte_event_dev_configure().
> > > +                        * The value must be less than @ref rte_event_dev_config.nb_event_queues
> > > +                        * which was previously supplied to rte_event_dev_configure().
> >
> > Some reason, similar text got removed for flow_id. Please add the same.
> >
>
> That was deliberate based on discussion on V2. See:
>
> http://inbox.dpdk.org/dev/Zby3nb4NGs8T5odL@bricha3-MOBL.ger.corp.intel.com/
>
> and wider thread discussion starting here:
>
> http://inbox.dpdk.org/dev/ZbvOtAEpzja0gu7b@bricha3-MOBL.ger.corp.intel.com/
>
> Basically, the comment is wrong based on what the code does now. No event
> adapters or apps are limiting the flow-id, and nothing seems broken, so we
> can remove the comment.

OK

>

^ permalink raw reply	[relevance 0%]

* Re: [DPDK/ethdev Bug 1381] TAP device can not support 17 queues
  @ 2024-02-20 19:23  3% ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2024-02-20 19:23 UTC (permalink / raw)
  To: bugzilla; +Cc: dev

On Tue, 20 Feb 2024 03:29:04 +0000
bugzilla@dpdk.org wrote:

> https://bugs.dpdk.org/show_bug.cgi?id=1381
> 
>             Bug ID: 1381
>            Summary: TAP device can not support 17 queues
>            Product: DPDK
>            Version: 23.11
>           Hardware: All
>                 OS: All
>             Status: UNCONFIRMED
>           Severity: normal
>           Priority: Normal
>          Component: ethdev
>           Assignee: dev@dpdk.org
>           Reporter: stephen@networkplumber.org
>   Target Milestone: ---
> 
> If you try:
> # dpdk-testpmd --log-level=pmd.net.tap:debug -l 1-2 --vdev=net_tap0 -- -i
> --rxq=8 --txq=8
> 
> It will fail because:
> EAL: Detected CPU lcores: 8
> EAL: Detected NUMA nodes: 1
> EAL: Detected static linkage of DPDK
> EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
> EAL: Selected IOVA mode 'VA'
> rte_pmd_tap_probe(): Initializing pmd_tap for net_tap0
> eth_dev_tap_create(): TAP device on numa 0
> tun_alloc(): /dev/net/tun Features 00007173
> tun_alloc():   Multi-queue support for 16 queues
> tun_alloc(): Device name is 'dtap0'
> tun_alloc(): Using rt-signal 35
> eth_dev_tap_create(): allocated dtap0
> Interactive-mode selected
> testpmd: create a new mbuf pool <mb_pool_0>: n=155456, size=2176, socket=0
> testpmd: preferred mempool ops selected: ring_mp_mc
> 
> Warning! port-topology=paired and odd forward ports number, the last port will
> pair with itself.
> 
> Configuring Port 0 (socket 0)
> tap_dev_configure(): net_tap0: dtap0: TX configured queues number: 8
> tap_dev_configure(): net_tap0: dtap0: RX configured queues number: 8
> tun_alloc(): /dev/net/tun Features 00007173
> tun_alloc():   Multi-queue support for 16 queues
> tun_alloc(): Device name is 'dtap0'
> tap_setup_queue(): dtap0: add tx queue for qid 0 fd 26
> tap_tx_queue_setup():   TX TUNTAP device name dtap0, qid 0 on fd 26 csum off
> tun_alloc(): /dev/net/tun Features 00007173
> tun_alloc():   Multi-queue support for 16 queues
> tun_alloc(): Device name is 'dtap0'
> tap_setup_queue(): dtap0: add tx queue for qid 1 fd 212
> tap_tx_queue_setup():   TX TUNTAP device name dtap0, qid 1 on fd 212 csum off
> tun_alloc(): /dev/net/tun Features 00007173
> tun_alloc():   Multi-queue support for 16 queues
> tun_alloc(): Device name is 'dtap0'
> tap_setup_queue(): dtap0: add tx queue for qid 2 fd 213
> tap_tx_queue_setup():   TX TUNTAP device name dtap0, qid 2 on fd 213 csum off
> tun_alloc(): /dev/net/tun Features 00007173
> tun_alloc():   Multi-queue support for 16 queues
> tun_alloc(): Device name is 'dtap0'
> tap_setup_queue(): dtap0: add tx queue for qid 3 fd 214
> tap_tx_queue_setup():   TX TUNTAP device name dtap0, qid 3 on fd 214 csum off
> tun_alloc(): /dev/net/tun Features 00007173
> tun_alloc():   Multi-queue support for 16 queues
> tun_alloc(): Device name is 'dtap0'
> tap_setup_queue(): dtap0: add tx queue for qid 4 fd 215
> tap_tx_queue_setup():   TX TUNTAP device name dtap0, qid 4 on fd 215 csum off
> tun_alloc(): /dev/net/tun Features 00007173
> tun_alloc():   Multi-queue support for 16 queues
> tun_alloc(): Device name is 'dtap0'
> tap_setup_queue(): dtap0: add tx queue for qid 5 fd 216
> tap_tx_queue_setup():   TX TUNTAP device name dtap0, qid 5 on fd 216 csum off
> tun_alloc(): /dev/net/tun Features 00007173
> tun_alloc():   Multi-queue support for 16 queues
> tun_alloc(): Device name is 'dtap0'
> tap_setup_queue(): dtap0: add tx queue for qid 6 fd 217
> tap_tx_queue_setup():   TX TUNTAP device name dtap0, qid 6 on fd 217 csum off
> tun_alloc(): /dev/net/tun Features 00007173
> tun_alloc():   Multi-queue support for 16 queues
> tun_alloc(): Device name is 'dtap0'
> tap_setup_queue(): dtap0: add tx queue for qid 7 fd 218
> tap_tx_queue_setup():   TX TUNTAP device name dtap0, qid 7 on fd 218 csum off
> tap_setup_queue(): dtap0: dup fd 26 for rx queue qid 0 (219)
> tap_rx_queue_setup():   RX TUNTAP device name dtap0, qid 0 on fd 219
> tap_setup_queue(): dtap0: dup fd 212 for rx queue qid 1 (220)
> tap_rx_queue_setup():   RX TUNTAP device name dtap0, qid 1 on fd 220
> tap_setup_queue(): dtap0: dup fd 213 for rx queue qid 2 (221)
> tap_rx_queue_setup():   RX TUNTAP device name dtap0, qid 2 on fd 221
> tap_setup_queue(): dtap0: dup fd 214 for rx queue qid 3 (222)
> tap_rx_queue_setup():   RX TUNTAP device name dtap0, qid 3 on fd 222
> tap_setup_queue(): dtap0: dup fd 215 for rx queue qid 4 (223)
> tap_rx_queue_setup():   RX TUNTAP device name dtap0, qid 4 on fd 223
> tap_setup_queue(): dtap0: dup fd 216 for rx queue qid 5 (224)
> tap_rx_queue_setup():   RX TUNTAP device name dtap0, qid 5 on fd 224
> tap_setup_queue(): dtap0: dup fd 217 for rx queue qid 6 (225)
> tap_rx_queue_setup():   RX TUNTAP device name dtap0, qid 6 on fd 225
> tap_setup_queue(): dtap0: dup fd 218 for rx queue qid 7 (226)
> tap_rx_queue_setup():   RX TUNTAP device name dtap0, qid 7 on fd 226
> EAL: Cannot send more than 8 FDs
> tap_mp_req_on_rxtx(): Failed to send start req to secondary 7
> 
> This is a regression caused by:
> commit c36ce7099c2187926cd62cff7ebd479823554929
> Author: Kumara Parameshwaran <kumaraparamesh92@gmail.com>
> Date:   Mon Jan 31 20:02:34 2022 +0530
> 
>     net/tap: fix to populate FDs in secondary process
> 
>     When a tap device is hotplugged to primary process which in turn
>     adds the device to all secondary process, the secondary process
>     does a tap_mp_attach_queues, but the fds are not populated in
>     the primary during the probe they are populated during the queue_setup,
>     added a fix to sync the queues during rte_eth_dev_start
> 
>     Fixes: 4852aa8f6e21 ("drivers/net: enable hotplug on secondary process")
>     Cc: stable@dpdk.org
> 
>     Signed-off-by: Kumara Parameshwaran <kparameshwar@vmware.com>
>     Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
> 

The number of file descriptors allowed in rte_mp_msg should be much larger.
The Linux kernel has an upper limit SCM_MAX_FD which is 253 (see net/scm.h)

But fixing this will break ABI because rte_mp_msg structure was exposed
in rte_eal.h.  It should have been internal!

Alternatively, since fds[] is the last field in rte_mp_msg, and num_fds is
also there, fds[] could have been a flexible array, rather than hard coded.




^ permalink raw reply	[relevance 3%]

* Re: [PATCH v3 10/11] eventdev: clarify docs on event object fields and op types
  @ 2024-02-20 17:39  3%         ` Bruce Richardson
  2024-02-21  9:31  0%           ` Jerin Jacob
  0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2024-02-20 17:39 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: dev, jerinj, mattias.ronnblom, abdullah.sevincer, sachin.saxena,
	hemant.agrawal, pbhagavatula, pravin.pathak

On Fri, Feb 09, 2024 at 02:44:04PM +0530, Jerin Jacob wrote:
> On Fri, Feb 2, 2024 at 6:11 PM Bruce Richardson
> <bruce.richardson@intel.com> wrote:
> >
> > Clarify the meaning of the NEW, FORWARD and RELEASE event types.
> > For the fields in "rte_event" struct, enhance the comments on each to
> > clarify the field's use, and whether it is preserved between enqueue and
> > dequeue, and it's role, if any, in scheduling.
> >
> > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > ---
> > V3: updates following review
> > ---
> >  lib/eventdev/rte_eventdev.h | 161 +++++++++++++++++++++++++-----------
> >  1 file changed, 111 insertions(+), 50 deletions(-)
> >
> > diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h
> > index 8d72765ae7..58219e027e 100644
> > --- a/lib/eventdev/rte_eventdev.h
> > +++ b/lib/eventdev/rte_eventdev.h
> > @@ -1463,47 +1463,54 @@ struct rte_event_vector {
> >
> >  /* Event enqueue operations */
> >  #define RTE_EVENT_OP_NEW                0
> > -/**< The event producers use this operation to inject a new event to the
> > - * event device.
> > +/**< The @ref rte_event.op field must be set to this operation type to inject a new event,
> > + * i.e. one not previously dequeued, into the event device, to be scheduled
> > + * for processing.
> >   */
> >  #define RTE_EVENT_OP_FORWARD            1
> > -/**< The CPU use this operation to forward the event to different event queue or
> > - * change to new application specific flow or schedule type to enable
> > - * pipelining.
> > +/**< The application must set the @ref rte_event.op field to this operation type to return a
> > + * previously dequeued event to the event device to be scheduled for further processing.
> >   *
> > - * This operation must only be enqueued to the same port that the
> > + * This event *must* be enqueued to the same port that the
> >   * event to be forwarded was dequeued from.
> > + *
> > + * The event's fields, including (but not limited to) flow_id, scheduling type,
> > + * destination queue, and event payload e.g. mbuf pointer, may all be updated as
> > + * desired by the application, but the @ref rte_event.impl_opaque field must
> > + * be kept to the same value as was present when the event was dequeued.
> >   */
> >  #define RTE_EVENT_OP_RELEASE            2
> >  /**< Release the flow context associated with the schedule type.
> >   *
> > - * If current flow's scheduler type method is *RTE_SCHED_TYPE_ATOMIC*
> > - * then this function hints the scheduler that the user has completed critical
> > - * section processing in the current atomic context.
> > - * The scheduler is now allowed to schedule events from the same flow from
> > - * an event queue to another port. However, the context may be still held
> > - * until the next rte_event_dequeue_burst() call, this call allows but does not
> > - * force the scheduler to release the context early.
> > - *
> > - * Early atomic context release may increase parallelism and thus system
> > + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_ATOMIC
> > + * then this operation type hints the scheduler that the user has completed critical
> > + * section processing for this event in the current atomic context, and that the
> > + * scheduler may unlock any atomic locks held for this event.
> > + * If this is the last event from an atomic flow, i.e. all flow locks are released,
> 
> 
> Similar comment as other email
> [Jerin] When there are multiple atomic events dequeue from @ref
> rte_event_dequeue_burst()
> for the same event queue, and it has same flow id then the lock is ....
> 
> [Mattias]
> Yes, or maybe describing the whole lock/unlock state.
> 
> "The conceptual per-queue-per-flow lock is in a locked state as long
> (and only as long) as one or more events pertaining to that flow were
> scheduled to the port in question, but are not yet released."
> 
> Maybe it needs to be more meaty, describing what released means. I don't
> have the full context of the documentation in my head when I'm writing this.
>

Will take a look to reword a bit
 
> 
> > + * the scheduler is now allowed to schedule events from that flow from to another port.
> > + * However, the atomic locks may be still held until the next rte_event_dequeue_burst()
> > + * call; enqueuing an event with opt type @ref RTE_EVENT_OP_RELEASE allows,
> 
> Is ";" intended?
> 
> > + * but does not force, the scheduler to release the atomic locks early.
> 
> instead of "not force", can use the term _hint_ the driver and reword.

Ok.
> 
> > + *
> > + * Early atomic lock release may increase parallelism and thus system
> >   * performance, but the user needs to design carefully the split into critical
> >   * vs non-critical sections.
> >   *
> > - * If current flow's scheduler type method is *RTE_SCHED_TYPE_ORDERED*
> > - * then this function hints the scheduler that the user has done all that need
> > - * to maintain event order in the current ordered context.
> > - * The scheduler is allowed to release the ordered context of this port and
> > - * avoid reordering any following enqueues.
> > - *
> > - * Early ordered context release may increase parallelism and thus system
> > - * performance.
> > + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_ORDERED
> > + * then this operation type informs the scheduler that the current event has
> > + * completed processing and will not be returned to the scheduler, i.e.
> > + * it has been dropped, and so the reordering context for that event
> > + * should be considered filled.
> >   *
> > - * If current flow's scheduler type method is *RTE_SCHED_TYPE_PARALLEL*
> > - * or no scheduling context is held then this function may be an NOOP,
> > - * depending on the implementation.
> > + * Events with this operation type must only be enqueued to the same port that the
> > + * event to be released was dequeued from. The @ref rte_event.impl_opaque
> > + * field in the release event must have the same value as that in the original dequeued event.
> >   *
> > - * This operation must only be enqueued to the same port that the
> > - * event to be released was dequeued from.
> > + * If a dequeued event is re-enqueued with operation type of @ref RTE_EVENT_OP_RELEASE,
> > + * then any subsequent enqueue of that event - or a copy of it - must be done as event of type
> > + * @ref RTE_EVENT_OP_NEW, not @ref RTE_EVENT_OP_FORWARD. This is because any context for
> > + * the originally dequeued event, i.e. atomic locks, or reorder buffer entries, will have
> > + * been removed or invalidated by the release operation.
> >   */
> >
> >  /**
> > @@ -1517,56 +1524,110 @@ struct rte_event {
> >                 /** Event attributes for dequeue or enqueue operation */
> >                 struct {
> >                         uint32_t flow_id:20;
> > -                       /**< Targeted flow identifier for the enqueue and
> > -                        * dequeue operation.
> > -                        * The value must be in the range of
> > -                        * [0, nb_event_queue_flows - 1] which
> > -                        * previously supplied to rte_event_dev_configure().
> > +                       /**< Target flow identifier for the enqueue and dequeue operation.
> > +                        *
> > +                        * For @ref RTE_SCHED_TYPE_ATOMIC, this field is used to identify a
> > +                        * flow for atomicity within a queue & priority level, such that events
> > +                        * from each individual flow will only be scheduled to one port at a time.
> > +                        *
> > +                        * This field is preserved between enqueue and dequeue when
> > +                        * a device reports the @ref RTE_EVENT_DEV_CAP_CARRY_FLOW_ID
> > +                        * capability. Otherwise the value is implementation dependent
> > +                        * on dequeue.
> >                          */
> >                         uint32_t sub_event_type:8;
> >                         /**< Sub-event types based on the event source.
> > +                        *
> > +                        * This field is preserved between enqueue and dequeue.
> > +                        * This field is for application or event adapter use,
> > +                        * and is not considered in scheduling decisions.
> 
> 
> cnxk driver is considering this for scheduling decision to
> differentiate the producer i.e event adapters.
> If other drivers are not then we can change the language around it is
> implementation defined.
> 
How does the event type influence the scheduling decision? I can drop the
last line here, but it seems strange to me that the type of event could affect
things. I would have thought that with the eventdev API only the queue,
flow id, and priority would be factors in scheduling?

> 
> > +                        *
> >                          * @see RTE_EVENT_TYPE_CPU
> >                          */
> >                         uint32_t event_type:4;
> > -                       /**< Event type to classify the event source.
> > -                        * @see RTE_EVENT_TYPE_ETHDEV, (RTE_EVENT_TYPE_*)
> > +                       /**< Event type to classify the event source. (RTE_EVENT_TYPE_*)
> > +                        *
> > +                        * This field is preserved between enqueue and dequeue
> > +                        * This field is for application or event adapter use,
> > +                        * and is not considered in scheduling decisions.
> 
> 
> cnxk driver is considering this for scheduling decision to
> differentiate the producer i.e event adapters.
> If other drivers are not then we can change the language around it is
> implementation defined.
> 
> >                          */
> >                         uint8_t op:2;
> > -                       /**< The type of event enqueue operation - new/forward/
> > -                        * etc.This field is not preserved across an instance
> > -                        * and is undefined on dequeue.
> > -                        * @see RTE_EVENT_OP_NEW, (RTE_EVENT_OP_*)
> > +                       /**< The type of event enqueue operation - new/forward/ etc.
> > +                        *
> > +                        * This field is *not* preserved across an instance
> > +                        * and is implementation dependent on dequeue.
> > +                        *
> > +                        * @see RTE_EVENT_OP_NEW
> > +                        * @see RTE_EVENT_OP_FORWARD
> > +                        * @see RTE_EVENT_OP_RELEASE
> >                          */
> >                         uint8_t rsvd:4;
> > -                       /**< Reserved for future use */
> > +                       /**< Reserved for future use.
> > +                        *
> > +                        * Should be set to zero on enqueue.
> 
> I am worried about some application explicitly start setting this to
> zero on every enqueue.
> Instead, can we say application should not touch the field, Since every eventdev
> operations starts with dequeue() driver can fill to the correct value.
> 

I'll set this to zero on "NEW", or untouched on FORWARD/RELEASE. 
If we don't state that it should be zeroed on NEW or untouched
otherwise we cannot use the space in future without ABI break.

> > +                        */
> >                         uint8_t sched_type:2;
> >                         /**< Scheduler synchronization type (RTE_SCHED_TYPE_*)
> >                          * associated with flow id on a given event queue
> >                          * for the enqueue and dequeue operation.
> > +                        *
> > +                        * This field is used to determine the scheduling type
> > +                        * for events sent to queues where @ref RTE_EVENT_QUEUE_CFG_ALL_TYPES
> > +                        * is configured.
> > +                        * For queues where only a single scheduling type is available,
> > +                        * this field must be set to match the configured scheduling type.
> > +                        *
> > +                        * This field is preserved between enqueue and dequeue.
> > +                        *
> > +                        * @see RTE_SCHED_TYPE_ORDERED
> > +                        * @see RTE_SCHED_TYPE_ATOMIC
> > +                        * @see RTE_SCHED_TYPE_PARALLEL
> >                          */
> >                         uint8_t queue_id;
> >                         /**< Targeted event queue identifier for the enqueue or
> >                          * dequeue operation.
> > -                        * The value must be in the range of
> > -                        * [0, nb_event_queues - 1] which previously supplied to
> > -                        * rte_event_dev_configure().
> > +                        * The value must be less than @ref rte_event_dev_config.nb_event_queues
> > +                        * which was previously supplied to rte_event_dev_configure().
> 
> Some reason, similar text got removed for flow_id. Please add the same.
> 

That was deliberate based on discussion on V2. See:

http://inbox.dpdk.org/dev/Zby3nb4NGs8T5odL@bricha3-MOBL.ger.corp.intel.com/

and wider thread discussion starting here:

http://inbox.dpdk.org/dev/ZbvOtAEpzja0gu7b@bricha3-MOBL.ger.corp.intel.com/

Basically, the comment is wrong based on what the code does now. No event
adapters or apps are limiting the flow-id, and nothing seems broken, so we
can remove the comment.


^ permalink raw reply	[relevance 3%]

* Re: [PATCH v4 01/18] mbuf: deprecate GCC marker in rte mbuf struct
  2024-02-18 12:39  0%     ` Thomas Monjalon
  2024-02-18 13:07  0%       ` Morten Brørup
@ 2024-02-20 17:20  0%       ` Tyler Retzlaff
  1 sibling, 0 replies; 200+ results
From: Tyler Retzlaff @ 2024-02-20 17:20 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, Ajit Khaparde, Andrew Boyer, Andrew Rybchenko,
	Bruce Richardson, Chenbo Xia, Chengwen Feng, Dariusz Sosnowski,
	David Christensen, Hyong Youb Kim, Jerin Jacob, Jie Hai,
	Jingjing Wu, John Daley, Kevin Laatz, Kiran Kumar K,
	Konstantin Ananyev, Maciej Czekaj, Matan Azrad, Maxime Coquelin,
	Nithin Dabilpuram, Ori Kam, Ruifeng Wang, Satha Rao,
	Somnath Kotur, Suanming Mou, Sunil Kumar Kori,
	Viacheslav Ovsiienko, Yisen Zhuang, Yuying Zhang, mb

On Sun, Feb 18, 2024 at 01:39:52PM +0100, Thomas Monjalon wrote:
> 15/02/2024 07:21, Tyler Retzlaff:
> > Provide a macro that allows conditional expansion of RTE_MARKER fields
> > to empty to allow rte_mbuf to be used with MSVC. It is proposed that
> > we announce the fields to be __rte_deprecated (currently disabled).
> > 
> > Introduce C11 anonymous unions to permit aliasing of well-known
> > offsets by name into the rte_mbuf structure by a *new* name and to
> > provide padding for cache alignment.
> > 
> > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> > ---
> >  doc/guides/rel_notes/deprecation.rst |  20 ++
> >  lib/eal/include/rte_common.h         |   6 +
> >  lib/mbuf/rte_mbuf_core.h             | 375 +++++++++++++++++++----------------
> >  3 files changed, 233 insertions(+), 168 deletions(-)
> > 
> > diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> > index 10630ba..8594255 100644
> > --- a/doc/guides/rel_notes/deprecation.rst
> > +++ b/doc/guides/rel_notes/deprecation.rst
> > @@ -17,6 +17,26 @@ Other API and ABI deprecation notices are to be posted below.
> >  Deprecation Notices
> >  -------------------
> >  
> > +* mbuf: Named zero sized fields of type ``RTE_MARKER`` and ``RTE_MARKER64``
> > +  will be removed from ``struct rte_mbuf`` and replaced with new fields
> > +  in anonymous unions.
> > +
> > +  The names of the fields impacted are:
> > +
> > +    old name                  new name
> > +
> > +  ``cacheline0``            ``mbuf_cachelin0``
> > +  ``rearm_data``            ``mbuf_rearm_data``
> > +  ``rx_descriptor_fields1`` ``mbuf_rx_descriptor_fields1``
> > +  ``cacheline1``            ``mbuf_cachelin1``
> > +
> > +  Contributions to DPDK should immediately start using the new names,
> > +  applications should adapt to new names as soon as possible as the
> > +  old names will be removed in a future DPDK release.
> > +
> > +  Note: types of the new names are not API compatible with the old and
> > +  some code conversion is required to maintain correct behavior.
> > +
> >  * build: The ``enable_kmods`` option is deprecated and will be removed in a future release.
> >    Setting/clearing the option has no impact on the build.
> >    Instead, kernel modules will be always built for OS's where out-of-tree kernel modules
> > diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h
> > index d7d6390..af73f67 100644
> > --- a/lib/eal/include/rte_common.h
> > +++ b/lib/eal/include/rte_common.h
> > @@ -582,6 +582,12 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void)
> >  /** Marker for 8B alignment in a structure. */
> >  __extension__ typedef uint64_t RTE_MARKER64[0];
> >  
> > +#define __rte_marker(type, name) type name /* __rte_deprecated */
> > +
> > +#else
> > +
> > +#define __rte_marker(type, name)
> > +
> >  #endif
> >  
> >  /*********** Macros for calculating min and max **********/
> > diff --git a/lib/mbuf/rte_mbuf_core.h b/lib/mbuf/rte_mbuf_core.h
> > index 5688683..9e9590b 100644
> > --- a/lib/mbuf/rte_mbuf_core.h
> > +++ b/lib/mbuf/rte_mbuf_core.h
> > @@ -16,7 +16,10 @@
> >   * New fields and flags should fit in the "dynamic space".
> >   */
> >  
> > +#include <assert.h>
> > +#include <stdalign.h>
> >  #include <stdint.h>
> > +#include <stddef.h>
> >  
> >  #include <rte_byteorder.h>
> >  #include <rte_stdatomic.h>
> > @@ -464,204 +467,240 @@ enum {
> >   * The generic rte_mbuf, containing a packet mbuf.
> >   */
> >  struct rte_mbuf {
> > -	RTE_MARKER cacheline0;
> > -
> > -	void *buf_addr;           /**< Virtual address of segment buffer. */
> > +	__rte_marker(RTE_MARKER, cacheline0);
> 
> You don't need to keep the first argument.
> This would be simpler:
> 	__rte_marker(cacheline0);
> You just need to create 2 functions: __rte_marker and __rte_marker64.

no objection, i'll add 2 macros and drop the first argument.

> 
> You should replace all occurrences of RTE_MARKER in DPDK in one patch,
> and mark RTE_MARKER as deprecated (use #pragma GCC poison)

will update to use pragma instead of __rte_deprecated

> 
> > +	union {
> > +		char mbuf_cacheline0[RTE_CACHE_LINE_MIN_SIZE];
> > +		__extension__
> > +		struct {
> > +			void *buf_addr;           /**< Virtual address of segment buffer. 
> 
> I think it is ugly.
> 
> Changing mbuf API is a serious issue.

agreed, do you have an alternate proposal to solve problem?

> 

^ permalink raw reply	[relevance 0%]

* Re: [RFC v3 1/6] eal: add static per-lcore memory allocation facility
  2024-02-20 11:39  0%         ` Bruce Richardson
  2024-02-20 13:37  0%           ` Morten Brørup
@ 2024-02-20 16:26  0%           ` Mattias Rönnblom
  1 sibling, 0 replies; 200+ results
From: Mattias Rönnblom @ 2024-02-20 16:26 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: Mattias Rönnblom, dev, Morten Brørup, Stephen Hemminger

On 2024-02-20 12:39, Bruce Richardson wrote:
> On Tue, Feb 20, 2024 at 11:47:14AM +0100, Mattias Rönnblom wrote:
>> On 2024-02-20 10:11, Bruce Richardson wrote:
>>> On Tue, Feb 20, 2024 at 09:49:03AM +0100, Mattias Rönnblom wrote:
>>>> Introduce DPDK per-lcore id variables, or lcore variables for short.
>>>>
>>>> An lcore variable has one value for every current and future lcore
>>>> id-equipped thread.
>>>>
>>>> The primary <rte_lcore_var.h> use case is for statically allocating
>>>> small chunks of often-used data, which is related logically, but where
>>>> there are performance benefits to reap from having updates being local
>>>> to an lcore.
>>>>
>>>> Lcore variables are similar to thread-local storage (TLS, e.g., C11
>>>> _Thread_local), but decoupling the values' life time with that of the
>>>> threads.
> 
> <snip>
> 
>>>> +/*
>>>> + * Avoid using offset zero, since it would result in a NULL-value
>>>> + * "handle" (offset) pointer, which in principle and per the API
>>>> + * definition shouldn't be an issue, but may confuse some tools and
>>>> + * users.
>>>> + */
>>>> +#define INITIAL_OFFSET 1
>>>> +
>>>> +char rte_lcore_var[RTE_MAX_LCORE][RTE_MAX_LCORE_VAR] __rte_cache_aligned;
>>>> +
>>>
>>> While I like the idea of improved handling for per-core variables, my main
>>> concern with this set is this definition here, which adds yet another
>>> dependency on the compile-time defined RTE_MAX_LCORE value.
>>>
>>
>> lcore variables replaces one RTE_MAX_LCORE-dependent pattern with another.
>>
>> You could even argue the dependency on RTE_MAX_LCORE is reduced with lcore
>> variables, if you look at where/in how many places in the code base this
>> macro is being used. Centralizing per-lcore data management may also provide
>> some opportunity in the future for extending the API to cope with some more
>> dynamic RTE_MAX_LCORE variant. Not without ABI breakage of course, but we
>> are not ever going to change anything related to RTE_MAX_LCORE without
>> breaking the ABI, since this constant is everywhere, including compiled into
>> the application itself.
>>
> 
> Yep, that is true if it's widely used.
> 
>>> I believe we already have an issue with this #define where it's impossible
>>> to come up with a single value that works for all, or nearly all cases. The
>>> current default is still 128, yet DPDK needs to support systems where the
>>> number of cores is well into the hundreds, requiring workarounds of core
>>> mappings or customized builds of DPDK. Upping the value fixes those issues
>>> at the cost to memory footprint explosion for smaller systems.
>>>
>>
>> I agree this is an issue.
>>
>> RTE_MAX_LCORE also need to be sized to accommodate not only all cores used,
>> but the sum of all EAL threads and registered non-EAL threads.
>>
>> So, there is no reliable way to discover what RTE_MAX_LCORE is on a
>> particular piece of hardware, since the actual number of lcore ids needed is
>> up to the application.
>>
>> Why is the default set so low? Linux has MAX_CPUS, which serves the same
>> purpose, which is set to 4096 by default, if I recall correctly. Shouldn't
>> we at least be able to increase it to 256?
> 
> The default is so low because of the mempool caches. These are an array of
> buffer pointers with 512 (IIRC) entries per core up to RTE_MAX_LCORE.
> 
>>
>>> I'm therefore nervous about putting more dependencies on this value, when I
>>> feel we should be moving away from its use, to allow more runtime
>>> configurability of cores.
>>>
>>
>> What more specifically do you have in mind?
>>
> 
> I don't think having a dynamically scaling RTE_MAX_LCORE is feasible, but
> what I would like to see is a runtime specified value. For example, you
> could run DPDK with EAL parameter "--max-lcores=1024" for large systems or
> "--max-lcores=32" for small ones. That would then be used at init-time to
> scale all internal datastructures appropriately.
> 

Sounds reasonably to me, especially if you would take gradual approach.

By gradual I mean something like adding a function 
rte_lcore_max_possible(), or something like that, returning the EAL 
init-specified value. DPDK libraries/PMDs could then gradually be made 
aware and taking advantage of knowing that lcore ids will always be 
below a certain threshold, usually significantly lower than RTE_MAX_LCORE.

The only change required for lcore variables would be that the FOREACH 
macro would use the run-time-max value, rather than RTE_MAX_LCORE, which 
in turn would leave all the higher-numbered lcore id buffers 
untouched/unmapped.

The set of possible lcore ids could also be expressed as a bitset, if 
you have machine with a huge amount of cores, running many small DPDK 
instances.

> /Bruce
> 
> <snip for brevity>

^ permalink raw reply	[relevance 0%]

* RE: [RFC v3 1/6] eal: add static per-lcore memory allocation facility
  2024-02-20 11:39  0%         ` Bruce Richardson
@ 2024-02-20 13:37  0%           ` Morten Brørup
  2024-02-20 16:26  0%           ` Mattias Rönnblom
  1 sibling, 0 replies; 200+ results
From: Morten Brørup @ 2024-02-20 13:37 UTC (permalink / raw)
  To: Bruce Richardson, Mattias Rönnblom
  Cc: Mattias Rönnblom, dev, Stephen Hemminger

> From: Bruce Richardson [mailto:bruce.richardson@intel.com]
> Sent: Tuesday, 20 February 2024 12.39
> 
> On Tue, Feb 20, 2024 at 11:47:14AM +0100, Mattias Rönnblom wrote:
> > On 2024-02-20 10:11, Bruce Richardson wrote:
> > > On Tue, Feb 20, 2024 at 09:49:03AM +0100, Mattias Rönnblom wrote:
> > > > Introduce DPDK per-lcore id variables, or lcore variables for
> short.
> > > >
> > > > An lcore variable has one value for every current and future
> lcore
> > > > id-equipped thread.
> > > >
> > > > The primary <rte_lcore_var.h> use case is for statically
> allocating
> > > > small chunks of often-used data, which is related logically, but
> where
> > > > there are performance benefits to reap from having updates being
> local
> > > > to an lcore.
> > > >
> > > > Lcore variables are similar to thread-local storage (TLS, e.g.,
> C11
> > > > _Thread_local), but decoupling the values' life time with that of
> the
> > > > threads.
> 
> <snip>
> 
> > > > +/*
> > > > + * Avoid using offset zero, since it would result in a NULL-
> value
> > > > + * "handle" (offset) pointer, which in principle and per the API
> > > > + * definition shouldn't be an issue, but may confuse some tools
> and
> > > > + * users.
> > > > + */
> > > > +#define INITIAL_OFFSET 1
> > > > +
> > > > +char rte_lcore_var[RTE_MAX_LCORE][RTE_MAX_LCORE_VAR]
> __rte_cache_aligned;
> > > > +
> > >
> > > While I like the idea of improved handling for per-core variables,
> my main
> > > concern with this set is this definition here, which adds yet
> another
> > > dependency on the compile-time defined RTE_MAX_LCORE value.
> > >
> >
> > lcore variables replaces one RTE_MAX_LCORE-dependent pattern with
> another.
> >
> > You could even argue the dependency on RTE_MAX_LCORE is reduced with
> lcore
> > variables, if you look at where/in how many places in the code base
> this
> > macro is being used. Centralizing per-lcore data management may also
> provide
> > some opportunity in the future for extending the API to cope with
> some more
> > dynamic RTE_MAX_LCORE variant. Not without ABI breakage of course,
> but we
> > are not ever going to change anything related to RTE_MAX_LCORE
> without
> > breaking the ABI, since this constant is everywhere, including
> compiled into
> > the application itself.
> >
> 
> Yep, that is true if it's widely used.
> 
> > > I believe we already have an issue with this #define where it's
> impossible
> > > to come up with a single value that works for all, or nearly all
> cases. The
> > > current default is still 128, yet DPDK needs to support systems
> where the
> > > number of cores is well into the hundreds, requiring workarounds of
> core
> > > mappings or customized builds of DPDK. Upping the value fixes those
> issues
> > > at the cost to memory footprint explosion for smaller systems.
> > >
> >
> > I agree this is an issue.
> >
> > RTE_MAX_LCORE also need to be sized to accommodate not only all cores
> used,
> > but the sum of all EAL threads and registered non-EAL threads.
> >
> > So, there is no reliable way to discover what RTE_MAX_LCORE is on a
> > particular piece of hardware, since the actual number of lcore ids
> needed is
> > up to the application.
> >
> > Why is the default set so low? Linux has MAX_CPUS, which serves the
> same
> > purpose, which is set to 4096 by default, if I recall correctly.
> Shouldn't
> > we at least be able to increase it to 256?

I recall a recent techboard meeting where the default was discussed. The default was agreed so low because it suffices for the vast majority of hardware out there, and applications for bigger platforms can be expected to build DPDK with a different configuration themselves. And as Bruce also mentions, it's a tradeoff for memory consumption.

> 
> The default is so low because of the mempool caches. These are an array
> of
> buffer pointers with 512 (IIRC) entries per core up to RTE_MAX_LCORE.

The decision was based on a need to make a quick decision, so we used narrow guesstimates, not a broader memory consumption analysis.

If we really cared about default memory consumption, we should reduce the default RTE_MAX_QUEUES_PER_PORT from 1024 too. It has quite an effect.

Having hard data about which build time configuration parameters have the biggest effect on memory consumption would be extremely useful for tweaking the parameters for resource limited hardware.
It's a mix of static and dynamic allocation, so it's not obvious which scalable data structures consume the most memory.

> 
> >
> > > I'm therefore nervous about putting more dependencies on this
> value, when I
> > > feel we should be moving away from its use, to allow more runtime
> > > configurability of cores.
> > >
> >
> > What more specifically do you have in mind?
> >
> 
> I don't think having a dynamically scaling RTE_MAX_LCORE is feasible,
> but
> what I would like to see is a runtime specified value. For example, you
> could run DPDK with EAL parameter "--max-lcores=1024" for large systems
> or
> "--max-lcores=32" for small ones. That would then be used at init-time
> to
> scale all internal datastructures appropriately.
> 

I agree 100 % that a better long term solution should be on the general road map.
Memory is a precious resource, but few seem to care about it.

A mix could provide an easy migration path:
Having RTE_MAX_LCORE as the hard upper limit (and default value) for a runtime specified max number ("rte_max_lcores").
With this, the goal would be for modules with very small data sets to continue using RTE_MAX_LCORE fixed size arrays, and for modules with larger data sets to migrate to rte_max_lcores dynamically sized arrays.

I am opposed to blocking a new patch series, only because it adds another RTE_MAX_LCORE sized array. We already have plenty of those.
It can be migrated towards dynamically sized array at a later time, just like the other modules with RTE_MAX_LCORE sized arrays.
Perhaps "fixing" an existing module would free up more memory than fixing this module. Let's spend development resources where they have the biggest impact.


^ permalink raw reply	[relevance 0%]

* Re: [RFC v3 1/6] eal: add static per-lcore memory allocation facility
  2024-02-20 10:47  3%       ` Mattias Rönnblom
@ 2024-02-20 11:39  0%         ` Bruce Richardson
  2024-02-20 13:37  0%           ` Morten Brørup
  2024-02-20 16:26  0%           ` Mattias Rönnblom
  0 siblings, 2 replies; 200+ results
From: Bruce Richardson @ 2024-02-20 11:39 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: Mattias Rönnblom, dev, Morten Brørup, Stephen Hemminger

On Tue, Feb 20, 2024 at 11:47:14AM +0100, Mattias Rönnblom wrote:
> On 2024-02-20 10:11, Bruce Richardson wrote:
> > On Tue, Feb 20, 2024 at 09:49:03AM +0100, Mattias Rönnblom wrote:
> > > Introduce DPDK per-lcore id variables, or lcore variables for short.
> > > 
> > > An lcore variable has one value for every current and future lcore
> > > id-equipped thread.
> > > 
> > > The primary <rte_lcore_var.h> use case is for statically allocating
> > > small chunks of often-used data, which is related logically, but where
> > > there are performance benefits to reap from having updates being local
> > > to an lcore.
> > > 
> > > Lcore variables are similar to thread-local storage (TLS, e.g., C11
> > > _Thread_local), but decoupling the values' life time with that of the
> > > threads.

<snip>

> > > +/*
> > > + * Avoid using offset zero, since it would result in a NULL-value
> > > + * "handle" (offset) pointer, which in principle and per the API
> > > + * definition shouldn't be an issue, but may confuse some tools and
> > > + * users.
> > > + */
> > > +#define INITIAL_OFFSET 1
> > > +
> > > +char rte_lcore_var[RTE_MAX_LCORE][RTE_MAX_LCORE_VAR] __rte_cache_aligned;
> > > +
> > 
> > While I like the idea of improved handling for per-core variables, my main
> > concern with this set is this definition here, which adds yet another
> > dependency on the compile-time defined RTE_MAX_LCORE value.
> > 
> 
> lcore variables replaces one RTE_MAX_LCORE-dependent pattern with another.
> 
> You could even argue the dependency on RTE_MAX_LCORE is reduced with lcore
> variables, if you look at where/in how many places in the code base this
> macro is being used. Centralizing per-lcore data management may also provide
> some opportunity in the future for extending the API to cope with some more
> dynamic RTE_MAX_LCORE variant. Not without ABI breakage of course, but we
> are not ever going to change anything related to RTE_MAX_LCORE without
> breaking the ABI, since this constant is everywhere, including compiled into
> the application itself.
> 

Yep, that is true if it's widely used.

> > I believe we already have an issue with this #define where it's impossible
> > to come up with a single value that works for all, or nearly all cases. The
> > current default is still 128, yet DPDK needs to support systems where the
> > number of cores is well into the hundreds, requiring workarounds of core
> > mappings or customized builds of DPDK. Upping the value fixes those issues
> > at the cost to memory footprint explosion for smaller systems.
> > 
> 
> I agree this is an issue.
> 
> RTE_MAX_LCORE also need to be sized to accommodate not only all cores used,
> but the sum of all EAL threads and registered non-EAL threads.
> 
> So, there is no reliable way to discover what RTE_MAX_LCORE is on a
> particular piece of hardware, since the actual number of lcore ids needed is
> up to the application.
> 
> Why is the default set so low? Linux has MAX_CPUS, which serves the same
> purpose, which is set to 4096 by default, if I recall correctly. Shouldn't
> we at least be able to increase it to 256?

The default is so low because of the mempool caches. These are an array of
buffer pointers with 512 (IIRC) entries per core up to RTE_MAX_LCORE.

> 
> > I'm therefore nervous about putting more dependencies on this value, when I
> > feel we should be moving away from its use, to allow more runtime
> > configurability of cores.
> > 
> 
> What more specifically do you have in mind?
> 

I don't think having a dynamically scaling RTE_MAX_LCORE is feasible, but
what I would like to see is a runtime specified value. For example, you
could run DPDK with EAL parameter "--max-lcores=1024" for large systems or
"--max-lcores=32" for small ones. That would then be used at init-time to
scale all internal datastructures appropriately.

/Bruce

<snip for brevity>

^ permalink raw reply	[relevance 0%]

* [PATCH v3 1/7] ethdev: support report register names and filter
  @ 2024-02-20 10:58  8%   ` Jie Hai
  0 siblings, 0 replies; 200+ results
From: Jie Hai @ 2024-02-20 10:58 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch adds "filter" and "names" fields to "rte_dev_reg_info"
structure. Names of registers in data fields can be reported and
the registers can be filtered by their names.

The new API rte_eth_dev_get_reg_info_ext() is added to support
reporting names and filtering by names. And the original API
rte_eth_dev_get_reg_info() does not use the name and filter fields.
A local variable is used in rte_eth_dev_get_reg_info for
compatibility. If the drivers does not report the names, set them
to "offset_XXX".

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 doc/guides/rel_notes/release_24_03.rst |  9 +++++++
 lib/ethdev/rte_dev_info.h              | 11 ++++++++
 lib/ethdev/rte_ethdev.c                | 36 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 28 ++++++++++++++++++++
 lib/ethdev/version.map                 |  1 +
 5 files changed, 85 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index db8be50c6dfd..f8882ba36bb9 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -102,6 +102,12 @@ New Features
 
   * Added support for comparing result between packet fields or value.
 
+* **Added support for dumping regiters with names and filter.**
+
+  * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
+    the registers by their names and get the information of registers(names,
+    values and other attributes).
+
 
 Removed Items
 -------------
@@ -154,6 +160,9 @@ ABI Changes
 
 * No ABI change that would break compatibility with 23.11.
 
+* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
+  structure for reporting names of registers and filtering them by names.
+
 
 Known Issues
 ------------
diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
index 67cf0ae52668..2f4541bd46c8 100644
--- a/lib/ethdev/rte_dev_info.h
+++ b/lib/ethdev/rte_dev_info.h
@@ -11,6 +11,11 @@ extern "C" {
 
 #include <stdint.h>
 
+#define RTE_ETH_REG_NAME_SIZE 128
+struct rte_eth_reg_name {
+	char name[RTE_ETH_REG_NAME_SIZE];
+};
+
 /*
  * Placeholder for accessing device registers
  */
@@ -20,6 +25,12 @@ struct rte_dev_reg_info {
 	uint32_t length; /**< Number of registers to fetch */
 	uint32_t width; /**< Size of device register */
 	uint32_t version; /**< Device version */
+	/**
+	 * Filter for target subset of registers.
+	 * This field could affects register selection for data/length/names.
+	 */
+	char *filter;
+	struct rte_eth_reg_name *names; /**< Registers name saver */
 };
 
 /*
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f1c658f49e80..9eb4e696a51a 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6388,8 +6388,39 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
+{
+	struct rte_dev_reg_info reg_info = { 0 };
+	int ret;
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Cannot get ethdev port %u register info to NULL",
+			port_id);
+		return -EINVAL;
+	}
+
+	reg_info.length = info->length;
+	reg_info.data = info->data;
+	reg_info.names = NULL;
+	reg_info.filter = NULL;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0)
+		return ret;
+
+	info->length = reg_info.length;
+	info->width = reg_info.width;
+	info->version = reg_info.version;
+	info->offset = reg_info.offset;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
 {
 	struct rte_eth_dev *dev;
+	uint32_t i;
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -6408,6 +6439,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 
 	rte_ethdev_trace_get_reg_info(port_id, info, ret);
 
+	/* Report the default names if drivers not report. */
+	if (info->names != NULL && strlen(info->names[0].name) == 0)
+		for (i = 0; i < info->length; i++)
+			snprintf(info->names[i].name, RTE_ETH_REG_NAME_SIZE,
+				"offset_%x", info->offset + i * info->width);
 	return ret;
 }
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index a14ca15f34ce..4b4aa8d2152e 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5066,6 +5066,34 @@ __rte_experimental
 int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 		struct rte_power_monitor_cond *pmc);
 
+/**
+ * Retrieve the filtered device registers (values and names) and
+ * register attributes (number of registers and register size)
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param info
+ *   Pointer to rte_dev_reg_info structure to fill in.
+ *   If info->filter is not NULL and the driver does not support names or
+ *   filter, return error. If info->filter is NULL, return info for all
+ *   registers (seen as filter none).
+ *   If info->data is NULL, the function fills in the width and length fields.
+ *   If non-NULL, ethdev considers there are enough spaces to store the
+ *   registers, and the values of registers whose name contains the filter
+ *   string are put into the buffer pointed at by the data field. Do the same
+ *   for the names of registers if info->names is not NULL. If drivers do not
+ *   report names, default names are given by ethdev.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EIO) if device is removed.
+ *   - others depends on the specific operations implementation.
+ */
+__rte_experimental
+int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
+
 /**
  * Retrieve device registers and register attributes (number of registers and
  * register size)
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 8678b6991eee..2bdafce693c3 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -325,6 +325,7 @@ EXPERIMENTAL {
 	rte_flow_template_table_resizable;
 	rte_flow_template_table_resize;
 	rte_flow_template_table_resize_complete;
+	rte_eth_dev_get_reg_info_ext;
 };
 
 INTERNAL {
-- 
2.30.0


^ permalink raw reply	[relevance 8%]

* Re: [RFC v3 1/6] eal: add static per-lcore memory allocation facility
  @ 2024-02-20 10:47  3%       ` Mattias Rönnblom
  2024-02-20 11:39  0%         ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Mattias Rönnblom @ 2024-02-20 10:47 UTC (permalink / raw)
  To: Bruce Richardson, Mattias Rönnblom
  Cc: dev, Morten Brørup, Stephen Hemminger

On 2024-02-20 10:11, Bruce Richardson wrote:
> On Tue, Feb 20, 2024 at 09:49:03AM +0100, Mattias Rönnblom wrote:
>> Introduce DPDK per-lcore id variables, or lcore variables for short.
>>
>> An lcore variable has one value for every current and future lcore
>> id-equipped thread.
>>
>> The primary <rte_lcore_var.h> use case is for statically allocating
>> small chunks of often-used data, which is related logically, but where
>> there are performance benefits to reap from having updates being local
>> to an lcore.
>>
>> Lcore variables are similar to thread-local storage (TLS, e.g., C11
>> _Thread_local), but decoupling the values' life time with that of the
>> threads.
>>
>> Lcore variables are also similar in terms of functionality provided by
>> FreeBSD kernel's DPCPU_*() family of macros and the associated
>> build-time machinery. DPCPU uses linker scripts, which effectively
>> prevents the reuse of its, otherwise seemingly viable, approach.
>>
>> The currently-prevailing way to solve the same problem as lcore
>> variables is to keep a module's per-lcore data as RTE_MAX_LCORE-sized
>> array of cache-aligned, RTE_CACHE_GUARDed structs. The benefit of
>> lcore variables over this approach is that data related to the same
>> lcore now is close (spatially, in memory), rather than data used by
>> the same module, which in turn avoid excessive use of padding,
>> polluting caches with unused data.
>>
>> RFC v3:
>>   * Replace use of GCC-specific alignof(<expression>) with alignof(<type>).
>>   * Update example to reflect FOREACH macro name change (in RFC v2).
>>
>> RFC v2:
>>   * Use alignof to derive alignment requirements. (Morten Brørup)
>>   * Change name of FOREACH to make it distinct from <rte_lcore.h>'s
>>     *per-EAL-thread* RTE_LCORE_FOREACH(). (Morten Brørup)
>>   * Allow user-specified alignment, but limit max to cache line size.
>>
>> Signed-off-by: Mattias Rönnblom <mattias.ronnblom@ericsson.com>
>> ---
>>   config/rte_config.h                   |   1 +
>>   doc/api/doxy-api-index.md             |   1 +
>>   lib/eal/common/eal_common_lcore_var.c |  82 ++++++
>>   lib/eal/common/meson.build            |   1 +
>>   lib/eal/include/meson.build           |   1 +
>>   lib/eal/include/rte_lcore_var.h       | 375 ++++++++++++++++++++++++++
>>   lib/eal/version.map                   |   4 +
>>   7 files changed, 465 insertions(+)
>>   create mode 100644 lib/eal/common/eal_common_lcore_var.c
>>   create mode 100644 lib/eal/include/rte_lcore_var.h
>>
>> diff --git a/config/rte_config.h b/config/rte_config.h
>> index da265d7dd2..884482e473 100644
>> --- a/config/rte_config.h
>> +++ b/config/rte_config.h
>> @@ -30,6 +30,7 @@
>>   /* EAL defines */
>>   #define RTE_CACHE_GUARD_LINES 1
>>   #define RTE_MAX_HEAPS 32
>> +#define RTE_MAX_LCORE_VAR 1048576
>>   #define RTE_MAX_MEMSEG_LISTS 128
>>   #define RTE_MAX_MEMSEG_PER_LIST 8192
>>   #define RTE_MAX_MEM_MB_PER_LIST 32768
>> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
>> index a6a768bd7c..bb06bb7ca1 100644
>> --- a/doc/api/doxy-api-index.md
>> +++ b/doc/api/doxy-api-index.md
>> @@ -98,6 +98,7 @@ The public API headers are grouped by topics:
>>     [interrupts](@ref rte_interrupts.h),
>>     [launch](@ref rte_launch.h),
>>     [lcore](@ref rte_lcore.h),
>> +  [lcore-varible](@ref rte_lcore_var.h),
>>     [per-lcore](@ref rte_per_lcore.h),
>>     [service cores](@ref rte_service.h),
>>     [keepalive](@ref rte_keepalive.h),
>> diff --git a/lib/eal/common/eal_common_lcore_var.c b/lib/eal/common/eal_common_lcore_var.c
>> new file mode 100644
>> index 0000000000..dfd11cbd0b
>> --- /dev/null
>> +++ b/lib/eal/common/eal_common_lcore_var.c
>> @@ -0,0 +1,82 @@
>> +/* SPDX-License-Identifier: BSD-3-Clause
>> + * Copyright(c) 2024 Ericsson AB
>> + */
>> +
>> +#include <inttypes.h>
>> +
>> +#include <rte_common.h>
>> +#include <rte_debug.h>
>> +#include <rte_log.h>
>> +
>> +#include <rte_lcore_var.h>
>> +
>> +#include "eal_private.h"
>> +
>> +#define WARN_THRESHOLD 75
>> +
>> +/*
>> + * Avoid using offset zero, since it would result in a NULL-value
>> + * "handle" (offset) pointer, which in principle and per the API
>> + * definition shouldn't be an issue, but may confuse some tools and
>> + * users.
>> + */
>> +#define INITIAL_OFFSET 1
>> +
>> +char rte_lcore_var[RTE_MAX_LCORE][RTE_MAX_LCORE_VAR] __rte_cache_aligned;
>> +
> 
> While I like the idea of improved handling for per-core variables, my main
> concern with this set is this definition here, which adds yet another
> dependency on the compile-time defined RTE_MAX_LCORE value.
> 

lcore variables replaces one RTE_MAX_LCORE-dependent pattern with another.

You could even argue the dependency on RTE_MAX_LCORE is reduced with 
lcore variables, if you look at where/in how many places in the code 
base this macro is being used. Centralizing per-lcore data management 
may also provide some opportunity in the future for extending the API to 
cope with some more dynamic RTE_MAX_LCORE variant. Not without ABI 
breakage of course, but we are not ever going to change anything related 
to RTE_MAX_LCORE without breaking the ABI, since this constant is 
everywhere, including compiled into the application itself.

> I believe we already have an issue with this #define where it's impossible
> to come up with a single value that works for all, or nearly all cases. The
> current default is still 128, yet DPDK needs to support systems where the
> number of cores is well into the hundreds, requiring workarounds of core
> mappings or customized builds of DPDK. Upping the value fixes those issues
> at the cost to memory footprint explosion for smaller systems.
> 

I agree this is an issue.

RTE_MAX_LCORE also need to be sized to accommodate not only all cores 
used, but the sum of all EAL threads and registered non-EAL threads.

So, there is no reliable way to discover what RTE_MAX_LCORE is on a 
particular piece of hardware, since the actual number of lcore ids 
needed is up to the application.

Why is the default set so low? Linux has MAX_CPUS, which serves the same 
purpose, which is set to 4096 by default, if I recall correctly. 
Shouldn't we at least be able to increase it to 256?

> I'm therefore nervous about putting more dependencies on this value, when I
> feel we should be moving away from its use, to allow more runtime
> configurability of cores.
> 

What more specifically do you have in mind?

Maybe I'm overly pessimistic, but supporting lcores without any upper 
bound and also allowing them to be added and removed at any point during 
run time seems far-fetched, given where DPDK is today.

To include an actual upper bound, set during DPDK run-time 
initialization, lower than RTE_MAX_LCORE, seems easier. I think there is 
some equivalent in the Linux kernel. Again, you would need to 
accommodate for future rte_register_thread() calls.

<rte_lcore_var.h> could be extended with a user-specified lcore variable 
  init/free function callbacks, to allow lazy or late initialization.

If one could have a way to retrieve the max possible lcore ids *for a 
particular DPDK process* (as opposed to a particular build) it would be 
possible to avoid touching the per-lcore buffers for lcore ids that 
would never be used. With data in BSS, it would never be mapped/allocated.

An issue with BSS data is that there might be very RT-sensitive 
applications deciding to lock all memory into RAM, to avoid latency 
jitter caused by paging, and such would suffer from a large 
rte_lcore_var (or all the current static arrays). Lcore variables makes 
this worse, since rte_lcore_var is larger than the sum of today's static 
arrays, and must be so, with some margin, since there is no way to 
figure out ahead of time how much memory is actually going to be needed.

> For this set/feature, would it be possible to have a run-time allocated
> (and sized) array rather than using the RTE_MAX_LCORE value?
> 

What I explored was having the per-lcore buffers dynamically allocated. 
What I ran into was I saw no apparent benefit, and with dynamic 
allocation there were new problems to solve. One was to assure lcore 
variable buffers were allocated before they were being used. In 
particular if you want to use huge page memory, lcore variables may be 
available only when that machinery is ready to accept requests.

Also, with huge page memory, you won't get the benefit you will get from 
depend paging and BSS (i.e., only used memory is actually allocated).

With malloc(), I believe you generally do get that same benefit, if you 
allocation is sufficiently large.

I also considered just allocating chunks, fitting (say) 64 kB worth of 
lcore variables in each. Turned out more complex, and to no benefit, 
other than reducing footprint for mlockall() type apps, which seemed 
like corner case.

I never considered no upper-bound, dynamic, RTE_MAX_LCORE.

> Thanks, (and apologies for the mini-rant!)
> 
> /Bruce

Thanks for the comments. This is was no way near a rant.


^ permalink raw reply	[relevance 3%]

* Re: [PATCH v2 1/7] ethdev: support report register names and filter
  2024-02-07 17:00  3%     ` Ferruh Yigit
@ 2024-02-20  8:43  3%       ` Jie Hai
  0 siblings, 0 replies; 200+ results
From: Jie Hai @ 2024-02-20  8:43 UTC (permalink / raw)
  To: Ferruh Yigit, dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui

Hi, Ferruh,
Thanks for your review.

On 2024/2/8 1:00, Ferruh Yigit wrote:
> On 2/5/2024 10:51 AM, Jie Hai wrote:
>> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
>> structure. Names of registers in data fields can be reported and
>> the registers can be filtered by their names.
>>
>> For compatibility, the original API rte_eth_dev_get_reg_info()
>> does not use the name and filter fields. The new API
>> rte_eth_dev_get_reg_info_ext() is added to support reporting
>> names and filtering by names. If the drivers does not report
>> the names, set them to "offset_XXX".
>>
>> Signed-off-by: Jie Hai <haijie1@huawei.com>
>> ---
>>   doc/guides/rel_notes/release_24_03.rst |  8 ++++++
>>   lib/ethdev/rte_dev_info.h              | 11 ++++++++
>>   lib/ethdev/rte_ethdev.c                | 36 ++++++++++++++++++++++++++
>>   lib/ethdev/rte_ethdev.h                | 22 ++++++++++++++++
>>   4 files changed, 77 insertions(+)
>>
>> diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
>> index 84d3144215c6..5d402341223a 100644
>> --- a/doc/guides/rel_notes/release_24_03.rst
>> +++ b/doc/guides/rel_notes/release_24_03.rst
>> @@ -75,6 +75,11 @@ New Features
>>     * Added support for Atomic Rules' TK242 packet-capture family of devices
>>       with PCI IDs: ``0x1024, 0x1025, 0x1026``.
>>   
>> +* **Added support for dumping regiters with names and filter.**
>>
> 
> s/regiters/registers/
Will correct in v3.
> 
>> +
>> +  * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
>> +  * the registers by their names and get the information of registers(names,
>> +  * values and other attributes).
>>   
> 
> '*' makes a bullet, but above seems one sentences, if so please only
> keep the first '*'.
Will correct in v3.
> 
>>   Removed Items
>>   -------------
>> @@ -124,6 +129,9 @@ ABI Changes
>>   
>>   * No ABI change that would break compatibility with 23.11.
>>   
>> +* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
>> +  structure for reporting names of regiters and filtering them by names.
>> +
>>   
> 
> This will break the ABI.
> 
> Think about a case, an application compiled with an old version of DPDK,
> later same application started to use this version without re-compile,
> application will send old version of 'struct rte_dev_reg_info', but new
> version of DPDK will try to access or update new fields of the 'struct
> rte_dev_reg_info'
> 
Actually, we use a local variable "struct rte_dev_reg_info reg_info" in
'rte_eth_dev_get_reg_info()' to pass to the driver, and the new fields
are set to zero. The old drivers do not visit the new fields.
We make constrains that if filter is NULL, do not filter and get info of 
all registers.
For an old version APP and new version ethdev, driver will not visit the 
new fields. so it does not break the ABI.
> One option is:
> - to add a new 'struct rte_dev_reg_info_ext',
> - 'rte_eth_dev_get_reg_info()' still uses old 'struct rte_dev_reg_info'
> - 'get_reg()' dev_ops will use this new 'struct rte_dev_reg_info_ext'
> - Add deprecation notice to update 'rte_eth_dev_get_reg_info()' to use
> new struct in next LTS release
> 

> 
>>   Known Issues
>>   ------------
>> diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
>> index 67cf0ae52668..2f4541bd46c8 100644
>> --- a/lib/ethdev/rte_dev_info.h
>> +++ b/lib/ethdev/rte_dev_info.h
>> @@ -11,6 +11,11 @@ extern "C" {
>>   
>>   #include <stdint.h>
>>   
>> +#define RTE_ETH_REG_NAME_SIZE 128
>> +struct rte_eth_reg_name {
>> +	char name[RTE_ETH_REG_NAME_SIZE];
>> +};
>> +
>>   /*
>>    * Placeholder for accessing device registers
>>    */
>> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>>   	uint32_t length; /**< Number of registers to fetch */
>>   	uint32_t width; /**< Size of device register */
>>   	uint32_t version; /**< Device version */
>> +	/**
>> +	 * Filter for target subset of registers.
>> +	 * This field could affects register selection for data/length/names.
>> +	 */
>> +	char *filter;
>> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>>   };
>>   
>>   /*
>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
>> index f1c658f49e80..3e0294e49092 100644
>> --- a/lib/ethdev/rte_ethdev.c
>> +++ b/lib/ethdev/rte_ethdev.c
>> @@ -6388,8 +6388,39 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
>>   
>>   int
>>   rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>> +{
>> +	struct rte_dev_reg_info reg_info;
>> +	int ret;
>> +
>> +	if (info == NULL) {
>> +		RTE_ETHDEV_LOG_LINE(ERR,
>> +			"Cannot get ethdev port %u register info to NULL",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	reg_info.length = info->length;
>> +	reg_info.data = info->data;
>> +	reg_info.names = NULL;
>> +	reg_info.filter = NULL;
>> +
>> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
>> +	if (ret != 0)
>> +		return ret;
>> +
>> +	info->length = reg_info.length;
>> +	info->width = reg_info.width;
>> +	info->version = reg_info.version;
>> +	info->offset = reg_info.offset;
>> +
>> +	return 0;
>> +}
>> +
>> +int
>> +rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
>>   {
>>   	struct rte_eth_dev *dev;
>> +	uint32_t i;
>>   	int ret;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> @@ -6408,6 +6439,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>>   
>>   	rte_ethdev_trace_get_reg_info(port_id, info, ret);
>>   
>> +	/* Report the default names if drivers not report. */
>> +	if (info->names != NULL && strlen(info->names[0].name) == 0)
>> +		for (i = 0; i < info->length; i++)
>> +			sprintf(info->names[i].name, "offset_%x",
>> +				info->offset + i * info->width);
>>
> 
> Better to use 'snprintf()'
> 
Will correct in v3.
>>   	return ret;
>>   }
>>   
>> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
>> index 2687c23fa6fb..3abc2ad3f865 100644
>> --- a/lib/ethdev/rte_ethdev.h
>> +++ b/lib/ethdev/rte_ethdev.h
>> @@ -5053,6 +5053,28 @@ __rte_experimental
>>   int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
>>   		struct rte_power_monitor_cond *pmc);
>>   
>> +/**
>> + * Retrieve the filtered device registers (values and names) and
>> + * register attributes (number of registers and register size)
>> + *
>> + * @param port_id
>> + *   The port identifier of the Ethernet device.
>> + * @param info
>> + *   Pointer to rte_dev_reg_info structure to fill in. If info->data is
>> + *   NULL, the function fills in the width and length fields. If non-NULL,
>> + *   the values of registers whose name contains the filter string are put
>> + *   into the buffer pointed at by the data field. Do the same for the names
>> + *   of registers if info->names is not NULL.
>>
> 
> May be good to mention if info->names is not NULL, but driver doesn't
> support names, ehtdev fills the names automatically.
> 
> As both 'rte_eth_dev_get_reg_info()' & 'rte_eth_dev_get_reg_info_ext()'
> use same dev_ops ('get_reg()'), it is possible that driver doesn't
> support filtering, so if the user provides info->filter but driver
> doesn't support it, I think API should return error, what do you think?
> 
> And can you please make it clear above, if filtering is provided with
> info->data = NULL, are the returned width and length fields for filtered
> number of registers or all registers?
> 
> 
Will correct in v3.
>> + * @return
>> + *   - (0) if successful.
>> + *   - (-ENOTSUP) if hardware doesn't support.
>> + *   - (-EINVAL) if bad parameter.
>> + *   - (-ENODEV) if *port_id* invalid.
>> + *   - (-EIO) if device is removed.
>> + *   - others depends on the specific operations implementation.
>> + */
>> +int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
>> +
>>
> 
> Can you please make the new API as experimental. That is the requirement
> for new APIs.
> 
> Also need to add the API to version.map
Will correct in v3.
> 
> 
>>   /**
>>    * Retrieve device registers and register attributes (number of registers and
>>    * register size)
> 
> .

Best regards,
Jie Hai

^ permalink raw reply	[relevance 3%]

* [PATCH v8 0/2]  add telemetry cmds for ring
    @ 2024-02-19  8:32  3% ` Jie Hai
  1 sibling, 0 replies; 200+ results
From: Jie Hai @ 2024-02-19  8:32 UTC (permalink / raw)
  To: dev
  Cc: lihuisong, fengchengwen, huangdengdui, ferruh.yigit, thomas,
	konstantin.v.ananyev, honnappa.nagarahalli, david.marchand,
	Ruifeng.Wang, mb

This patch set supports telemetry cmd to list rings and dump information
of a ring by its name.

v1->v2:
1. Add space after "switch".
2. Fix wrong strlen parameter.

v2->v3:
1. Remove prefix "rte_" for static function.
2. Add Acked-by Konstantin Ananyev for PATCH 1.
3. Introduce functions to return strings instead copy strings.
4. Check pointer to memzone of ring.
5. Remove redundant variable.
6. Hold lock when access ring data.

v3->v4:
1. Update changelog according to reviews of Honnappa Nagarahalli.
2. Add Reviewed-by Honnappa Nagarahalli.
3. Correct grammar in help information.
4. Correct spell warning on "te" reported by checkpatch.pl.
5. Use ring_walk() to query ring info instead of rte_ring_lookup().
6. Fix that type definition the flag field of rte_ring does not match the usage.
7. Use rte_tel_data_add_dict_uint_hex instead of rte_tel_data_add_dict_u64
   for mask and flags.

v4->v5:
1. Add Acked-by Konstantin Ananyev and Chengwen Feng.
2. Add ABI change explanation for commit message of patch 1/3.

v5->v6:
1. Add Acked-by Morten Br?rup.
2. Fix incorrect reference of commit.

v6->v7:
1. Remove prod/consumer head/tail info.

v7->v8:
1. Drop patch 1/3 and related codes.

Jie Hai (2):
  ring: add telemetry cmd to list rings
  ring: add telemetry cmd for ring info

 lib/ring/meson.build |   1 +
 lib/ring/rte_ring.c  | 135 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 136 insertions(+)

-- 
2.30.0


^ permalink raw reply	[relevance 3%]

* Re: [RESEND v7 1/3] ring: fix unmatched type definition and usage
  2024-02-18 18:11  3%     ` Thomas Monjalon
@ 2024-02-19  8:24  0%       ` Jie Hai
  0 siblings, 0 replies; 200+ results
From: Jie Hai @ 2024-02-19  8:24 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: honnappa.nagarahalli, konstantin.v.ananyev, dev, david.marchand,
	Ruifeng.Wang, mb, lihuisong, fengchengwen, liudongdong3

On 2024/2/19 2:11, Thomas Monjalon wrote:
> 09/11/2023 11:20, Jie Hai:
>> Field 'flags' of struct rte_ring is defined as int type. However,
>> it is used as unsigned int. To ensure consistency, change the
>> type of flags to unsigned int. Since these two types has the
>> same byte size, this change is not an ABI change.
>>
>> Fixes: af75078fece3 ("first public release")
>>
>> Signed-off-by: Jie Hai <haijie1@huawei.com>
>> Acked-by: Konstantin Ananyev <konstantin.v.ananyev@yandex.ru>
>> Acked-by: Chengwen Feng <fengchengwen@huawei.com>
>> Acked-by: Morten Brørup <mb@smartsharesystems.com>
>> ---
>>   lib/ring/rte_ring_core.h | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/lib/ring/rte_ring_core.h b/lib/ring/rte_ring_core.h
>> index b7708730658a..14dac6495d83 100644
>> --- a/lib/ring/rte_ring_core.h
>> +++ b/lib/ring/rte_ring_core.h
>> @@ -119,7 +119,7 @@ struct rte_ring_hts_headtail {
>>   struct rte_ring {
>>   	char name[RTE_RING_NAMESIZE] __rte_cache_aligned;
>>   	/**< Name of the ring. */
>> -	int flags;               /**< Flags supplied at creation. */
>> +	uint32_t flags;               /**< Flags supplied at creation. */
> 
> This triggers a warning in our ABI checker:
> 
>        in pointed to type 'struct rte_ring' at rte_ring_core.h:119:1:
>          type size hasn't changed
>          1 data member change:
>            type of 'int flags' changed:
>              entity changed from 'int' to compatible type 'typedef uint32_t' at stdint-uintn.h:26:1
>                type name changed from 'int' to 'unsigned int'
>                type size hasn't changed
> 
> I guess we were supposed to merge this in 23.11, sorry about this.
> 
> How can we proceed?
> 
How about we drop this amendment (patch 1/3) for now?
> 
> .

^ permalink raw reply	[relevance 0%]

* Re: [RESEND v7 1/3] ring: fix unmatched type definition and usage
  @ 2024-02-18 18:11  3%     ` Thomas Monjalon
  2024-02-19  8:24  0%       ` Jie Hai
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2024-02-18 18:11 UTC (permalink / raw)
  To: Jie Hai
  Cc: honnappa.nagarahalli, konstantin.v.ananyev, dev, david.marchand,
	Ruifeng.Wang, mb, lihuisong, fengchengwen, liudongdong3

09/11/2023 11:20, Jie Hai:
> Field 'flags' of struct rte_ring is defined as int type. However,
> it is used as unsigned int. To ensure consistency, change the
> type of flags to unsigned int. Since these two types has the
> same byte size, this change is not an ABI change.
> 
> Fixes: af75078fece3 ("first public release")
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> Acked-by: Konstantin Ananyev <konstantin.v.ananyev@yandex.ru>
> Acked-by: Chengwen Feng <fengchengwen@huawei.com>
> Acked-by: Morten Brørup <mb@smartsharesystems.com>
> ---
>  lib/ring/rte_ring_core.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/lib/ring/rte_ring_core.h b/lib/ring/rte_ring_core.h
> index b7708730658a..14dac6495d83 100644
> --- a/lib/ring/rte_ring_core.h
> +++ b/lib/ring/rte_ring_core.h
> @@ -119,7 +119,7 @@ struct rte_ring_hts_headtail {
>  struct rte_ring {
>  	char name[RTE_RING_NAMESIZE] __rte_cache_aligned;
>  	/**< Name of the ring. */
> -	int flags;               /**< Flags supplied at creation. */
> +	uint32_t flags;               /**< Flags supplied at creation. */

This triggers a warning in our ABI checker:

      in pointed to type 'struct rte_ring' at rte_ring_core.h:119:1:
        type size hasn't changed
        1 data member change:
          type of 'int flags' changed:
            entity changed from 'int' to compatible type 'typedef uint32_t' at stdint-uintn.h:26:1
              type name changed from 'int' to 'unsigned int'
              type size hasn't changed

I guess we were supposed to merge this in 23.11, sorry about this.

How can we proceed?



^ permalink raw reply	[relevance 3%]

* RE: [PATCH v4 01/18] mbuf: deprecate GCC marker in rte mbuf struct
  2024-02-18 12:39  0%     ` Thomas Monjalon
@ 2024-02-18 13:07  0%       ` Morten Brørup
  2024-02-20 17:20  0%       ` Tyler Retzlaff
  1 sibling, 0 replies; 200+ results
From: Morten Brørup @ 2024-02-18 13:07 UTC (permalink / raw)
  To: Thomas Monjalon, dev, Tyler Retzlaff
  Cc: Ajit Khaparde, Andrew Boyer, Andrew Rybchenko, Bruce Richardson,
	Chenbo Xia, Chengwen Feng, Dariusz Sosnowski, David Christensen,
	Hyong Youb Kim, Jerin Jacob, Jie Hai, Jingjing Wu, John Daley,
	Kevin Laatz, Kiran Kumar K, Konstantin Ananyev, Maciej Czekaj,
	Matan Azrad, Maxime Coquelin, Nithin Dabilpuram, Ori Kam,
	Ruifeng Wang, Satha Rao, Somnath Kotur, Suanming Mou,
	Sunil Kumar Kori, Viacheslav Ovsiienko, Yisen Zhuang,
	Yuying Zhang

> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Sunday, 18 February 2024 13.40
> 
> 15/02/2024 07:21, Tyler Retzlaff:
> > Provide a macro that allows conditional expansion of RTE_MARKER
> fields
> > to empty to allow rte_mbuf to be used with MSVC. It is proposed that
> > we announce the fields to be __rte_deprecated (currently disabled).
> >
> > Introduce C11 anonymous unions to permit aliasing of well-known
> > offsets by name into the rte_mbuf structure by a *new* name and to
> > provide padding for cache alignment.
> >
> > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> > ---
> >  doc/guides/rel_notes/deprecation.rst |  20 ++
> >  lib/eal/include/rte_common.h         |   6 +
> >  lib/mbuf/rte_mbuf_core.h             | 375 +++++++++++++++++++------
> ----------
> >  3 files changed, 233 insertions(+), 168 deletions(-)
> >
> > diff --git a/doc/guides/rel_notes/deprecation.rst
> b/doc/guides/rel_notes/deprecation.rst
> > index 10630ba..8594255 100644
> > --- a/doc/guides/rel_notes/deprecation.rst
> > +++ b/doc/guides/rel_notes/deprecation.rst
> > @@ -17,6 +17,26 @@ Other API and ABI deprecation notices are to be
> posted below.
> >  Deprecation Notices
> >  -------------------
> >
> > +* mbuf: Named zero sized fields of type ``RTE_MARKER`` and
> ``RTE_MARKER64``
> > +  will be removed from ``struct rte_mbuf`` and replaced with new
> fields
> > +  in anonymous unions.
> > +
> > +  The names of the fields impacted are:
> > +
> > +    old name                  new name
> > +
> > +  ``cacheline0``            ``mbuf_cachelin0``
> > +  ``rearm_data``            ``mbuf_rearm_data``
> > +  ``rx_descriptor_fields1`` ``mbuf_rx_descriptor_fields1``
> > +  ``cacheline1``            ``mbuf_cachelin1``
> > +
> > +  Contributions to DPDK should immediately start using the new
> names,
> > +  applications should adapt to new names as soon as possible as the
> > +  old names will be removed in a future DPDK release.
> > +
> > +  Note: types of the new names are not API compatible with the old
> and
> > +  some code conversion is required to maintain correct behavior.
> > +
> >  * build: The ``enable_kmods`` option is deprecated and will be
> removed in a future release.
> >    Setting/clearing the option has no impact on the build.
> >    Instead, kernel modules will be always built for OS's where out-
> of-tree kernel modules
> > diff --git a/lib/eal/include/rte_common.h
> b/lib/eal/include/rte_common.h
> > index d7d6390..af73f67 100644
> > --- a/lib/eal/include/rte_common.h
> > +++ b/lib/eal/include/rte_common.h
> > @@ -582,6 +582,12 @@ static void
> __attribute__((destructor(RTE_PRIO(prio)), used)) func(void)
> >  /** Marker for 8B alignment in a structure. */
> >  __extension__ typedef uint64_t RTE_MARKER64[0];
> >
> > +#define __rte_marker(type, name) type name /* __rte_deprecated */
> > +
> > +#else
> > +
> > +#define __rte_marker(type, name)
> > +
> >  #endif
> >
> >  /*********** Macros for calculating min and max **********/
> > diff --git a/lib/mbuf/rte_mbuf_core.h b/lib/mbuf/rte_mbuf_core.h
> > index 5688683..9e9590b 100644
> > --- a/lib/mbuf/rte_mbuf_core.h
> > +++ b/lib/mbuf/rte_mbuf_core.h
> > @@ -16,7 +16,10 @@
> >   * New fields and flags should fit in the "dynamic space".
> >   */
> >
> > +#include <assert.h>
> > +#include <stdalign.h>
> >  #include <stdint.h>
> > +#include <stddef.h>
> >
> >  #include <rte_byteorder.h>
> >  #include <rte_stdatomic.h>
> > @@ -464,204 +467,240 @@ enum {
> >   * The generic rte_mbuf, containing a packet mbuf.
> >   */
> >  struct rte_mbuf {
> > -	RTE_MARKER cacheline0;
> > -
> > -	void *buf_addr;           /**< Virtual address of segment buffer.
> */
> > +	__rte_marker(RTE_MARKER, cacheline0);
> 
> You don't need to keep the first argument.
> This would be simpler:
> 	__rte_marker(cacheline0);
> You just need to create 2 functions: __rte_marker and __rte_marker64.
> 
> You should replace all occurrences of RTE_MARKER in DPDK in one patch,
> and mark RTE_MARKER as deprecated (use #pragma GCC poison)

I like this suggestion.
However, some applications might use RTE_MARKER in their own structures.
Wouldn't it be considered API breakage to mark RTE_MARKER as deprecated?

> 
> > +	union {
> > +		char mbuf_cacheline0[RTE_CACHE_LINE_MIN_SIZE];
> > +		__extension__
> > +		struct {
> > +			void *buf_addr;           /**< Virtual address of
> segment buffer.
> 
> I think it is ugly.
> 
> Changing mbuf API is a serious issue.


^ permalink raw reply	[relevance 0%]

* Re: [PATCH v4 01/18] mbuf: deprecate GCC marker in rte mbuf struct
  2024-02-15  6:21  3%   ` [PATCH v4 01/18] mbuf: deprecate GCC marker in rte mbuf struct Tyler Retzlaff
@ 2024-02-18 12:39  0%     ` Thomas Monjalon
  2024-02-18 13:07  0%       ` Morten Brørup
  2024-02-20 17:20  0%       ` Tyler Retzlaff
  0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2024-02-18 12:39 UTC (permalink / raw)
  To: dev
  Cc: Ajit Khaparde, Andrew Boyer, Andrew Rybchenko, Bruce Richardson,
	Chenbo Xia, Chengwen Feng, Dariusz Sosnowski, David Christensen,
	Hyong Youb Kim, Jerin Jacob, Jie Hai, Jingjing Wu, John Daley,
	Kevin Laatz, Kiran Kumar K, Konstantin Ananyev, Maciej Czekaj,
	Matan Azrad, Maxime Coquelin, Nithin Dabilpuram, Ori Kam,
	Ruifeng Wang, Satha Rao, Somnath Kotur, Suanming Mou,
	Sunil Kumar Kori, Viacheslav Ovsiienko, Yisen Zhuang,
	Yuying Zhang, mb, Tyler Retzlaff

15/02/2024 07:21, Tyler Retzlaff:
> Provide a macro that allows conditional expansion of RTE_MARKER fields
> to empty to allow rte_mbuf to be used with MSVC. It is proposed that
> we announce the fields to be __rte_deprecated (currently disabled).
> 
> Introduce C11 anonymous unions to permit aliasing of well-known
> offsets by name into the rte_mbuf structure by a *new* name and to
> provide padding for cache alignment.
> 
> Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> ---
>  doc/guides/rel_notes/deprecation.rst |  20 ++
>  lib/eal/include/rte_common.h         |   6 +
>  lib/mbuf/rte_mbuf_core.h             | 375 +++++++++++++++++++----------------
>  3 files changed, 233 insertions(+), 168 deletions(-)
> 
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 10630ba..8594255 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -17,6 +17,26 @@ Other API and ABI deprecation notices are to be posted below.
>  Deprecation Notices
>  -------------------
>  
> +* mbuf: Named zero sized fields of type ``RTE_MARKER`` and ``RTE_MARKER64``
> +  will be removed from ``struct rte_mbuf`` and replaced with new fields
> +  in anonymous unions.
> +
> +  The names of the fields impacted are:
> +
> +    old name                  new name
> +
> +  ``cacheline0``            ``mbuf_cachelin0``
> +  ``rearm_data``            ``mbuf_rearm_data``
> +  ``rx_descriptor_fields1`` ``mbuf_rx_descriptor_fields1``
> +  ``cacheline1``            ``mbuf_cachelin1``
> +
> +  Contributions to DPDK should immediately start using the new names,
> +  applications should adapt to new names as soon as possible as the
> +  old names will be removed in a future DPDK release.
> +
> +  Note: types of the new names are not API compatible with the old and
> +  some code conversion is required to maintain correct behavior.
> +
>  * build: The ``enable_kmods`` option is deprecated and will be removed in a future release.
>    Setting/clearing the option has no impact on the build.
>    Instead, kernel modules will be always built for OS's where out-of-tree kernel modules
> diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h
> index d7d6390..af73f67 100644
> --- a/lib/eal/include/rte_common.h
> +++ b/lib/eal/include/rte_common.h
> @@ -582,6 +582,12 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void)
>  /** Marker for 8B alignment in a structure. */
>  __extension__ typedef uint64_t RTE_MARKER64[0];
>  
> +#define __rte_marker(type, name) type name /* __rte_deprecated */
> +
> +#else
> +
> +#define __rte_marker(type, name)
> +
>  #endif
>  
>  /*********** Macros for calculating min and max **********/
> diff --git a/lib/mbuf/rte_mbuf_core.h b/lib/mbuf/rte_mbuf_core.h
> index 5688683..9e9590b 100644
> --- a/lib/mbuf/rte_mbuf_core.h
> +++ b/lib/mbuf/rte_mbuf_core.h
> @@ -16,7 +16,10 @@
>   * New fields and flags should fit in the "dynamic space".
>   */
>  
> +#include <assert.h>
> +#include <stdalign.h>
>  #include <stdint.h>
> +#include <stddef.h>
>  
>  #include <rte_byteorder.h>
>  #include <rte_stdatomic.h>
> @@ -464,204 +467,240 @@ enum {
>   * The generic rte_mbuf, containing a packet mbuf.
>   */
>  struct rte_mbuf {
> -	RTE_MARKER cacheline0;
> -
> -	void *buf_addr;           /**< Virtual address of segment buffer. */
> +	__rte_marker(RTE_MARKER, cacheline0);

You don't need to keep the first argument.
This would be simpler:
	__rte_marker(cacheline0);
You just need to create 2 functions: __rte_marker and __rte_marker64.

You should replace all occurrences of RTE_MARKER in DPDK in one patch,
and mark RTE_MARKER as deprecated (use #pragma GCC poison)

> +	union {
> +		char mbuf_cacheline0[RTE_CACHE_LINE_MIN_SIZE];
> +		__extension__
> +		struct {
> +			void *buf_addr;           /**< Virtual address of segment buffer. 

I think it is ugly.

Changing mbuf API is a serious issue.



^ permalink raw reply	[relevance 0%]

* Re: [PATCH v2 0/4] more replacement of zero length array
  2024-02-16 10:14  0%         ` David Marchand
@ 2024-02-16 20:46  0%           ` Tyler Retzlaff
  0 siblings, 0 replies; 200+ results
From: Tyler Retzlaff @ 2024-02-16 20:46 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, Bruce Richardson, Cristian Dumitrescu, Honnappa Nagarahalli,
	Sameh Gobriel, Vladimir Medvedkin, Yipeng Wang, mb, fengchengwen,
	Dodji Seketeli

On Fri, Feb 16, 2024 at 11:14:27AM +0100, David Marchand wrote:
> On Wed, Feb 14, 2024 at 8:36 AM David Marchand
> <david.marchand@redhat.com> wrote:
> > > I'm okay with the change being merged but if there is concern I can drop
> > > this patch from the series.
> >
> > At least, we can't merge it in the current form.
> >
> > If libabigail gets a fix quickly, DPDK CI will still need a released version.
> > So for this patch to be merged now, we need a libabigail suppression rule.
> > I don't see a way to precisely waive this issue, so my suggestion is
> > to silence any change on the concerned structure here (which should be
> > ok, as the pipeline library data struct have been super stable for a
> > couple of years).
> > Something like:
> >
> > $ git diff
> > diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
> > index 21b8cd6113..d667157909 100644
> > --- a/devtools/libabigail.abignore
> > +++ b/devtools/libabigail.abignore
> > @@ -33,3 +33,5 @@
> >  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> >  ; Temporary exceptions till next major ABI version ;
> >  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> > +[suppress_type]
> > +       name = rte_pipeline_table_entry
> 
> Dodji confirmed the issue in libabigail and prepared a fix.
> 
> DPDK still needs a suppression rule (like the one proposed above) if
> we want to merge this change before the libabigail fix makes it to all
> distribs.
> Please resubmit this series with my proposal and a comment pointing at
> libabigail bz squashed in patch 4.

this works out conveniently, i noticed there are a few more instances
that i'll try to add to this series so i'll come back with a new rev.

i've marked the series changes requested in patchwork for now.

> 
> 
> -- 
> David Marchand

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] doc: update minimum Linux kernel version
  2024-02-16  8:29  0%             ` Morten Brørup
@ 2024-02-16 17:22  0%               ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2024-02-16 17:22 UTC (permalink / raw)
  To: Morten Brørup; +Cc: Patrick Robb, Aaron Conole, dev

On Fri, 16 Feb 2024 09:29:47 +0100
Morten Brørup <mb@smartsharesystems.com> wrote:

> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Friday, 16 February 2024 04.05
> > 
> > On Thu, 11 Jan 2024 23:38:07 +0100
> > Morten Brørup <mb@smartsharesystems.com> wrote:
> >   
> > > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > > Sent: Thursday, 11 January 2024 20.55
> > > >
> > > > On Thu, 11 Jan 2024 20:26:56 +0100
> > > > Morten Brørup <mb@smartsharesystems.com> wrote:
> > > >  
> > > > >
> > > > >
> > > > > When the documentation specifies a minimum required kernel  
> > version,  
> > > > it implicitly claims that DPDK works with that kernel version.  
> > > > >
> > > > > So we should either test with the specified kernel version (which  
> > > > requires significant effort to set up, so I’m not going to ask for
> > > > it!), or add a big fat disclaimer/warning that DPDK is not tested  
> > with  
> > > > the mentioned kernel version, and list the kernel versions actually
> > > > tested.
> > > >
> > > > It is much less of an issue than it used to be since there should  
> > be no  
> > > > need for
> > > > DPDK specific kernel components. The kernel API/ABI is stable  
> > across  
> > > > releases
> > > > (with the notable exception of BPF). Therefore the DPDK kernel  
> > version  
> > > > dependency
> > > > is much less than it used to be.  
> > 
> > There are three issues here:
> > 
> > 1. Supporting out of date kernel also means supporting out of date
> > build environments
> >    that maybe missing headers. The recent example was the TAP device
> > requiring (or cloning
> >    which is worse) the headers to the FLOWER classifier.  If we move
> > the kernel version
> >    to current LTS, then FLOWER is always present.
> > 2. Supporting out of date kernel means more test infrastructure. Some
> > CI needs to build
> >    test on older environments.
> > 3. The place it impacts current CI is the building on CentOS7. CentOS7
> > is end of life
> >    do we have to keep it? The compiler also lack good C11 support so
> > not sure how CI keeps working.
> > 
> > The way I view it, if you are on an old system, then stick to old DPDK
> > LTS version.
> > We don't want to here about regressions on end of life systems.  
> 
> The system requirements in the Getting Started Guide [1] says:
> 
> Kernel version >= 4.14
> The kernel version required is based on the oldest long term stable kernel available at kernel.org when the DPDK version is in development.
> Compatibility for recent distribution kernels will be kept, notably RHEL/CentOS 7.

We need to drop CentOS 7 soon.

https://www.redhat.com/en/topics/linux/centos-linux-eol

	CentOS Linux 7 will reach end of life (EOL) on June 30, 2024. 

^ permalink raw reply	[relevance 0%]

* Re: [PATCH v2] lib/hash: new feature adding existing key
  @ 2024-02-16 12:43  3%   ` Thomas Monjalon
  0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2024-02-16 12:43 UTC (permalink / raw)
  To: dev
  Cc: Abdullah Ömer Yamaç,
	Yipeng Wang, Sameh Gobriel, Bruce Richardson, Vladimir Medvedkin,
	David Marchand, Abdullah Ömer Yamaç

Any review please?
If maintainers agree with the idea, we should announce the ABI change.


23/10/2023 10:29, Abdullah Ömer Yamaç:
> From: Abdullah Ömer Yamaç <omer.yamac@ceng.metu.edu.tr>
> 
> In some use cases inserting data with the same key shouldn't be
> overwritten. We use a new flag in this patch to disable overwriting
> data for the same key.
> 
> Signed-off-by: Abdullah Ömer Yamaç <omer.yamac@ceng.metu.edu.tr>
> 
> ---
> Cc: Yipeng Wang <yipeng1.wang@intel.com>
> Cc: Sameh Gobriel <sameh.gobriel@intel.com>
> Cc: Bruce Richardson <bruce.richardson@intel.com>
> Cc: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
> Cc: David Marchand <david.marchand@redhat.com>
> ---
>  lib/hash/rte_cuckoo_hash.c | 10 +++++++++-
>  lib/hash/rte_cuckoo_hash.h |  2 ++
>  lib/hash/rte_hash.h        |  4 ++++
>  3 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/hash/rte_cuckoo_hash.c b/lib/hash/rte_cuckoo_hash.c
> index 19b23f2a97..fe8f21bee4 100644
> --- a/lib/hash/rte_cuckoo_hash.c
> +++ b/lib/hash/rte_cuckoo_hash.c
> @@ -32,7 +32,8 @@
>  				   RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY | \
>  				   RTE_HASH_EXTRA_FLAGS_EXT_TABLE |	\
>  				   RTE_HASH_EXTRA_FLAGS_NO_FREE_ON_DEL | \
> -				   RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF)
> +				   RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF | \
> +				   RTE_HASH_EXTRA_FLAGS_DISABLE_UPDATE_EXISTING_KEY)
>  
>  #define FOR_EACH_BUCKET(CURRENT_BKT, START_BUCKET)                            \
>  	for (CURRENT_BKT = START_BUCKET;                                      \
> @@ -148,6 +149,7 @@ rte_hash_create(const struct rte_hash_parameters *params)
>  	unsigned int readwrite_concur_support = 0;
>  	unsigned int writer_takes_lock = 0;
>  	unsigned int no_free_on_del = 0;
> +	unsigned int no_update_data = 0;
>  	uint32_t *ext_bkt_to_free = NULL;
>  	uint32_t *tbl_chng_cnt = NULL;
>  	struct lcore_cache *local_free_slots = NULL;
> @@ -216,6 +218,9 @@ rte_hash_create(const struct rte_hash_parameters *params)
>  		no_free_on_del = 1;
>  	}
>  
> +	if (params->extra_flag & RTE_HASH_EXTRA_FLAGS_DISABLE_UPDATE_EXISTING_KEY)
> +		no_update_data = 1;
> +
>  	/* Store all keys and leave the first entry as a dummy entry for lookup_bulk */
>  	if (use_local_cache)
>  		/*
> @@ -428,6 +433,7 @@ rte_hash_create(const struct rte_hash_parameters *params)
>  	h->ext_table_support = ext_table_support;
>  	h->writer_takes_lock = writer_takes_lock;
>  	h->no_free_on_del = no_free_on_del;
> +	h->no_update_data = no_update_data;
>  	h->readwrite_concur_lf_support = readwrite_concur_lf_support;
>  
>  #if defined(RTE_ARCH_X86)
> @@ -707,6 +713,8 @@ search_and_update(const struct rte_hash *h, void *data, const void *key,
>  			k = (struct rte_hash_key *) ((char *)keys +
>  					bkt->key_idx[i] * h->key_entry_size);
>  			if (rte_hash_cmp_eq(key, k->key, h) == 0) {
> +				if (h->no_update_data == 1)
> +					return -EINVAL;
>  				/* The store to application data at *data
>  				 * should not leak after the store to pdata
>  				 * in the key store. i.e. pdata is the guard
> diff --git a/lib/hash/rte_cuckoo_hash.h b/lib/hash/rte_cuckoo_hash.h
> index eb2644f74b..e8b7283ec2 100644
> --- a/lib/hash/rte_cuckoo_hash.h
> +++ b/lib/hash/rte_cuckoo_hash.h
> @@ -193,6 +193,8 @@ struct rte_hash {
>  	/**< If read-write concurrency support is enabled */
>  	uint8_t ext_table_support;     /**< Enable extendable bucket table */
>  	uint8_t no_free_on_del;
> +	/**< If update is prohibited on adding same key */
> +	uint8_t no_update_data;
>  	/**< If key index should be freed on calling rte_hash_del_xxx APIs.
>  	 * If this is set, rte_hash_free_key_with_position must be called to
>  	 * free the key index associated with the deleted entry.
> diff --git a/lib/hash/rte_hash.h b/lib/hash/rte_hash.h
> index 7ecc021111..ca5b4841d2 100644
> --- a/lib/hash/rte_hash.h
> +++ b/lib/hash/rte_hash.h
> @@ -55,6 +55,10 @@ extern "C" {
>   */
>  #define RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF 0x20
>  
> +/** Flag to disable updating data of existing key
> + */
> +#define RTE_HASH_EXTRA_FLAGS_DISABLE_UPDATE_EXISTING_KEY 0x40
> +
>  /**
>   * The type of hash value of a key.
>   * It should be a value of at least 32bit with fully random pattern.
> 






^ permalink raw reply	[relevance 3%]

* Re: [PATCH v2 0/4] more replacement of zero length array
  2024-02-14  7:36  4%       ` David Marchand
@ 2024-02-16 10:14  0%         ` David Marchand
  2024-02-16 20:46  0%           ` Tyler Retzlaff
  0 siblings, 1 reply; 200+ results
From: David Marchand @ 2024-02-16 10:14 UTC (permalink / raw)
  To: Tyler Retzlaff
  Cc: dev, Bruce Richardson, Cristian Dumitrescu, Honnappa Nagarahalli,
	Sameh Gobriel, Vladimir Medvedkin, Yipeng Wang, mb, fengchengwen,
	Dodji Seketeli

On Wed, Feb 14, 2024 at 8:36 AM David Marchand
<david.marchand@redhat.com> wrote:
> > I'm okay with the change being merged but if there is concern I can drop
> > this patch from the series.
>
> At least, we can't merge it in the current form.
>
> If libabigail gets a fix quickly, DPDK CI will still need a released version.
> So for this patch to be merged now, we need a libabigail suppression rule.
> I don't see a way to precisely waive this issue, so my suggestion is
> to silence any change on the concerned structure here (which should be
> ok, as the pipeline library data struct have been super stable for a
> couple of years).
> Something like:
>
> $ git diff
> diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
> index 21b8cd6113..d667157909 100644
> --- a/devtools/libabigail.abignore
> +++ b/devtools/libabigail.abignore
> @@ -33,3 +33,5 @@
>  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>  ; Temporary exceptions till next major ABI version ;
>  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> +[suppress_type]
> +       name = rte_pipeline_table_entry

Dodji confirmed the issue in libabigail and prepared a fix.

DPDK still needs a suppression rule (like the one proposed above) if
we want to merge this change before the libabigail fix makes it to all
distribs.
Please resubmit this series with my proposal and a comment pointing at
libabigail bz squashed in patch 4.


-- 
David Marchand


^ permalink raw reply	[relevance 0%]

* RE: [PATCH] doc: update minimum Linux kernel version
  2024-02-16  3:05  0%           ` Stephen Hemminger
@ 2024-02-16  8:29  0%             ` Morten Brørup
  2024-02-16 17:22  0%               ` Stephen Hemminger
  0 siblings, 1 reply; 200+ results
From: Morten Brørup @ 2024-02-16  8:29 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Patrick Robb, Aaron Conole, dev

> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Friday, 16 February 2024 04.05
> 
> On Thu, 11 Jan 2024 23:38:07 +0100
> Morten Brørup <mb@smartsharesystems.com> wrote:
> 
> > > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > > Sent: Thursday, 11 January 2024 20.55
> > >
> > > On Thu, 11 Jan 2024 20:26:56 +0100
> > > Morten Brørup <mb@smartsharesystems.com> wrote:
> > >
> > > >
> > > >
> > > > When the documentation specifies a minimum required kernel
> version,
> > > it implicitly claims that DPDK works with that kernel version.
> > > >
> > > > So we should either test with the specified kernel version (which
> > > requires significant effort to set up, so I’m not going to ask for
> > > it!), or add a big fat disclaimer/warning that DPDK is not tested
> with
> > > the mentioned kernel version, and list the kernel versions actually
> > > tested.
> > >
> > > It is much less of an issue than it used to be since there should
> be no
> > > need for
> > > DPDK specific kernel components. The kernel API/ABI is stable
> across
> > > releases
> > > (with the notable exception of BPF). Therefore the DPDK kernel
> version
> > > dependency
> > > is much less than it used to be.
> 
> There are three issues here:
> 
> 1. Supporting out of date kernel also means supporting out of date
> build environments
>    that maybe missing headers. The recent example was the TAP device
> requiring (or cloning
>    which is worse) the headers to the FLOWER classifier.  If we move
> the kernel version
>    to current LTS, then FLOWER is always present.
> 2. Supporting out of date kernel means more test infrastructure. Some
> CI needs to build
>    test on older environments.
> 3. The place it impacts current CI is the building on CentOS7. CentOS7
> is end of life
>    do we have to keep it? The compiler also lack good C11 support so
> not sure how CI keeps working.
> 
> The way I view it, if you are on an old system, then stick to old DPDK
> LTS version.
> We don't want to here about regressions on end of life systems.

The system requirements in the Getting Started Guide [1] says:

Kernel version >= 4.14
The kernel version required is based on the oldest long term stable kernel available at kernel.org when the DPDK version is in development.
Compatibility for recent distribution kernels will be kept, notably RHEL/CentOS 7.

[1]: https://doc.dpdk.org/guides/linux_gsg/sys_reqs.html#system-software

If we consider it API breakage to change that, we have to wait until the 24.11 release.
For future DPDK LTS releases, we should be more careful about what we claim to support. And again: If we claim to support something, people expect it to be tested in CI.

Disregarding the API breakage by stopping support for a system we claim to support... RHEL7 testing was changed to LTS only [2], that should probably have been applied to CentOS 7 too.

[2]: https://inbox.dpdk.org/dev/CAJvnSUBcq3gznQD4k=krQ+gu2OxTxA2YJBc=J=LtidFXqgg_hg@mail.gmail.com/



^ permalink raw reply	[relevance 0%]

* Re: [PATCH] doc: update minimum Linux kernel version
  2024-01-11 22:38  0%         ` Morten Brørup
@ 2024-02-16  3:05  0%           ` Stephen Hemminger
  2024-02-16  8:29  0%             ` Morten Brørup
  0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2024-02-16  3:05 UTC (permalink / raw)
  To: Morten Brørup; +Cc: Patrick Robb, Aaron Conole, dev

On Thu, 11 Jan 2024 23:38:07 +0100
Morten Brørup <mb@smartsharesystems.com> wrote:

> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Thursday, 11 January 2024 20.55
> > 
> > On Thu, 11 Jan 2024 20:26:56 +0100
> > Morten Brørup <mb@smartsharesystems.com> wrote:
> >   
> > >
> > >
> > > When the documentation specifies a minimum required kernel version,  
> > it implicitly claims that DPDK works with that kernel version.  
> > >
> > > So we should either test with the specified kernel version (which  
> > requires significant effort to set up, so I’m not going to ask for
> > it!), or add a big fat disclaimer/warning that DPDK is not tested with
> > the mentioned kernel version, and list the kernel versions actually
> > tested.
> > 
> > It is much less of an issue than it used to be since there should be no
> > need for
> > DPDK specific kernel components. The kernel API/ABI is stable across
> > releases
> > (with the notable exception of BPF). Therefore the DPDK kernel version
> > dependency
> > is much less than it used to be.  

There are three issues here:

1. Supporting out of date kernel also means supporting out of date build environments
   that maybe missing headers. The recent example was the TAP device requiring (or cloning
   which is worse) the headers to the FLOWER classifier.  If we move the kernel version
   to current LTS, then FLOWER is always present.
2. Supporting out of date kernel means more test infrastructure. Some CI needs to build
   test on older environments.
3. The place it impacts current CI is the building on CentOS7. CentOS7 is end of life
   do we have to keep it? The compiler also lack good C11 support so not sure how CI keeps working.

The way I view it, if you are on an old system, then stick to old DPDK LTS version.
We don't want to here about regressions on end of life systems.

^ permalink raw reply	[relevance 0%]

* [PATCH 0/7] add Nitrox compress device support
@ 2024-02-15 12:48  3% Nagadheeraj Rottela
  2024-02-29 17:22  0% ` Akhil Goyal
  0 siblings, 1 reply; 200+ results
From: Nagadheeraj Rottela @ 2024-02-15 12:48 UTC (permalink / raw)
  To: gakhil, fanzhang.oss, ashishg; +Cc: dev, Nagadheeraj Rottela

Add the Nitrox PMD to support Nitrox compress device.
---
v3:
* Fixed ABI compatibility issue.

v2:
* Reformatted patches to minimize number of changes.
* Removed empty file with only copyright.
* Updated all feature flags in nitrox.ini file.
* Added separate gotos in nitrox_pci_probe() function.

Nagadheeraj Rottela (7):
  crypto/nitrox: move nitrox common code to common folder
  compress/nitrox: add nitrox compressdev driver
  common/nitrox: add compress hardware queue management
  crypto/nitrox: set queue type during queue pair setup
  compress/nitrox: add software queue management
  compress/nitrox: add stateless request support
  compress/nitrox: add stateful request support

 MAINTAINERS                                   |    8 +
 doc/guides/compressdevs/features/nitrox.ini   |   17 +
 doc/guides/compressdevs/index.rst             |    1 +
 doc/guides/compressdevs/nitrox.rst            |   50 +
 drivers/common/nitrox/meson.build             |   19 +
 .../{crypto => common}/nitrox/nitrox_csr.h    |   12 +
 .../{crypto => common}/nitrox/nitrox_device.c |   51 +-
 .../{crypto => common}/nitrox/nitrox_device.h |    4 +-
 .../{crypto => common}/nitrox/nitrox_hal.c    |  116 ++
 .../{crypto => common}/nitrox/nitrox_hal.h    |  115 ++
 .../{crypto => common}/nitrox/nitrox_logs.c   |    0
 .../{crypto => common}/nitrox/nitrox_logs.h   |    0
 drivers/{crypto => common}/nitrox/nitrox_qp.c |   53 +-
 drivers/{crypto => common}/nitrox/nitrox_qp.h |   37 +-
 drivers/common/nitrox/version.map             |    9 +
 drivers/compress/nitrox/meson.build           |   16 +
 drivers/compress/nitrox/nitrox_comp.c         |  604 +++++++++
 drivers/compress/nitrox/nitrox_comp.h         |   35 +
 drivers/compress/nitrox/nitrox_comp_reqmgr.c  | 1199 +++++++++++++++++
 drivers/compress/nitrox/nitrox_comp_reqmgr.h  |   58 +
 drivers/crypto/nitrox/meson.build             |   11 +-
 drivers/crypto/nitrox/nitrox_sym.c            |    1 +
 drivers/meson.build                           |    1 +
 23 files changed, 2396 insertions(+), 21 deletions(-)
 create mode 100644 doc/guides/compressdevs/features/nitrox.ini
 create mode 100644 doc/guides/compressdevs/nitrox.rst
 create mode 100644 drivers/common/nitrox/meson.build
 rename drivers/{crypto => common}/nitrox/nitrox_csr.h (67%)
 rename drivers/{crypto => common}/nitrox/nitrox_device.c (77%)
 rename drivers/{crypto => common}/nitrox/nitrox_device.h (81%)
 rename drivers/{crypto => common}/nitrox/nitrox_hal.c (65%)
 rename drivers/{crypto => common}/nitrox/nitrox_hal.h (59%)
 rename drivers/{crypto => common}/nitrox/nitrox_logs.c (100%)
 rename drivers/{crypto => common}/nitrox/nitrox_logs.h (100%)
 rename drivers/{crypto => common}/nitrox/nitrox_qp.c (69%)
 rename drivers/{crypto => common}/nitrox/nitrox_qp.h (75%)
 create mode 100644 drivers/common/nitrox/version.map
 create mode 100644 drivers/compress/nitrox/meson.build
 create mode 100644 drivers/compress/nitrox/nitrox_comp.c
 create mode 100644 drivers/compress/nitrox/nitrox_comp.h
 create mode 100644 drivers/compress/nitrox/nitrox_comp_reqmgr.c
 create mode 100644 drivers/compress/nitrox/nitrox_comp_reqmgr.h

-- 
2.42.0


^ permalink raw reply	[relevance 3%]

* [PATCH v4 01/18] mbuf: deprecate GCC marker in rte mbuf struct
  @ 2024-02-15  6:21  3%   ` Tyler Retzlaff
  2024-02-18 12:39  0%     ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Tyler Retzlaff @ 2024-02-15  6:21 UTC (permalink / raw)
  To: dev
  Cc: Ajit Khaparde, Andrew Boyer, Andrew Rybchenko, Bruce Richardson,
	Chenbo Xia, Chengwen Feng, Dariusz Sosnowski, David Christensen,
	Hyong Youb Kim, Jerin Jacob, Jie Hai, Jingjing Wu, John Daley,
	Kevin Laatz, Kiran Kumar K, Konstantin Ananyev, Maciej Czekaj,
	Matan Azrad, Maxime Coquelin, Nithin Dabilpuram, Ori Kam,
	Ruifeng Wang, Satha Rao, Somnath Kotur, Suanming Mou,
	Sunil Kumar Kori, Viacheslav Ovsiienko, Yisen Zhuang,
	Yuying Zhang, mb, Tyler Retzlaff

Provide a macro that allows conditional expansion of RTE_MARKER fields
to empty to allow rte_mbuf to be used with MSVC. It is proposed that
we announce the fields to be __rte_deprecated (currently disabled).

Introduce C11 anonymous unions to permit aliasing of well-known
offsets by name into the rte_mbuf structure by a *new* name and to
provide padding for cache alignment.

Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
---
 doc/guides/rel_notes/deprecation.rst |  20 ++
 lib/eal/include/rte_common.h         |   6 +
 lib/mbuf/rte_mbuf_core.h             | 375 +++++++++++++++++++----------------
 3 files changed, 233 insertions(+), 168 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 10630ba..8594255 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -17,6 +17,26 @@ Other API and ABI deprecation notices are to be posted below.
 Deprecation Notices
 -------------------
 
+* mbuf: Named zero sized fields of type ``RTE_MARKER`` and ``RTE_MARKER64``
+  will be removed from ``struct rte_mbuf`` and replaced with new fields
+  in anonymous unions.
+
+  The names of the fields impacted are:
+
+    old name                  new name
+
+  ``cacheline0``            ``mbuf_cachelin0``
+  ``rearm_data``            ``mbuf_rearm_data``
+  ``rx_descriptor_fields1`` ``mbuf_rx_descriptor_fields1``
+  ``cacheline1``            ``mbuf_cachelin1``
+
+  Contributions to DPDK should immediately start using the new names,
+  applications should adapt to new names as soon as possible as the
+  old names will be removed in a future DPDK release.
+
+  Note: types of the new names are not API compatible with the old and
+  some code conversion is required to maintain correct behavior.
+
 * build: The ``enable_kmods`` option is deprecated and will be removed in a future release.
   Setting/clearing the option has no impact on the build.
   Instead, kernel modules will be always built for OS's where out-of-tree kernel modules
diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h
index d7d6390..af73f67 100644
--- a/lib/eal/include/rte_common.h
+++ b/lib/eal/include/rte_common.h
@@ -582,6 +582,12 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void)
 /** Marker for 8B alignment in a structure. */
 __extension__ typedef uint64_t RTE_MARKER64[0];
 
+#define __rte_marker(type, name) type name /* __rte_deprecated */
+
+#else
+
+#define __rte_marker(type, name)
+
 #endif
 
 /*********** Macros for calculating min and max **********/
diff --git a/lib/mbuf/rte_mbuf_core.h b/lib/mbuf/rte_mbuf_core.h
index 5688683..9e9590b 100644
--- a/lib/mbuf/rte_mbuf_core.h
+++ b/lib/mbuf/rte_mbuf_core.h
@@ -16,7 +16,10 @@
  * New fields and flags should fit in the "dynamic space".
  */
 
+#include <assert.h>
+#include <stdalign.h>
 #include <stdint.h>
+#include <stddef.h>
 
 #include <rte_byteorder.h>
 #include <rte_stdatomic.h>
@@ -464,204 +467,240 @@ enum {
  * The generic rte_mbuf, containing a packet mbuf.
  */
 struct rte_mbuf {
-	RTE_MARKER cacheline0;
-
-	void *buf_addr;           /**< Virtual address of segment buffer. */
+	__rte_marker(RTE_MARKER, cacheline0);
+	union {
+		char mbuf_cacheline0[RTE_CACHE_LINE_MIN_SIZE];
+		__extension__
+		struct {
+			void *buf_addr;           /**< Virtual address of segment buffer. */
 #if RTE_IOVA_IN_MBUF
-	/**
-	 * Physical address of segment buffer.
-	 * This field is undefined if the build is configured to use only
-	 * virtual address as IOVA (i.e. RTE_IOVA_IN_MBUF is 0).
-	 * Force alignment to 8-bytes, so as to ensure we have the exact
-	 * same mbuf cacheline0 layout for 32-bit and 64-bit. This makes
-	 * working on vector drivers easier.
-	 */
-	rte_iova_t buf_iova __rte_aligned(sizeof(rte_iova_t));
+			/**
+			 * Physical address of segment buffer.
+			 * This field is undefined if the build is configured to use only
+			 * virtual address as IOVA (i.e. RTE_IOVA_IN_MBUF is 0).
+			 * Force alignment to 8-bytes, so as to ensure we have the exact
+			 * same mbuf cacheline0 layout for 32-bit and 64-bit. This makes
+			 * working on vector drivers easier.
+			 */
+			rte_iova_t buf_iova __rte_aligned(sizeof(rte_iova_t));
 #else
-	/**
-	 * Next segment of scattered packet.
-	 * This field is valid when physical address field is undefined.
-	 * Otherwise next pointer in the second cache line will be used.
-	 */
-	struct rte_mbuf *next;
+			/**
+			 * Next segment of scattered packet.
+			 * This field is valid when physical address field is undefined.
+			 * Otherwise next pointer in the second cache line will be used.
+			 */
+			struct rte_mbuf *next;
 #endif
 
-	/* next 8 bytes are initialised on RX descriptor rearm */
-	RTE_MARKER64 rearm_data;
-	uint16_t data_off;
-
-	/**
-	 * Reference counter. Its size should at least equal to the size
-	 * of port field (16 bits), to support zero-copy broadcast.
-	 * It should only be accessed using the following functions:
-	 * rte_mbuf_refcnt_update(), rte_mbuf_refcnt_read(), and
-	 * rte_mbuf_refcnt_set(). The functionality of these functions (atomic,
-	 * or non-atomic) is controlled by the RTE_MBUF_REFCNT_ATOMIC flag.
-	 */
-	RTE_ATOMIC(uint16_t) refcnt;
-
-	/**
-	 * Number of segments. Only valid for the first segment of an mbuf
-	 * chain.
-	 */
-	uint16_t nb_segs;
-
-	/** Input port (16 bits to support more than 256 virtual ports).
-	 * The event eth Tx adapter uses this field to specify the output port.
-	 */
-	uint16_t port;
-
-	uint64_t ol_flags;        /**< Offload features. */
+			/* next 8 bytes are initialised on RX descriptor rearm */
+			__rte_marker(RTE_MARKER64, rearm_data);
+			union {
+				char mbuf_rearm_data[8];
+				__extension__
+				struct {
+					uint16_t data_off;
+
+					/**
+					 * Reference counter. Its size should at least equal to the
+					 * size of port field (16 bits), to support zero-copy
+					 * broadcast.
+					 * It should only be accessed using the following
+					 * functions:
+					 * rte_mbuf_refcnt_update(), rte_mbuf_refcnt_read(), and
+					 * rte_mbuf_refcnt_set(). The functionality of these
+					 * functions (atomic, or non-atomic) is controlled by the
+					 * RTE_MBUF_REFCNT_ATOMIC flag.
+					 */
+					RTE_ATOMIC(uint16_t) refcnt;
+
+					/**
+					 * Number of segments. Only valid for the first segment of
+					 * an mbuf chain.
+					 */
+					uint16_t nb_segs;
+
+					/**
+					 * Input port (16 bits to support more than 256 virtual
+					 * ports).  The event eth Tx adapter uses this field to
+					 * specify the output port.
+					 */
+					uint16_t port;
+				};
+			};
 
-	/* remaining bytes are set on RX when pulling packet from descriptor */
-	RTE_MARKER rx_descriptor_fields1;
+			uint64_t ol_flags;        /**< Offload features. */
 
-	/*
-	 * The packet type, which is the combination of outer/inner L2, L3, L4
-	 * and tunnel types. The packet_type is about data really present in the
-	 * mbuf. Example: if vlan stripping is enabled, a received vlan packet
-	 * would have RTE_PTYPE_L2_ETHER and not RTE_PTYPE_L2_VLAN because the
-	 * vlan is stripped from the data.
-	 */
-	union {
-		uint32_t packet_type; /**< L2/L3/L4 and tunnel information. */
-		__extension__
-		struct {
-			uint8_t l2_type:4;   /**< (Outer) L2 type. */
-			uint8_t l3_type:4;   /**< (Outer) L3 type. */
-			uint8_t l4_type:4;   /**< (Outer) L4 type. */
-			uint8_t tun_type:4;  /**< Tunnel type. */
+			/* remaining bytes are set on RX when pulling packet from descriptor */
+			__rte_marker(RTE_MARKER, rx_descriptor_fields1);
 			union {
-				uint8_t inner_esp_next_proto;
-				/**< ESP next protocol type, valid if
-				 * RTE_PTYPE_TUNNEL_ESP tunnel type is set
-				 * on both Tx and Rx.
-				 */
+				char mbuf_rx_descriptor_fields1[8];
 				__extension__
 				struct {
-					uint8_t inner_l2_type:4;
-					/**< Inner L2 type. */
-					uint8_t inner_l3_type:4;
-					/**< Inner L3 type. */
+					/*
+					 * The packet type, which is the combination of outer/inner
+					 * L2, L3, L4 and tunnel types. The packet_type is about
+					 * data really present in the mbuf. Example: if vlan
+					 * stripping is enabled, a received vlan packet would have
+					 * RTE_PTYPE_L2_ETHER and not RTE_PTYPE_L2_VLAN because the
+					 * vlan is stripped from the data.
+					 */
+					union {
+						uint32_t packet_type;
+						/**< L2/L3/L4 and tunnel information. */
+						__extension__
+						struct {
+							uint8_t l2_type:4;
+							/**< (Outer) L2 type. */
+							uint8_t l3_type:4;
+							/**< (Outer) L3 type. */
+							uint8_t l4_type:4;
+							/**< (Outer) L4 type. */
+							uint8_t tun_type:4;
+							/**< Tunnel type. */
+							union {
+								uint8_t inner_esp_next_proto;
+								/**< ESP next protocol type, valid
+								 * if RTE_PTYPE_TUNNEL_ESP tunnel
+								 * type is set on both Tx and Rx.
+								 */
+								__extension__
+								struct {
+									uint8_t inner_l2_type:4;
+									/**< Inner L2 type. */
+									uint8_t inner_l3_type:4;
+									/**< Inner L3 type. */
+								};
+							};
+							uint8_t inner_l4_type:4;
+							/**< Inner L4 type. */
+						};
+					};
+					uint32_t pkt_len;
+					/**< Total pkt len: sum of all segments. */
 				};
 			};
-			uint8_t inner_l4_type:4; /**< Inner L4 type. */
-		};
-	};
 
-	uint32_t pkt_len;         /**< Total pkt len: sum of all segments. */
-	uint16_t data_len;        /**< Amount of data in segment buffer. */
-	/** VLAN TCI (CPU order), valid if RTE_MBUF_F_RX_VLAN is set. */
-	uint16_t vlan_tci;
+			uint16_t data_len;        /**< Amount of data in segment buffer. */
+			/** VLAN TCI (CPU order), valid if RTE_MBUF_F_RX_VLAN is set. */
+			uint16_t vlan_tci;
 
-	union {
-		union {
-			uint32_t rss;     /**< RSS hash result if RSS enabled */
-			struct {
+			union {
 				union {
+					uint32_t rss;     /**< RSS hash result if RSS enabled */
 					struct {
-						uint16_t hash;
-						uint16_t id;
-					};
-					uint32_t lo;
-					/**< Second 4 flexible bytes */
-				};
-				uint32_t hi;
-				/**< First 4 flexible bytes or FD ID, dependent
-				 * on RTE_MBUF_F_RX_FDIR_* flag in ol_flags.
-				 */
-			} fdir;	/**< Filter identifier if FDIR enabled */
-			struct rte_mbuf_sched sched;
-			/**< Hierarchical scheduler : 8 bytes */
-			struct {
-				uint32_t reserved1;
-				uint16_t reserved2;
-				uint16_t txq;
-				/**< The event eth Tx adapter uses this field
-				 * to store Tx queue id.
-				 * @see rte_event_eth_tx_adapter_txq_set()
-				 */
-			} txadapter; /**< Eventdev ethdev Tx adapter */
-			uint32_t usr;
-			/**< User defined tags. See rte_distributor_process() */
-		} hash;                   /**< hash information */
-	};
+						union {
+							__extension__
+							struct {
+								uint16_t hash;
+								uint16_t id;
+							};
+							uint32_t lo;
+							/**< Second 4 flexible bytes */
+						};
+						uint32_t hi;
+						/**< First 4 flexible bytes or FD ID, dependent
+						 * on RTE_MBUF_F_RX_FDIR_* flag in ol_flags.
+						 */
+					} fdir;	/**< Filter identifier if FDIR enabled */
+					struct rte_mbuf_sched sched;
+					/**< Hierarchical scheduler : 8 bytes */
+					struct {
+						uint32_t reserved1;
+						uint16_t reserved2;
+						uint16_t txq;
+						/**< The event eth Tx adapter uses this field
+						 * to store Tx queue id.
+						 * @see rte_event_eth_tx_adapter_txq_set()
+						 */
+					} txadapter; /**< Eventdev ethdev Tx adapter */
+					uint32_t usr;
+					/**< User defined tags. See rte_distributor_process() */
+				} hash;                   /**< hash information */
+			};
 
-	/** Outer VLAN TCI (CPU order), valid if RTE_MBUF_F_RX_QINQ is set. */
-	uint16_t vlan_tci_outer;
+			/** Outer VLAN TCI (CPU order), valid if RTE_MBUF_F_RX_QINQ is set. */
+			uint16_t vlan_tci_outer;
 
-	uint16_t buf_len;         /**< Length of segment buffer. */
+			uint16_t buf_len;         /**< Length of segment buffer. */
 
-	struct rte_mempool *pool; /**< Pool from which mbuf was allocated. */
+			struct rte_mempool *pool; /**< Pool from which mbuf was allocated. */
+		};
+	};
 
 	/* second cache line - fields only used in slow path or on TX */
-	RTE_MARKER cacheline1 __rte_cache_min_aligned;
-
-#if RTE_IOVA_IN_MBUF
-	/**
-	 * Next segment of scattered packet. Must be NULL in the last
-	 * segment or in case of non-segmented packet.
-	 */
-	struct rte_mbuf *next;
-#else
-	/**
-	 * Reserved for dynamic fields
-	 * when the next pointer is in first cache line (i.e. RTE_IOVA_IN_MBUF is 0).
-	 */
-	uint64_t dynfield2;
-#endif
-
-	/* fields to support TX offloads */
+	__rte_marker(RTE_MARKER, cacheline1);
 	union {
-		uint64_t tx_offload;       /**< combined for easy fetch */
+		char mbuf_cacheline1[RTE_CACHE_LINE_MIN_SIZE];
 		__extension__
 		struct {
-			uint64_t l2_len:RTE_MBUF_L2_LEN_BITS;
-			/**< L2 (MAC) Header Length for non-tunneling pkt.
-			 * Outer_L4_len + ... + Inner_L2_len for tunneling pkt.
+#if RTE_IOVA_IN_MBUF
+			/**
+			 * Next segment of scattered packet. Must be NULL in the last
+			 * segment or in case of non-segmented packet.
 			 */
-			uint64_t l3_len:RTE_MBUF_L3_LEN_BITS;
-			/**< L3 (IP) Header Length. */
-			uint64_t l4_len:RTE_MBUF_L4_LEN_BITS;
-			/**< L4 (TCP/UDP) Header Length. */
-			uint64_t tso_segsz:RTE_MBUF_TSO_SEGSZ_BITS;
-			/**< TCP TSO segment size */
-
-			/*
-			 * Fields for Tx offloading of tunnels.
-			 * These are undefined for packets which don't request
-			 * any tunnel offloads (outer IP or UDP checksum,
-			 * tunnel TSO).
-			 *
-			 * PMDs should not use these fields unconditionally
-			 * when calculating offsets.
-			 *
-			 * Applications are expected to set appropriate tunnel
-			 * offload flags when they fill in these fields.
+			struct rte_mbuf *next;
+#else
+			/**
+			 * Reserved for dynamic fields
+			 * when the next pointer is in first cache line
+			 * (i.e. RTE_IOVA_IN_MBUF is 0).
 			 */
-			uint64_t outer_l3_len:RTE_MBUF_OUTL3_LEN_BITS;
-			/**< Outer L3 (IP) Hdr Length. */
-			uint64_t outer_l2_len:RTE_MBUF_OUTL2_LEN_BITS;
-			/**< Outer L2 (MAC) Hdr Length. */
+			uint64_t dynfield2;
+#endif
 
-			/* uint64_t unused:RTE_MBUF_TXOFLD_UNUSED_BITS; */
-		};
-	};
+			/* fields to support TX offloads */
+			union {
+				uint64_t tx_offload;       /**< combined for easy fetch */
+				__extension__
+				struct {
+					uint64_t l2_len:RTE_MBUF_L2_LEN_BITS;
+					/**< L2 (MAC) Header Length for non-tunneling pkt.
+					 * Outer_L4_len + ... + Inner_L2_len for tunneling pkt.
+					 */
+					uint64_t l3_len:RTE_MBUF_L3_LEN_BITS;
+					/**< L3 (IP) Header Length. */
+					uint64_t l4_len:RTE_MBUF_L4_LEN_BITS;
+					/**< L4 (TCP/UDP) Header Length. */
+					uint64_t tso_segsz:RTE_MBUF_TSO_SEGSZ_BITS;
+					/**< TCP TSO segment size */
+
+					/*
+					 * Fields for Tx offloading of tunnels.
+					 * These are undefined for packets which don't request
+					 * any tunnel offloads (outer IP or UDP checksum,
+					 * tunnel TSO).
+					 *
+					 * PMDs should not use these fields unconditionally
+					 * when calculating offsets.
+					 *
+					 * Applications are expected to set appropriate tunnel
+					 * offload flags when they fill in these fields.
+					 */
+					uint64_t outer_l3_len:RTE_MBUF_OUTL3_LEN_BITS;
+					/**< Outer L3 (IP) Hdr Length. */
+					uint64_t outer_l2_len:RTE_MBUF_OUTL2_LEN_BITS;
+					/**< Outer L2 (MAC) Hdr Length. */
+
+					/* uint64_t unused:RTE_MBUF_TXOFLD_UNUSED_BITS; */
+				};
+			};
 
-	/** Shared data for external buffer attached to mbuf. See
-	 * rte_pktmbuf_attach_extbuf().
-	 */
-	struct rte_mbuf_ext_shared_info *shinfo;
+			/** Shared data for external buffer attached to mbuf. See
+			 * rte_pktmbuf_attach_extbuf().
+			 */
+			struct rte_mbuf_ext_shared_info *shinfo;
 
-	/** Size of the application private data. In case of an indirect
-	 * mbuf, it stores the direct mbuf private data size.
-	 */
-	uint16_t priv_size;
+			/** Size of the application private data. In case of an indirect
+			 * mbuf, it stores the direct mbuf private data size.
+			 */
+			uint16_t priv_size;
 
-	/** Timesync flags for use with IEEE1588. */
-	uint16_t timesync;
+			/** Timesync flags for use with IEEE1588. */
+			uint16_t timesync;
 
-	uint32_t dynfield1[9]; /**< Reserved for dynamic fields. */
+			uint32_t dynfield1[9]; /**< Reserved for dynamic fields. */
+		};
+	};
 } __rte_cache_aligned;
 
 /**
-- 
1.8.3.1


^ permalink raw reply	[relevance 3%]

* [PATCH v4 27/39] mempool: use C11 alignas
  @ 2024-02-14 16:35  4%   ` Tyler Retzlaff
  0 siblings, 0 replies; 200+ results
From: Tyler Retzlaff @ 2024-02-14 16:35 UTC (permalink / raw)
  To: dev
  Cc: Andrew Rybchenko, Bruce Richardson, Chengwen Feng,
	Cristian Dumitrescu, David Christensen, David Hunt, Ferruh Yigit,
	Honnappa Nagarahalli, Jasvinder Singh, Jerin Jacob, Kevin Laatz,
	Konstantin Ananyev, Min Zhou, Ruifeng Wang, Sameh Gobriel,
	Stanislaw Kardach, Thomas Monjalon, Vladimir Medvedkin,
	Yipeng Wang, Tyler Retzlaff

* Move __rte_aligned from the end of {struct,union} definitions to
  be between {struct,union} and tag.

  The placement between {struct,union} and the tag allows the desired
  alignment to be imparted on the type regardless of the toolchain being
  used for all of GCC, LLVM, MSVC compilers building both C and C++.

* Replace use of __rte_aligned(a) on variables/fields with alignas(a).

Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
Acked-by: Morten Brørup <mb@smartsharesystems.com>
---
 lib/mempool/rte_mempool.h | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/lib/mempool/rte_mempool.h b/lib/mempool/rte_mempool.h
index 6fa4d48..23fd5c8 100644
--- a/lib/mempool/rte_mempool.h
+++ b/lib/mempool/rte_mempool.h
@@ -34,6 +34,7 @@
  * user cache created with rte_mempool_cache_create().
  */
 
+#include <stdalign.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <inttypes.h>
@@ -66,7 +67,7 @@
  * captured since they can be calculated from other stats.
  * For example: put_cache_objs = put_objs - put_common_pool_objs.
  */
-struct rte_mempool_debug_stats {
+struct __rte_cache_aligned rte_mempool_debug_stats {
 	uint64_t put_bulk;             /**< Number of puts. */
 	uint64_t put_objs;             /**< Number of objects successfully put. */
 	uint64_t put_common_pool_bulk; /**< Number of bulks enqueued in common pool. */
@@ -80,13 +81,13 @@ struct rte_mempool_debug_stats {
 	uint64_t get_success_blks;     /**< Successful allocation number of contiguous blocks. */
 	uint64_t get_fail_blks;        /**< Failed allocation number of contiguous blocks. */
 	RTE_CACHE_GUARD;
-} __rte_cache_aligned;
+};
 #endif
 
 /**
  * A structure that stores a per-core object cache.
  */
-struct rte_mempool_cache {
+struct __rte_cache_aligned rte_mempool_cache {
 	uint32_t size;	      /**< Size of the cache */
 	uint32_t flushthresh; /**< Threshold before we flush excess elements */
 	uint32_t len;	      /**< Current cache count */
@@ -109,8 +110,8 @@ struct rte_mempool_cache {
 	 * Cache is allocated to this size to allow it to overflow in certain
 	 * cases to avoid needless emptying of cache.
 	 */
-	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2] __rte_cache_aligned;
-} __rte_cache_aligned;
+	alignas(RTE_CACHE_LINE_SIZE) void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2];
+};
 
 /**
  * A structure that stores the size of mempool elements.
@@ -218,15 +219,15 @@ struct rte_mempool_memhdr {
  * The structure is cache-line aligned to avoid ABI breakages in
  * a number of cases when something small is added.
  */
-struct rte_mempool_info {
+struct __rte_cache_aligned rte_mempool_info {
 	/** Number of objects in the contiguous block */
 	unsigned int contig_block_size;
-} __rte_cache_aligned;
+};
 
 /**
  * The RTE mempool structure.
  */
-struct rte_mempool {
+struct __rte_cache_aligned rte_mempool {
 	char name[RTE_MEMPOOL_NAMESIZE]; /**< Name of mempool. */
 	union {
 		void *pool_data;         /**< Ring or pool to store objects. */
@@ -268,7 +269,7 @@ struct rte_mempool {
 	 */
 	struct rte_mempool_debug_stats stats[RTE_MAX_LCORE + 1];
 #endif
-}  __rte_cache_aligned;
+};
 
 /** Spreading among memory channels not required. */
 #define RTE_MEMPOOL_F_NO_SPREAD		0x0001
@@ -688,7 +689,7 @@ typedef int (*rte_mempool_get_info_t)(const struct rte_mempool *mp,
 
 
 /** Structure defining mempool operations structure */
-struct rte_mempool_ops {
+struct __rte_cache_aligned rte_mempool_ops {
 	char name[RTE_MEMPOOL_OPS_NAMESIZE]; /**< Name of mempool ops struct. */
 	rte_mempool_alloc_t alloc;       /**< Allocate private data. */
 	rte_mempool_free_t free;         /**< Free the external pool. */
@@ -713,7 +714,7 @@ struct rte_mempool_ops {
 	 * Dequeue a number of contiguous object blocks.
 	 */
 	rte_mempool_dequeue_contig_blocks_t dequeue_contig_blocks;
-} __rte_cache_aligned;
+};
 
 #define RTE_MEMPOOL_MAX_OPS_IDX 16  /**< Max registered ops structs */
 
@@ -726,14 +727,14 @@ struct rte_mempool_ops {
  * any function pointers stored directly in the mempool struct would not be.
  * This results in us simply having "ops_index" in the mempool struct.
  */
-struct rte_mempool_ops_table {
+struct __rte_cache_aligned rte_mempool_ops_table {
 	rte_spinlock_t sl;     /**< Spinlock for add/delete. */
 	uint32_t num_ops;      /**< Number of used ops structs in the table. */
 	/**
 	 * Storage for all possible ops structs.
 	 */
 	struct rte_mempool_ops ops[RTE_MEMPOOL_MAX_OPS_IDX];
-} __rte_cache_aligned;
+};
 
 /** Array of registered ops structs. */
 extern struct rte_mempool_ops_table rte_mempool_ops_table;
-- 
1.8.3.1


^ permalink raw reply	[relevance 4%]

* Re: [PATCH v2 0/4] more replacement of zero length array
  2024-02-13 19:20  3%     ` Tyler Retzlaff
@ 2024-02-14  7:36  4%       ` David Marchand
  2024-02-16 10:14  0%         ` David Marchand
  0 siblings, 1 reply; 200+ results
From: David Marchand @ 2024-02-14  7:36 UTC (permalink / raw)
  To: Tyler Retzlaff
  Cc: dev, Bruce Richardson, Cristian Dumitrescu, Honnappa Nagarahalli,
	Sameh Gobriel, Vladimir Medvedkin, Yipeng Wang, mb, fengchengwen,
	Dodji Seketeli

On Tue, Feb 13, 2024 at 8:20 PM Tyler Retzlaff
<roretzla@linux.microsoft.com> wrote:
>
> On Tue, Feb 13, 2024 at 02:14:28PM +0100, David Marchand wrote:
> > On Mon, Feb 12, 2024 at 11:36 PM Tyler Retzlaff
> > <roretzla@linux.microsoft.com> wrote:
> > >
> > > Replace some missed zero length arrays not captured in the
> > > original series.
> > > https://patchwork.dpdk.org/project/dpdk/list/?series=30410&state=*
> > >
> > > Zero length arrays are a GNU extension that has been
> > > superseded by flex arrays.
> > >
> > > https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
> > >
> > > v2:
> > >     * added additional patches for fib & pipeline libs.
> > >       series-acks have been placed only against original
> > >       hash and rcu patches.
> >
> > There seems to be an issue with the ABI check on those changes.
> > After a quick chat with Dodji, I opened a bug for libabigail.
> >
> > https://sourceware.org/bugzilla/show_bug.cgi?id=31377
>
> I double checked again and I don't see the struct in question being
> embedded as a field of another struct/union.  So I don't think there should
> be an ABI change here.

That was and is still my understanding too.

The message we get when testing this series is:

                      type size hasn't changed
                      1 data member change:
                        'uint8_t action_data[]' has *some* difference
- please report as a bug

which is why I reached out to Dodji (libabigail maintainer).

Dodji explained me that zero length / flex arrays conversion is
something he has been working on, and there are still some rough
edges.
This message is there so that libabigail community gets more input on
real life cases to handle.


>
> I'm okay with the change being merged but if there is concern I can drop
> this patch from the series.

At least, we can't merge it in the current form.

If libabigail gets a fix quickly, DPDK CI will still need a released version.
So for this patch to be merged now, we need a libabigail suppression rule.
I don't see a way to precisely waive this issue, so my suggestion is
to silence any change on the concerned structure here (which should be
ok, as the pipeline library data struct have been super stable for a
couple of years).
Something like:

$ git diff
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index 21b8cd6113..d667157909 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -33,3 +33,5 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Temporary exceptions till next major ABI version ;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+[suppress_type]
+       name = rte_pipeline_table_entry


-- 
David Marchand


^ permalink raw reply	[relevance 4%]

* [PATCH v3 27/39] mempool: use C11 alignas
  @ 2024-02-14  7:06  4%   ` Tyler Retzlaff
  0 siblings, 0 replies; 200+ results
From: Tyler Retzlaff @ 2024-02-14  7:06 UTC (permalink / raw)
  To: dev
  Cc: Andrew Rybchenko, Bruce Richardson, Chengwen Feng,
	Cristian Dumitrescu, David Christensen, David Hunt, Ferruh Yigit,
	Honnappa Nagarahalli, Jasvinder Singh, Jerin Jacob, Kevin Laatz,
	Konstantin Ananyev, Min Zhou, Ruifeng Wang, Sameh Gobriel,
	Stanislaw Kardach, Thomas Monjalon, Vladimir Medvedkin,
	Yipeng Wang, Tyler Retzlaff

* Move __rte_aligned from the end of {struct,union} definitions to
  be between {struct,union} and tag.

  The placement between {struct,union} and the tag allows the desired
  alignment to be imparted on the type regardless of the toolchain being
  used for all of GCC, LLVM, MSVC compilers building both C and C++.

* Replace use of __rte_aligned(a) on variables/fields with alignas(a).

Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
---
 lib/mempool/rte_mempool.h | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/lib/mempool/rte_mempool.h b/lib/mempool/rte_mempool.h
index 6fa4d48..23fd5c8 100644
--- a/lib/mempool/rte_mempool.h
+++ b/lib/mempool/rte_mempool.h
@@ -34,6 +34,7 @@
  * user cache created with rte_mempool_cache_create().
  */
 
+#include <stdalign.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <inttypes.h>
@@ -66,7 +67,7 @@
  * captured since they can be calculated from other stats.
  * For example: put_cache_objs = put_objs - put_common_pool_objs.
  */
-struct rte_mempool_debug_stats {
+struct __rte_cache_aligned rte_mempool_debug_stats {
 	uint64_t put_bulk;             /**< Number of puts. */
 	uint64_t put_objs;             /**< Number of objects successfully put. */
 	uint64_t put_common_pool_bulk; /**< Number of bulks enqueued in common pool. */
@@ -80,13 +81,13 @@ struct rte_mempool_debug_stats {
 	uint64_t get_success_blks;     /**< Successful allocation number of contiguous blocks. */
 	uint64_t get_fail_blks;        /**< Failed allocation number of contiguous blocks. */
 	RTE_CACHE_GUARD;
-} __rte_cache_aligned;
+};
 #endif
 
 /**
  * A structure that stores a per-core object cache.
  */
-struct rte_mempool_cache {
+struct __rte_cache_aligned rte_mempool_cache {
 	uint32_t size;	      /**< Size of the cache */
 	uint32_t flushthresh; /**< Threshold before we flush excess elements */
 	uint32_t len;	      /**< Current cache count */
@@ -109,8 +110,8 @@ struct rte_mempool_cache {
 	 * Cache is allocated to this size to allow it to overflow in certain
 	 * cases to avoid needless emptying of cache.
 	 */
-	void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2] __rte_cache_aligned;
-} __rte_cache_aligned;
+	alignas(RTE_CACHE_LINE_SIZE) void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2];
+};
 
 /**
  * A structure that stores the size of mempool elements.
@@ -218,15 +219,15 @@ struct rte_mempool_memhdr {
  * The structure is cache-line aligned to avoid ABI breakages in
  * a number of cases when something small is added.
  */
-struct rte_mempool_info {
+struct __rte_cache_aligned rte_mempool_info {
 	/** Number of objects in the contiguous block */
 	unsigned int contig_block_size;
-} __rte_cache_aligned;
+};
 
 /**
  * The RTE mempool structure.
  */
-struct rte_mempool {
+struct __rte_cache_aligned rte_mempool {
 	char name[RTE_MEMPOOL_NAMESIZE]; /**< Name of mempool. */
 	union {
 		void *pool_data;         /**< Ring or pool to store objects. */
@@ -268,7 +269,7 @@ struct rte_mempool {
 	 */
 	struct rte_mempool_debug_stats stats[RTE_MAX_LCORE + 1];
 #endif
-}  __rte_cache_aligned;
+};
 
 /** Spreading among memory channels not required. */
 #define RTE_MEMPOOL_F_NO_SPREAD		0x0001
@@ -688,7 +689,7 @@ typedef int (*rte_mempool_get_info_t)(const struct rte_mempool *mp,
 
 
 /** Structure defining mempool operations structure */
-struct rte_mempool_ops {
+struct __rte_cache_aligned rte_mempool_ops {
 	char name[RTE_MEMPOOL_OPS_NAMESIZE]; /**< Name of mempool ops struct. */
 	rte_mempool_alloc_t alloc;       /**< Allocate private data. */
 	rte_mempool_free_t free;         /**< Free the external pool. */
@@ -713,7 +714,7 @@ struct rte_mempool_ops {
 	 * Dequeue a number of contiguous object blocks.
 	 */
 	rte_mempool_dequeue_contig_blocks_t dequeue_contig_blocks;
-} __rte_cache_aligned;
+};
 
 #define RTE_MEMPOOL_MAX_OPS_IDX 16  /**< Max registered ops structs */
 
@@ -726,14 +727,14 @@ struct rte_mempool_ops {
  * any function pointers stored directly in the mempool struct would not be.
  * This results in us simply having "ops_index" in the mempool struct.
  */
-struct rte_mempool_ops_table {
+struct __rte_cache_aligned rte_mempool_ops_table {
 	rte_spinlock_t sl;     /**< Spinlock for add/delete. */
 	uint32_t num_ops;      /**< Number of used ops structs in the table. */
 	/**
 	 * Storage for all possible ops structs.
 	 */
 	struct rte_mempool_ops ops[RTE_MEMPOOL_MAX_OPS_IDX];
-} __rte_cache_aligned;
+};
 
 /** Array of registered ops structs. */
 extern struct rte_mempool_ops_table rte_mempool_ops_table;
-- 
1.8.3.1


^ permalink raw reply	[relevance 4%]

* Re: [PATCH v2 0/4] more replacement of zero length array
  2024-02-13 13:14  3%   ` David Marchand
@ 2024-02-13 19:20  3%     ` Tyler Retzlaff
  2024-02-14  7:36  4%       ` David Marchand
  0 siblings, 1 reply; 200+ results
From: Tyler Retzlaff @ 2024-02-13 19:20 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, Bruce Richardson, Cristian Dumitrescu, Honnappa Nagarahalli,
	Sameh Gobriel, Vladimir Medvedkin, Yipeng Wang, mb, fengchengwen,
	Dodji Seketeli

On Tue, Feb 13, 2024 at 02:14:28PM +0100, David Marchand wrote:
> On Mon, Feb 12, 2024 at 11:36 PM Tyler Retzlaff
> <roretzla@linux.microsoft.com> wrote:
> >
> > Replace some missed zero length arrays not captured in the
> > original series.
> > https://patchwork.dpdk.org/project/dpdk/list/?series=30410&state=*
> >
> > Zero length arrays are a GNU extension that has been
> > superseded by flex arrays.
> >
> > https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
> >
> > v2:
> >     * added additional patches for fib & pipeline libs.
> >       series-acks have been placed only against original
> >       hash and rcu patches.
> 
> There seems to be an issue with the ABI check on those changes.
> After a quick chat with Dodji, I opened a bug for libabigail.
> 
> https://sourceware.org/bugzilla/show_bug.cgi?id=31377

I double checked again and I don't see the struct in question being
embedded as a field of another struct/union.  So I don't think there should
be an ABI change here.

I'm okay with the change being merged but if there is concern I can drop
this patch from the series.

> 
> 
> -- 
> David Marchand

^ permalink raw reply	[relevance 3%]

* RE: [PATCH v2] RFC: replace GCC marker extension with C11 anonymous unions
  2024-02-13  6:45  3%   ` [PATCH v2] RFC: " Tyler Retzlaff
  2024-02-13  8:57  0%     ` Bruce Richardson
@ 2024-02-13 17:09  0%     ` Morten Brørup
  1 sibling, 0 replies; 200+ results
From: Morten Brørup @ 2024-02-13 17:09 UTC (permalink / raw)
  To: Tyler Retzlaff, dev
  Cc: Andrew Boyer, Andrew Rybchenko, Bruce Richardson, Chenbo Xia,
	Konstantin Ananyev, Maxime Coquelin

> From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com]
> Sent: Tuesday, 13 February 2024 07.46
> 
> The zero sized RTE_MARKER<n> typedefs are a GCC extension unsupported
> by
> MSVC.  Replace the use of the RTE_MARKER typedefs with anonymous
> unions.
> 
> Note:
> 
> v1 of the series tried to maintain the API after some study it has been
> discovered that some existing uses of the markers do not produce
> compilation
> failure but evaluate to unintended values in the absence of adaptation.
> For this reason the existing markers cannot be removed because it is
> too hard
> to identify what needs to be changed by consumers. While the ABI has
> been
> maintained the subtle API change is just too risky.
> 
> The question I'm asking now is how to gracefully deprecate the markers
> while allowing consumption of the struct on Windows.
> 
> I propose the following:
> 
> * Introduce the unions as per-this series except instead of adding
> members
>   that match the original RTE_MARKER field names provide *new* names.
> * Retain (conditionally compiled away on Windows) the existing
> RTE_MARKER
>   fields with their original names.
> * Convert in-tree code to use the new names in the unions.
> 
> The old names & markers would be announced for deprecation and
> eventually
> removed and when they are the conditional compilation would also go
> away.
> 
> Thoughts?

Seems like the right thing to do!

The modified type of rearm_data might not be noticed by out-of-tree PMD developers, so using a new name for the new type reduces the risk.

If some of the markers maintain their type or get a compatible type (from an API perspective), they can keep their names.


^ permalink raw reply	[relevance 0%]

* Re: [PATCH v2 0/4] more replacement of zero length array
  @ 2024-02-13 13:14  3%   ` David Marchand
  2024-02-13 19:20  3%     ` Tyler Retzlaff
  0 siblings, 1 reply; 200+ results
From: David Marchand @ 2024-02-13 13:14 UTC (permalink / raw)
  To: Tyler Retzlaff
  Cc: dev, Bruce Richardson, Cristian Dumitrescu, Honnappa Nagarahalli,
	Sameh Gobriel, Vladimir Medvedkin, Yipeng Wang, mb, fengchengwen,
	Dodji Seketeli

On Mon, Feb 12, 2024 at 11:36 PM Tyler Retzlaff
<roretzla@linux.microsoft.com> wrote:
>
> Replace some missed zero length arrays not captured in the
> original series.
> https://patchwork.dpdk.org/project/dpdk/list/?series=30410&state=*
>
> Zero length arrays are a GNU extension that has been
> superseded by flex arrays.
>
> https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
>
> v2:
>     * added additional patches for fib & pipeline libs.
>       series-acks have been placed only against original
>       hash and rcu patches.

There seems to be an issue with the ABI check on those changes.
After a quick chat with Dodji, I opened a bug for libabigail.

https://sourceware.org/bugzilla/show_bug.cgi?id=31377


-- 
David Marchand


^ permalink raw reply	[relevance 3%]

* Re: [PATCH v2] RFC: replace GCC marker extension with C11 anonymous unions
  2024-02-13  6:45  3%   ` [PATCH v2] RFC: " Tyler Retzlaff
@ 2024-02-13  8:57  0%     ` Bruce Richardson
  2024-02-13 17:09  0%     ` Morten Brørup
  1 sibling, 0 replies; 200+ results
From: Bruce Richardson @ 2024-02-13  8:57 UTC (permalink / raw)
  To: Tyler Retzlaff
  Cc: dev, Andrew Boyer, Andrew Rybchenko, Chenbo Xia,
	Konstantin Ananyev, Maxime Coquelin, mb

On Mon, Feb 12, 2024 at 10:45:40PM -0800, Tyler Retzlaff wrote:
> The zero sized RTE_MARKER<n> typedefs are a GCC extension unsupported by
> MSVC.  Replace the use of the RTE_MARKER typedefs with anonymous unions.
> 
> Note:
> 
> v1 of the series tried to maintain the API after some study it has been
> discovered that some existing uses of the markers do not produce compilation
> failure but evaluate to unintended values in the absence of adaptation.
> For this reason the existing markers cannot be removed because it is too hard
> to identify what needs to be changed by consumers. While the ABI has been
> maintained the subtle API change is just too risky.
> 
> The question I'm asking now is how to gracefully deprecate the markers
> while allowing consumption of the struct on Windows.
> 
> I propose the following:
> 
> * Introduce the unions as per-this series except instead of adding members
>   that match the original RTE_MARKER field names provide *new* names.
> * Retain (conditionally compiled away on Windows) the existing RTE_MARKER
>   fields with their original names.
> * Convert in-tree code to use the new names in the unions.
> 
> The old names & markers would be announced for deprecation and eventually
> removed and when they are the conditional compilation would also go away.
> 
> Thoughts?
> 
This seems a good approach. +1 from me for the idea.

/Bruce

^ permalink raw reply	[relevance 0%]

* RE: [PATCH v2 1/4] ethdev: introduce encap hash calculation
  2024-02-12 20:09  3%           ` Ferruh Yigit
@ 2024-02-13  7:05  0%             ` Ori Kam
  0 siblings, 0 replies; 200+ results
From: Ori Kam @ 2024-02-13  7:05 UTC (permalink / raw)
  To: Ferruh Yigit, Dariusz Sosnowski, cristian.dumitrescu,
	andrew.rybchenko, stephen, NBU-Contact-Thomas Monjalon (EXTERNAL)
  Cc: dev, Raslan Darawsheh



> -----Original Message-----
> From: Ferruh Yigit <ferruh.yigit@amd.com>
> Sent: Monday, February 12, 2024 10:10 PM
> 
> On 2/12/2024 6:44 PM, Ori Kam wrote:
> > Hi Ferruh
> >
> >> -----Original Message-----
> >> From: Ferruh Yigit <ferruh.yigit@amd.com>
> >> Sent: Monday, February 12, 2024 7:05 PM
> >>
> >> On 2/11/2024 7:29 AM, Ori Kam wrote:
> >>> Hi Ferruh,
> >>>
> >>>> -----Original Message-----
> >>>> From: Ferruh Yigit <ferruh.yigit@amd.com>
> >>>> Sent: Thursday, February 8, 2024 7:13 PM
> >>>> To: Ori Kam <orika@nvidia.com>; Dariusz Sosnowski
> >>>>
> >>>> On 2/8/2024 9:09 AM, Ori Kam wrote:
> >>>>> During encapsulation of a packet, it is possible to change some
> >>>>> outer headers to improve flow destribution.
> >>>>> For example, from VXLAN RFC:
> >>>>> "It is recommended that the UDP source port number
> >>>>> be calculated using a hash of fields from the inner packet --
> >>>>> one example being a hash of the inner Ethernet frame's headers.
> >>>>> This is to enable a level of entropy for the ECMP/load-balancing"
> >>>>>
> >>>>> The tunnel protocol defines which outer field should hold this hash,
> >>>>> but it doesn't define the hash calculation algorithm.
> >>>>>
> >>>>> An application that uses flow offloads gets the first few packets
> >>>>> (exception path) and then decides to offload the flow.
> >>>>> As a result, there are two
> >>>>> different paths that a packet from a given flow may take.
> >>>>> SW for the first few packets or HW for the rest.
> >>>>> When the packet goes through the SW, the SW encapsulates the
> packet
> >>>>> and must use the same hash calculation as the HW will do for
> >>>>> the rest of the packets in this flow.
> >>>>>
> >>>>> the new function rte_flow_calc_encap_hash can query the hash value
> >>>>> fromm the driver for a given packet as if the packet was passed
> >>>>> through the HW.
> >>>>>
> >>>>> Signed-off-by: Ori Kam <orika@nvidia.com>
> >>>>> Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
> >>>>>
> >>>>
> >>>> <...>
> >>>>
> >>>>> +int
> >>>>> +rte_flow_calc_encap_hash(uint16_t port_id, const struct
> rte_flow_item
> >>>> pattern[],
> >>>>> +			 enum rte_flow_encap_hash_field dest_field,
> uint8_t
> >>>> hash_len,
> >>>>> +			 uint8_t *hash, struct rte_flow_error *error)
> >>>>> +{
> >>>>> +	int ret;
> >>>>> +	struct rte_eth_dev *dev;
> >>>>> +	const struct rte_flow_ops *ops;
> >>>>> +
> >>>>> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> >>>>> +	ops = rte_flow_ops_get(port_id, error);
> >>>>> +	if (!ops || !ops->flow_calc_encap_hash)
> >>>>> +		return rte_flow_error_set(error, ENOTSUP,
> >>>>> +
> >>>> RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
> >>>>> +					  "calc encap hash is not
> supported");
> >>>>> +	if ((dest_field == RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT
> &&
> >>>> hash_len != 2) ||
> >>>>> +	    (dest_field ==
> RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID
> >>>> && hash_len != 1))
> >>>>>
> >>>>
> >>>> If there is a fixed mapping with the dest_field and the size, instead of
> >>>> putting this information into check code, what do you think to put it
> >>>> into the data structure?
> >>>>
> >>>> I mean instead of using enum for dest_filed, it can be a struct that is
> >>>> holding enum and its expected size, this clarifies what the expected
> >>>> size for that field.
> >>>>
> >>>
> >>> From my original email I think we only need the type, we don't need the
> >> size.
> >>> On the RFC thread there was an objection. So I added the size,
> >>> If you think it is not needed lets remove it.
> >>>
> >>
> >> I am not saying length is not needed, but
> >> API gets 'dest_field' & 'hash_len', and according checks in the API for
> >> each 'dest_field' there is an exact 'hash_len' requirement, this
> >> requirement is something impacts user but this information is embedded
> >> in the API, my suggestion is make it more visible to user.
> >>
> >> My initial suggestion was put this into an object, like:
> >> ```
> >> struct x {
> >> 	enum rte_flow_encap_hash_field dest_field;
> >> 	size_t expected size;
> >> } y[] = {
> >> 	{ RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT, 2 },
> >> 	{ RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID, 1 }
> >> };
> >> ```
> >>
> >> But as you mentioned this is a limited set, perhaps it is sufficient to
> >> document size requirement in the "enum rte_flow_encap_hash_field" API
> >> doxygen comment.
> >
> > Will add it to the doxygen.
> >
> >>
> >>
> >>
> >>>>> +		return rte_flow_error_set(error, EINVAL,
> >>>>> +
> >>>> RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
> >>>>> +					  "hash len doesn't match the
> >>>> requested field len");
> >>>>> +	dev = &rte_eth_devices[port_id];
> >>>>> +	ret = ops->flow_calc_encap_hash(dev, pattern, dest_field,
> hash,
> >>>> error);
> >>>>>
> >>>>
> >>>> 'hash_len' is get by API, but it is not passed to dev_ops, does this
> >>>> mean this information hardcoded in the driver as well, if so why
> >>>> duplicate this information in driver instead off passing hash_len to
> driver?
> >>>
> >>> Not sure I understand, like I wrote above this is pure verification from my
> >> point of view.
> >>> The driver knows the size based on the dest.
> >>>
> >>
> >> My intention was similar to above comment, like dest_field type
> >> RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT implies that required size
> should
> >> be
> >> 2 bytes, and it seems driver already knows about this requirement.
> >
> > That is correct, that is why I don't think we need the size, add added it
> > only for validation due to community request.
> >
> >>
> >> Instead, it can be possible to verify 'hash_len' in the API level, pass
> >> this information to the driver and driver use 'hash_len' directly for
> >> its size parameter, so driver will rely on API provided 'hash_len' value
> >> instead of storing this information within driver.
> >>
> >> Lets assume 10 drivers are implementing this feature, should all of them
> >> define MLX5DR_CRC_ENCAP_ENTROPY_HASH_SIZE_16 equivalent
> >> enum/define
> >> withing the driver?
> >
> > No, the driver implements hard-coded logic, which means that it just needs
> to know
> > the dest field, in order to know what hash to calculate
> > It is possible that for each field the HW will calculate the hash using
> different algorithm.
> >
> 
> OK if HW already needs to know the size in advance, lets go with enum
> doxygen update only.
> 
> > Also it is possible that the HW doesn't support writing to the expected field,
> in which case we
> > want the driver call to fail.
> >
> > Field implies size.
> > Size doesn't implies field.
> >
> >>
> >>>>
> >>>>
> >>>>> +	return flow_err(port_id, ret, error);
> >>>>> +}
> >>>>> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> >>>>> index 1267c146e5..2bdf3a4a17 100644
> >>>>> --- a/lib/ethdev/rte_flow.h
> >>>>> +++ b/lib/ethdev/rte_flow.h
> >>>>> @@ -6783,6 +6783,57 @@ rte_flow_calc_table_hash(uint16_t
> port_id,
> >>>> const struct rte_flow_template_table
> >>>>>  			 const struct rte_flow_item pattern[], uint8_t
> >>>> pattern_template_index,
> >>>>>  			 uint32_t *hash, struct rte_flow_error *error);
> >>>>>
> >>>>> +/**
> >>>>> + * @warning
> >>>>> + * @b EXPERIMENTAL: this API may change without prior notice.
> >>>>> + *
> >>>>> + * Destination field type for the hash calculation, when encap action
> is
> >>>> used.
> >>>>> + *
> >>>>> + * @see function rte_flow_calc_encap_hash
> >>>>> + */
> >>>>> +enum rte_flow_encap_hash_field {
> >>>>> +	/* Calculate hash placed in UDP source port field. */
> >>>>>
> >>
> >> Just recognized that comments are not doxygen comments.
> >
> > Thanks,
> > Will fix.
> >>
> >>>>> +	RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT,
> >>>>> +	/* Calculate hash placed in NVGRE flow ID field. */
> >>>>> +	RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID,
> >>>>> +};
> >>>>>
> >>>>
> >>>> Indeed above enum represents a field in a network protocol, right?
> >>>> Instead of having a 'RTE_FLOW_ENCAP_HASH_' specific one, can re-
> using
> >>>> 'enum rte_flow_field_id' work?
> >>>
> >>> Since the option are really limited and defined by standard, I prefer to
> have
> >> dedicated options.
> >>>
> >>
> >> OK, my intention is to reduce the duplication. Just for brainstorm, what
> >> is the benefit of having 'RTE_FLOW_ENCAP_HASH_' specific enums, if we
> >> can present them as generic protocol fiels, like
> >> 'RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT' vs
> >> 'RTE_FLOW_FIELD_UDP_PORT_SRC,'?
> >
> > I guess you want to go with 'RTE_FLOW_FIELD_UDP_PORT_SRC
> > right?
> >
> 
> I just want to discuss if redundancy can be eliminated.
> 
> > The main issue is since the options are really limited and used for a very
> dedicated function.
> > When app developers / DPDK developers will look at it, it will be very
> unclear what is the use of this enum.
> > We already have an enum for fields. Like you suggested we could have
> used it,
> > but this will show much more option than there are really.
> >
> 
> OK, lets use dedicated enums to clarify to the users the specific fields
> available for this set of APIs.
> 
> Btw, is boundary check like following required for the APIs:
> ```
> if (dest_field > RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID)
> 	return -EINVAL;
> ```
> In case user pass an invalid value as 'dest_filed'
> 
> (Note: I intentionally not used MAX enum something like
> 'RTE_FLOW_ENCAP_HASH_FIELD_MAX' to not need to deal with ABI issues in
> the future.)
Good idea will add
Best,
Ori


^ permalink raw reply	[relevance 0%]

* [PATCH v2] RFC: replace GCC marker extension with C11 anonymous unions
      2024-01-31 13:49  3%   ` Bruce Richardson
@ 2024-02-13  6:45  3%   ` Tyler Retzlaff
  2024-02-13  8:57  0%     ` Bruce Richardson
  2024-02-13 17:09  0%     ` Morten Brørup
  2 siblings, 2 replies; 200+ results
From: Tyler Retzlaff @ 2024-02-13  6:45 UTC (permalink / raw)
  To: dev
  Cc: Andrew Boyer, Andrew Rybchenko, Bruce Richardson, Chenbo Xia,
	Konstantin Ananyev, Maxime Coquelin, mb, Tyler Retzlaff

The zero sized RTE_MARKER<n> typedefs are a GCC extension unsupported by
MSVC.  Replace the use of the RTE_MARKER typedefs with anonymous unions.

Note:

v1 of the series tried to maintain the API after some study it has been
discovered that some existing uses of the markers do not produce compilation
failure but evaluate to unintended values in the absence of adaptation.
For this reason the existing markers cannot be removed because it is too hard
to identify what needs to be changed by consumers. While the ABI has been
maintained the subtle API change is just too risky.

The question I'm asking now is how to gracefully deprecate the markers
while allowing consumption of the struct on Windows.

I propose the following:

* Introduce the unions as per-this series except instead of adding members
  that match the original RTE_MARKER field names provide *new* names.
* Retain (conditionally compiled away on Windows) the existing RTE_MARKER
  fields with their original names.
* Convert in-tree code to use the new names in the unions.

The old names & markers would be announced for deprecation and eventually
removed and when they are the conditional compilation would also go away.

Thoughts?

v2:
    * Introduce additional union/struct to agnostically pad cachline0 to
      RTE_CACHE_LINE_MIN_SIZE without conditional compilation.
    * Adapt ixgbe access of rearm_data field.
    * Move ol_flags field out of rearm_data union where it didn't belong.
    * Added a couple of static_asserts for offset of cacheline1 and
      sizeof struct rte_mbuf.

Tyler Retzlaff (1):
  mbuf: replace GCC marker extension with C11 anonymous unions

 drivers/net/ionic/ionic_lif.c               |   8 +-
 drivers/net/ionic/ionic_rxtx_sg.c           |   4 +-
 drivers/net/ionic/ionic_rxtx_simple.c       |   2 +-
 drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c      |   8 +-
 drivers/net/sfc/sfc_ef100_rx.c              |   8 +-
 drivers/net/sfc/sfc_ef10_rx.c               |  12 +-
 drivers/net/virtio/virtio_rxtx_packed_avx.h |   8 +-
 lib/mbuf/rte_mbuf_core.h                    | 276 ++++++++++++++++------------
 8 files changed, 179 insertions(+), 147 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[relevance 3%]

* Re: [PATCH v2 1/4] ethdev: introduce encap hash calculation
  @ 2024-02-12 20:09  3%           ` Ferruh Yigit
  2024-02-13  7:05  0%             ` Ori Kam
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2024-02-12 20:09 UTC (permalink / raw)
  To: Ori Kam, Dariusz Sosnowski, cristian.dumitrescu,
	andrew.rybchenko, stephen, NBU-Contact-Thomas Monjalon (EXTERNAL)
  Cc: dev, Raslan Darawsheh

On 2/12/2024 6:44 PM, Ori Kam wrote:
> Hi Ferruh
> 
>> -----Original Message-----
>> From: Ferruh Yigit <ferruh.yigit@amd.com>
>> Sent: Monday, February 12, 2024 7:05 PM
>>
>> On 2/11/2024 7:29 AM, Ori Kam wrote:
>>> Hi Ferruh,
>>>
>>>> -----Original Message-----
>>>> From: Ferruh Yigit <ferruh.yigit@amd.com>
>>>> Sent: Thursday, February 8, 2024 7:13 PM
>>>> To: Ori Kam <orika@nvidia.com>; Dariusz Sosnowski
>>>>
>>>> On 2/8/2024 9:09 AM, Ori Kam wrote:
>>>>> During encapsulation of a packet, it is possible to change some
>>>>> outer headers to improve flow destribution.
>>>>> For example, from VXLAN RFC:
>>>>> "It is recommended that the UDP source port number
>>>>> be calculated using a hash of fields from the inner packet --
>>>>> one example being a hash of the inner Ethernet frame's headers.
>>>>> This is to enable a level of entropy for the ECMP/load-balancing"
>>>>>
>>>>> The tunnel protocol defines which outer field should hold this hash,
>>>>> but it doesn't define the hash calculation algorithm.
>>>>>
>>>>> An application that uses flow offloads gets the first few packets
>>>>> (exception path) and then decides to offload the flow.
>>>>> As a result, there are two
>>>>> different paths that a packet from a given flow may take.
>>>>> SW for the first few packets or HW for the rest.
>>>>> When the packet goes through the SW, the SW encapsulates the packet
>>>>> and must use the same hash calculation as the HW will do for
>>>>> the rest of the packets in this flow.
>>>>>
>>>>> the new function rte_flow_calc_encap_hash can query the hash value
>>>>> fromm the driver for a given packet as if the packet was passed
>>>>> through the HW.
>>>>>
>>>>> Signed-off-by: Ori Kam <orika@nvidia.com>
>>>>> Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
>>>>>
>>>>
>>>> <...>
>>>>
>>>>> +int
>>>>> +rte_flow_calc_encap_hash(uint16_t port_id, const struct rte_flow_item
>>>> pattern[],
>>>>> +			 enum rte_flow_encap_hash_field dest_field, uint8_t
>>>> hash_len,
>>>>> +			 uint8_t *hash, struct rte_flow_error *error)
>>>>> +{
>>>>> +	int ret;
>>>>> +	struct rte_eth_dev *dev;
>>>>> +	const struct rte_flow_ops *ops;
>>>>> +
>>>>> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>>>> +	ops = rte_flow_ops_get(port_id, error);
>>>>> +	if (!ops || !ops->flow_calc_encap_hash)
>>>>> +		return rte_flow_error_set(error, ENOTSUP,
>>>>> +
>>>> RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
>>>>> +					  "calc encap hash is not supported");
>>>>> +	if ((dest_field == RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT &&
>>>> hash_len != 2) ||
>>>>> +	    (dest_field == RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID
>>>> && hash_len != 1))
>>>>>
>>>>
>>>> If there is a fixed mapping with the dest_field and the size, instead of
>>>> putting this information into check code, what do you think to put it
>>>> into the data structure?
>>>>
>>>> I mean instead of using enum for dest_filed, it can be a struct that is
>>>> holding enum and its expected size, this clarifies what the expected
>>>> size for that field.
>>>>
>>>
>>> From my original email I think we only need the type, we don't need the
>> size.
>>> On the RFC thread there was an objection. So I added the size,
>>> If you think it is not needed lets remove it.
>>>
>>
>> I am not saying length is not needed, but
>> API gets 'dest_field' & 'hash_len', and according checks in the API for
>> each 'dest_field' there is an exact 'hash_len' requirement, this
>> requirement is something impacts user but this information is embedded
>> in the API, my suggestion is make it more visible to user.
>>
>> My initial suggestion was put this into an object, like:
>> ```
>> struct x {
>> 	enum rte_flow_encap_hash_field dest_field;
>> 	size_t expected size;
>> } y[] = {
>> 	{ RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT, 2 },
>> 	{ RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID, 1 }
>> };
>> ```
>>
>> But as you mentioned this is a limited set, perhaps it is sufficient to
>> document size requirement in the "enum rte_flow_encap_hash_field" API
>> doxygen comment.
> 
> Will add it to the doxygen.
> 
>>
>>
>>
>>>>> +		return rte_flow_error_set(error, EINVAL,
>>>>> +
>>>> RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
>>>>> +					  "hash len doesn't match the
>>>> requested field len");
>>>>> +	dev = &rte_eth_devices[port_id];
>>>>> +	ret = ops->flow_calc_encap_hash(dev, pattern, dest_field, hash,
>>>> error);
>>>>>
>>>>
>>>> 'hash_len' is get by API, but it is not passed to dev_ops, does this
>>>> mean this information hardcoded in the driver as well, if so why
>>>> duplicate this information in driver instead off passing hash_len to driver?
>>>
>>> Not sure I understand, like I wrote above this is pure verification from my
>> point of view.
>>> The driver knows the size based on the dest.
>>>
>>
>> My intention was similar to above comment, like dest_field type
>> RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT implies that required size should
>> be
>> 2 bytes, and it seems driver already knows about this requirement.
> 
> That is correct, that is why I don't think we need the size, add added it
> only for validation due to community request.
> 
>>
>> Instead, it can be possible to verify 'hash_len' in the API level, pass
>> this information to the driver and driver use 'hash_len' directly for
>> its size parameter, so driver will rely on API provided 'hash_len' value
>> instead of storing this information within driver.
>>
>> Lets assume 10 drivers are implementing this feature, should all of them
>> define MLX5DR_CRC_ENCAP_ENTROPY_HASH_SIZE_16 equivalent
>> enum/define
>> withing the driver?
> 
> No, the driver implements hard-coded logic, which means that it just needs to know
> the dest field, in order to know what hash to calculate
> It is possible that for each field the HW will calculate the hash using different algorithm.
> 

OK if HW already needs to know the size in advance, lets go with enum
doxygen update only.

> Also it is possible that the HW doesn't support writing to the expected field, in which case we 
> want the driver call to fail.
> 
> Field implies size.
> Size doesn't implies field.
> 
>>
>>>>
>>>>
>>>>> +	return flow_err(port_id, ret, error);
>>>>> +}
>>>>> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
>>>>> index 1267c146e5..2bdf3a4a17 100644
>>>>> --- a/lib/ethdev/rte_flow.h
>>>>> +++ b/lib/ethdev/rte_flow.h
>>>>> @@ -6783,6 +6783,57 @@ rte_flow_calc_table_hash(uint16_t port_id,
>>>> const struct rte_flow_template_table
>>>>>  			 const struct rte_flow_item pattern[], uint8_t
>>>> pattern_template_index,
>>>>>  			 uint32_t *hash, struct rte_flow_error *error);
>>>>>
>>>>> +/**
>>>>> + * @warning
>>>>> + * @b EXPERIMENTAL: this API may change without prior notice.
>>>>> + *
>>>>> + * Destination field type for the hash calculation, when encap action is
>>>> used.
>>>>> + *
>>>>> + * @see function rte_flow_calc_encap_hash
>>>>> + */
>>>>> +enum rte_flow_encap_hash_field {
>>>>> +	/* Calculate hash placed in UDP source port field. */
>>>>>
>>
>> Just recognized that comments are not doxygen comments.
> 
> Thanks,
> Will fix.
>>
>>>>> +	RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT,
>>>>> +	/* Calculate hash placed in NVGRE flow ID field. */
>>>>> +	RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID,
>>>>> +};
>>>>>
>>>>
>>>> Indeed above enum represents a field in a network protocol, right?
>>>> Instead of having a 'RTE_FLOW_ENCAP_HASH_' specific one, can re-using
>>>> 'enum rte_flow_field_id' work?
>>>
>>> Since the option are really limited and defined by standard, I prefer to have
>> dedicated options.
>>>
>>
>> OK, my intention is to reduce the duplication. Just for brainstorm, what
>> is the benefit of having 'RTE_FLOW_ENCAP_HASH_' specific enums, if we
>> can present them as generic protocol fiels, like
>> 'RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT' vs
>> 'RTE_FLOW_FIELD_UDP_PORT_SRC,'?
> 
> I guess you want to go with 'RTE_FLOW_FIELD_UDP_PORT_SRC
> right?
>

I just want to discuss if redundancy can be eliminated.

> The main issue is since the options are really limited and used for a very dedicated function.
> When app developers / DPDK developers will look at it, it will be very unclear what is the use of this enum.
> We already have an enum for fields. Like you suggested we could have used it,
> but this will show much more option than there are really.
> 

OK, lets use dedicated enums to clarify to the users the specific fields
available for this set of APIs.

Btw, is boundary check like following required for the APIs:
```
if (dest_field > RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID)
	return -EINVAL;
```
In case user pass an invalid value as 'dest_filed'

(Note: I intentionally not used MAX enum something like
'RTE_FLOW_ENCAP_HASH_FIELD_MAX' to not need to deal with ABI issues in
the future.)


^ permalink raw reply	[relevance 3%]

* Re: [PATCH v7 00/19] Replace use of PMD logtype
  2024-02-03  4:10  3% ` [PATCH v7 00/19] Replace use of PMD logtype Stephen Hemminger
@ 2024-02-12 14:45  0%   ` David Marchand
  0 siblings, 0 replies; 200+ results
From: David Marchand @ 2024-02-12 14:45 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Thomas Monjalon

On Sat, Feb 3, 2024 at 5:11 AM Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> Many of the uses of PMD logtype have already been fixed.
> But there are still some leftovers, mostly places where
> drivers had a logtype but did not use them.
>
> Note: this is not an ABI break, but could break out of
>       tree drivers that never updated to use dynamic logtype.
>       DPDK never guaranteed that that would not happen.
>
> v7 - drop changes to newlines
>      drop changes related to RTE_LOG_DP
>      rebase now that other stuff has changed

Series applied.

Edits I did:
- fixed crypto/armv8 (compilation broken because of typo),
- fixed one missed use of PMD in crypto/caam_jr,
- fixed net/nfb build (thanks to Thomas for reporting),
- preferred per level macros instead of CAAM_JR_LOG, like in the rest
of the crypto/caam_jr driver,
- dropped more unrelated changes on \n in crypto/dpaa*,
- I also reorganised the commits, fixed (well dropped) wrong commit
title, typos, tried to use more consistent wording,


-- 
David Marchand


^ permalink raw reply	[relevance 0%]

* RE: [v7 1/1] net/af_xdp: fix multi interface support for K8s
  2024-02-07 23:24  0%             ` Ferruh Yigit
@ 2024-02-09 12:40  0%               ` Loftus, Ciara
  0 siblings, 0 replies; 200+ results
From: Loftus, Ciara @ 2024-02-09 12:40 UTC (permalink / raw)
  To: Ferruh Yigit, Tahhan, Maryam, stephen, lihuisong, fengchengwen,
	liuyonglong, Marchand, David
  Cc: dev, Koikkara Reeny, Shibin, Kevin Traynor, Luca Boccassi

> 
> On 1/11/2024 2:21 PM, Ferruh Yigit wrote:
> > On 1/11/2024 12:21 PM, Maryam Tahhan wrote:
> >> On 11/01/2024 11:35, Ferruh Yigit wrote:
> >>> Devarg is user interface, changing it impacts the user.
> >>>
> >>> Assume that user of '22.11.3' using 'use_cni' dev_arg, it will be broken
> >>> when user upgrades DPDK to '22.11.4', which is not expected.
> >>>
> >>> dev_arg is not API/ABI but as it impacts the user, it is in the gray
> >>> area to backport to the LTS release.
> >> Fair enough
> >>> Current patch doesn't have Fixes tag or stable tag, so it doesn't
> >>> request to be backported to LTS release. I took this as an improvement,
> >>> more than a fix.
> >>
> >> This was overlooked by me apologies. It's been a while since I've
> >> contributed to DPDK and I must've missed this detail in the contribution
> >> guide.
> >>> As far as I understand existing code (that use 'use_cni' dev_arg)
> >>> supports only single netdev, this patch adds support for multiple netdevs.
> >>
> >> The use_cni implementation will no longer work with the AF_XDP DP as the
> >> use_cni was originally implemented as it has hard coded what's now an
> >> incorrect path for the UDS.
> >>
> >>> So what do you think keep LTS with 'use_cni' dev_arg, is there a
> >>> requirement to update LTS release?
> >>> If so, can it be an option to keep 'use_cni' for backward compatibility
> >>> but add only add 'uds_path' and remove 'use_cni' in next LTS?
> >>
> >>
> >> Yeah we can go back to the version of the patch that had the 'use_cni'
> >> flag that was used in combination with the path argument. We can add
> >> better documentation re the "use_cni" misnomer... What we can then do is
> >> if no path argument is set by the user assume their intent and and
> >> generate the path internally in the AF_XDP PMD (which was suggested by
> >> Shibin at some stage). That way there should be no surprises to the End
> >> User.
> >>
> >
> > Ack, this keeps backward compatibility,
> >
> > BUT if 'use_cni' is already broken in v23.11 (that is what I understand
> > from your above comment), means there is no user of it in LTS, and we
> > can be more pragmatic and replace the dev_args, by backporting this
> > patch, assuming LTS maintainer is also OK with it.
> >
> 
> Hi Maryam,
> 
> How do you want to continue with the patch, I think options we considered:
> 
> 1. Fix 'use_cni' documentation (which we can backport to LTS) and
> overload the argument for new purpose. This will enable new feature by
> keeping backward compatibility. And requires new version of this patch.
> 
> 2. If the 'use_cni' is completely broken in the 23.11 LTS, which means
> there is no user or backward compatibility to worry about, we can merge
> this patch and backport it to LTS.
> 
> 3. Don't backport this fix to LTS, merge only to current release, which
> means your new feature won't be available to some users as long as a few
> years.
> 
> 
> (1.) is most user friendly, but if 'use_cni' already broken in LTS we
> can go with option (2.). What do you think?
> 
> 
> 
> btw, @Ciara, @Maryam, if (2.) is true, how we end up having a feature
> ('use_cni' dev_args) completely broken in an LTS release?

My understanding is that the use_cni implementation that is available in the 23.11 LTS is compatible with a particular version of the afxdp-plugins-for-kubernetes source. Maryam's change makes it compatible with the latest version. @Maryam can you confirm this?
If my understanding is correct then I think we should include the version/tag/commit-id of afxdp-plugins-for-kubernetes that the code is compatible with. Including backporting a patch to LTS to specify what version that code is comaptible with.

> 
> 
> 
> >
> >> Long term I would like to keep a (renamed) path argument (in case the
> >> path does ever change from the AF_XDP DP POV) and use it also in
> >> combination with another (maybe boolean) param for passing pinned bpf
> >> maps rather than another separate path.
> >>
> >> WDYT? Would this work for the LTS release?
> >>
> >>
> >


^ permalink raw reply	[relevance 0%]

* [PATCH v4 4/7] net/tap: rewrite the RSS BPF program
  @ 2024-02-08 19:05  2%   ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2024-02-08 19:05 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Rewrite the BPF program used to do queue based RSS.
Important changes:
	- uses newer BPF map format BTF
	- accepts key as parameter rather than constant default
	- can do L3 or L4 hashing
	- supports IPv4 options
	- supports IPv6 extension headers
	- restructured for readability

The usage of BPF is different as well:
	- the incoming configuration is looked up based on
	  class parameters rather than patching the BPF.
	- the resulting queue is placed in skb rather
	  than requiring a second pass through classifier step.

Note: This version only works with later patch to enable it on
the DPDK driver side. It is submitted as an incremental patch
to allow for easier review. Bisection still works because
the old instruction are still present for now.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 .gitignore                            |   3 -
 drivers/net/tap/bpf/Makefile          |  19 --
 drivers/net/tap/bpf/README            |  12 ++
 drivers/net/tap/bpf/bpf_api.h         | 276 --------------------------
 drivers/net/tap/bpf/bpf_elf.h         |  53 -----
 drivers/net/tap/bpf/bpf_extract.py    |  85 --------
 drivers/net/tap/bpf/meson.build       |  81 ++++++++
 drivers/net/tap/bpf/tap_bpf_program.c | 255 ------------------------
 drivers/net/tap/bpf/tap_rss.c         | 272 +++++++++++++++++++++++++
 9 files changed, 365 insertions(+), 691 deletions(-)
 delete mode 100644 drivers/net/tap/bpf/Makefile
 create mode 100644 drivers/net/tap/bpf/README
 delete mode 100644 drivers/net/tap/bpf/bpf_api.h
 delete mode 100644 drivers/net/tap/bpf/bpf_elf.h
 delete mode 100644 drivers/net/tap/bpf/bpf_extract.py
 create mode 100644 drivers/net/tap/bpf/meson.build
 delete mode 100644 drivers/net/tap/bpf/tap_bpf_program.c
 create mode 100644 drivers/net/tap/bpf/tap_rss.c

diff --git a/.gitignore b/.gitignore
index 3f444dcace2e..01a47a760660 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,9 +36,6 @@ TAGS
 # ignore python bytecode files
 *.pyc
 
-# ignore BPF programs
-drivers/net/tap/bpf/tap_bpf_program.o
-
 # DTS results
 dts/output
 
diff --git a/drivers/net/tap/bpf/Makefile b/drivers/net/tap/bpf/Makefile
deleted file mode 100644
index 9efeeb1bc704..000000000000
--- a/drivers/net/tap/bpf/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# This file is not built as part of normal DPDK build.
-# It is used to generate the eBPF code for TAP RSS.
-
-CLANG=clang
-CLANG_OPTS=-O2
-TARGET=../tap_bpf_insns.h
-
-all: $(TARGET)
-
-clean:
-	rm tap_bpf_program.o $(TARGET)
-
-tap_bpf_program.o: tap_bpf_program.c
-	$(CLANG) $(CLANG_OPTS) -emit-llvm -c $< -o - | \
-	llc -march=bpf -filetype=obj -o $@
-
-$(TARGET): tap_bpf_program.o
-	python3 bpf_extract.py -stap_bpf_program.c -o $@ $<
diff --git a/drivers/net/tap/bpf/README b/drivers/net/tap/bpf/README
new file mode 100644
index 000000000000..960a10da73b8
--- /dev/null
+++ b/drivers/net/tap/bpf/README
@@ -0,0 +1,12 @@
+This is the BPF program used to implement the RSS across queues
+flow action. It works like the skbedit tc filter but instead of mapping
+to only one queues, it maps to multiple queues based on RSS hash.
+
+This version is built the BPF Compile Once — Run Everywhere (CO-RE)
+framework and uses libbpf and bpftool.
+
+Limitations
+- requires libbpf version XX or later
+- rebuilding the BPF requires clang and bpftool
+- only Toeplitz hash with standard 40 byte key is supported
+- the number of queues per RSS action is limited to 16
diff --git a/drivers/net/tap/bpf/bpf_api.h b/drivers/net/tap/bpf/bpf_api.h
deleted file mode 100644
index 2638a8a4ac9a..000000000000
--- a/drivers/net/tap/bpf/bpf_api.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-
-#ifndef __BPF_API__
-#define __BPF_API__
-
-/* Note:
- *
- * This file can be included into eBPF kernel programs. It contains
- * a couple of useful helper functions, map/section ABI (bpf_elf.h),
- * misc macros and some eBPF specific LLVM built-ins.
- */
-
-#include <stdint.h>
-
-#include <linux/pkt_cls.h>
-#include <linux/bpf.h>
-#include <linux/filter.h>
-
-#include <asm/byteorder.h>
-
-#include "bpf_elf.h"
-
-/** libbpf pin type. */
-enum libbpf_pin_type {
-	LIBBPF_PIN_NONE,
-	/* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */
-	LIBBPF_PIN_BY_NAME,
-};
-
-/** Type helper macros. */
-
-#define __uint(name, val) int (*name)[val]
-#define __type(name, val) typeof(val) *name
-#define __array(name, val) typeof(val) *name[]
-
-/** Misc macros. */
-
-#ifndef __stringify
-# define __stringify(X)		#X
-#endif
-
-#ifndef __maybe_unused
-# define __maybe_unused		__attribute__((__unused__))
-#endif
-
-#ifndef offsetof
-# define offsetof(TYPE, MEMBER)	__builtin_offsetof(TYPE, MEMBER)
-#endif
-
-#ifndef likely
-# define likely(X)		__builtin_expect(!!(X), 1)
-#endif
-
-#ifndef unlikely
-# define unlikely(X)		__builtin_expect(!!(X), 0)
-#endif
-
-#ifndef htons
-# define htons(X)		__constant_htons((X))
-#endif
-
-#ifndef ntohs
-# define ntohs(X)		__constant_ntohs((X))
-#endif
-
-#ifndef htonl
-# define htonl(X)		__constant_htonl((X))
-#endif
-
-#ifndef ntohl
-# define ntohl(X)		__constant_ntohl((X))
-#endif
-
-#ifndef __inline__
-# define __inline__		__attribute__((always_inline))
-#endif
-
-/** Section helper macros. */
-
-#ifndef __section
-# define __section(NAME)						\
-	__attribute__((section(NAME), used))
-#endif
-
-#ifndef __section_tail
-# define __section_tail(ID, KEY)					\
-	__section(__stringify(ID) "/" __stringify(KEY))
-#endif
-
-#ifndef __section_xdp_entry
-# define __section_xdp_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_cls_entry
-# define __section_cls_entry						\
-	__section(ELF_SECTION_CLASSIFIER)
-#endif
-
-#ifndef __section_act_entry
-# define __section_act_entry						\
-	__section(ELF_SECTION_ACTION)
-#endif
-
-#ifndef __section_lwt_entry
-# define __section_lwt_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_license
-# define __section_license						\
-	__section(ELF_SECTION_LICENSE)
-#endif
-
-#ifndef __section_maps
-# define __section_maps							\
-	__section(ELF_SECTION_MAPS)
-#endif
-
-/** Declaration helper macros. */
-
-#ifndef BPF_LICENSE
-# define BPF_LICENSE(NAME)						\
-	char ____license[] __section_license = NAME
-#endif
-
-/** Classifier helper */
-
-#ifndef BPF_H_DEFAULT
-# define BPF_H_DEFAULT	-1
-#endif
-
-/** BPF helper functions for tc. Individual flags are in linux/bpf.h */
-
-#ifndef __BPF_FUNC
-# define __BPF_FUNC(NAME, ...)						\
-	(* NAME)(__VA_ARGS__) __maybe_unused
-#endif
-
-#ifndef BPF_FUNC
-# define BPF_FUNC(NAME, ...)						\
-	__BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME
-#endif
-
-/* Map access/manipulation */
-static void *BPF_FUNC(map_lookup_elem, void *map, const void *key);
-static int BPF_FUNC(map_update_elem, void *map, const void *key,
-		    const void *value, uint32_t flags);
-static int BPF_FUNC(map_delete_elem, void *map, const void *key);
-
-/* Time access */
-static uint64_t BPF_FUNC(ktime_get_ns);
-
-/* Debugging */
-
-/* FIXME: __attribute__ ((format(printf, 1, 3))) not possible unless
- * llvm bug https://llvm.org/bugs/show_bug.cgi?id=26243 gets resolved.
- * It would require ____fmt to be made const, which generates a reloc
- * entry (non-map).
- */
-static void BPF_FUNC(trace_printk, const char *fmt, int fmt_size, ...);
-
-#ifndef printt
-# define printt(fmt, ...)						\
-	({								\
-		char ____fmt[] = fmt;					\
-		trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__);	\
-	})
-#endif
-
-/* Random numbers */
-static uint32_t BPF_FUNC(get_prandom_u32);
-
-/* Tail calls */
-static void BPF_FUNC(tail_call, struct __sk_buff *skb, void *map,
-		     uint32_t index);
-
-/* System helpers */
-static uint32_t BPF_FUNC(get_smp_processor_id);
-static uint32_t BPF_FUNC(get_numa_node_id);
-
-/* Packet misc meta data */
-static uint32_t BPF_FUNC(get_cgroup_classid, struct __sk_buff *skb);
-static int BPF_FUNC(skb_under_cgroup, void *map, uint32_t index);
-
-static uint32_t BPF_FUNC(get_route_realm, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(get_hash_recalc, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(set_hash_invalid, struct __sk_buff *skb);
-
-/* Packet redirection */
-static int BPF_FUNC(redirect, int ifindex, uint32_t flags);
-static int BPF_FUNC(clone_redirect, struct __sk_buff *skb, int ifindex,
-		    uint32_t flags);
-
-/* Packet manipulation */
-static int BPF_FUNC(skb_load_bytes, struct __sk_buff *skb, uint32_t off,
-		    void *to, uint32_t len);
-static int BPF_FUNC(skb_store_bytes, struct __sk_buff *skb, uint32_t off,
-		    const void *from, uint32_t len, uint32_t flags);
-
-static int BPF_FUNC(l3_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(l4_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(csum_diff, const void *from, uint32_t from_size,
-		    const void *to, uint32_t to_size, uint32_t seed);
-static int BPF_FUNC(csum_update, struct __sk_buff *skb, uint32_t wsum);
-
-static int BPF_FUNC(skb_change_type, struct __sk_buff *skb, uint32_t type);
-static int BPF_FUNC(skb_change_proto, struct __sk_buff *skb, uint32_t proto,
-		    uint32_t flags);
-static int BPF_FUNC(skb_change_tail, struct __sk_buff *skb, uint32_t nlen,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_pull_data, struct __sk_buff *skb, uint32_t len);
-
-/* Event notification */
-static int __BPF_FUNC(skb_event_output, struct __sk_buff *skb, void *map,
-		      uint64_t index, const void *data, uint32_t size) =
-		      (void *) BPF_FUNC_perf_event_output;
-
-/* Packet vlan encap/decap */
-static int BPF_FUNC(skb_vlan_push, struct __sk_buff *skb, uint16_t proto,
-		    uint16_t vlan_tci);
-static int BPF_FUNC(skb_vlan_pop, struct __sk_buff *skb);
-
-/* Packet tunnel encap/decap */
-static int BPF_FUNC(skb_get_tunnel_key, struct __sk_buff *skb,
-		    struct bpf_tunnel_key *to, uint32_t size, uint32_t flags);
-static int BPF_FUNC(skb_set_tunnel_key, struct __sk_buff *skb,
-		    const struct bpf_tunnel_key *from, uint32_t size,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_get_tunnel_opt, struct __sk_buff *skb,
-		    void *to, uint32_t size);
-static int BPF_FUNC(skb_set_tunnel_opt, struct __sk_buff *skb,
-		    const void *from, uint32_t size);
-
-/** LLVM built-ins, mem*() routines work for constant size */
-
-#ifndef lock_xadd
-# define lock_xadd(ptr, val)	((void) __sync_fetch_and_add(ptr, val))
-#endif
-
-#ifndef memset
-# define memset(s, c, n)	__builtin_memset((s), (c), (n))
-#endif
-
-#ifndef memcpy
-# define memcpy(d, s, n)	__builtin_memcpy((d), (s), (n))
-#endif
-
-#ifndef memmove
-# define memmove(d, s, n)	__builtin_memmove((d), (s), (n))
-#endif
-
-/* FIXME: __builtin_memcmp() is not yet fully usable unless llvm bug
- * https://llvm.org/bugs/show_bug.cgi?id=26218 gets resolved. Also
- * this one would generate a reloc entry (non-map), otherwise.
- */
-#if 0
-#ifndef memcmp
-# define memcmp(a, b, n)	__builtin_memcmp((a), (b), (n))
-#endif
-#endif
-
-unsigned long long load_byte(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.byte");
-
-unsigned long long load_half(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.half");
-
-unsigned long long load_word(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.word");
-
-#endif /* __BPF_API__ */
diff --git a/drivers/net/tap/bpf/bpf_elf.h b/drivers/net/tap/bpf/bpf_elf.h
deleted file mode 100644
index ea8a11c95c0f..000000000000
--- a/drivers/net/tap/bpf/bpf_elf.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-#ifndef __BPF_ELF__
-#define __BPF_ELF__
-
-#include <asm/types.h>
-
-/* Note:
- *
- * Below ELF section names and bpf_elf_map structure definition
- * are not (!) kernel ABI. It's rather a "contract" between the
- * application and the BPF loader in tc. For compatibility, the
- * section names should stay as-is. Introduction of aliases, if
- * needed, are a possibility, though.
- */
-
-/* ELF section names, etc */
-#define ELF_SECTION_LICENSE	"license"
-#define ELF_SECTION_MAPS	"maps"
-#define ELF_SECTION_PROG	"prog"
-#define ELF_SECTION_CLASSIFIER	"classifier"
-#define ELF_SECTION_ACTION	"action"
-
-#define ELF_MAX_MAPS		64
-#define ELF_MAX_LICENSE_LEN	128
-
-/* Object pinning settings */
-#define PIN_NONE		0
-#define PIN_OBJECT_NS		1
-#define PIN_GLOBAL_NS		2
-
-/* ELF map definition */
-struct bpf_elf_map {
-	__u32 type;
-	__u32 size_key;
-	__u32 size_value;
-	__u32 max_elem;
-	__u32 flags;
-	__u32 id;
-	__u32 pinning;
-	__u32 inner_id;
-	__u32 inner_idx;
-};
-
-#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val)		\
-	struct ____btf_map_##name {				\
-		type_key key;					\
-		type_val value;					\
-	};							\
-	struct ____btf_map_##name				\
-	    __attribute__ ((section(".maps." #name), used))	\
-	    ____btf_map_##name = { }
-
-#endif /* __BPF_ELF__ */
diff --git a/drivers/net/tap/bpf/bpf_extract.py b/drivers/net/tap/bpf/bpf_extract.py
deleted file mode 100644
index 73c4dafe4eca..000000000000
--- a/drivers/net/tap/bpf/bpf_extract.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright (c) 2023 Stephen Hemminger <stephen@networkplumber.org>
-
-import argparse
-import sys
-import struct
-from tempfile import TemporaryFile
-from elftools.elf.elffile import ELFFile
-
-
-def load_sections(elffile):
-    """Get sections of interest from ELF"""
-    result = []
-    parts = [("cls_q", "cls_q_insns"), ("l3_l4", "l3_l4_hash_insns")]
-    for name, tag in parts:
-        section = elffile.get_section_by_name(name)
-        if section:
-            insns = struct.iter_unpack('<BBhL', section.data())
-            result.append([tag, insns])
-    return result
-
-
-def dump_section(name, insns, out):
-    """Dump the array of BPF instructions"""
-    print(f'\nstatic struct bpf_insn {name}[] = {{', file=out)
-    for bpf in insns:
-        code = bpf[0]
-        src = bpf[1] >> 4
-        dst = bpf[1] & 0xf
-        off = bpf[2]
-        imm = bpf[3]
-        print(f'\t{{{code:#04x}, {dst:4d}, {src:4d}, {off:8d}, {imm:#010x}}},',
-              file=out)
-    print('};', file=out)
-
-
-def parse_args():
-    """Parse command line arguments"""
-    parser = argparse.ArgumentParser()
-    parser.add_argument('-s',
-                        '--source',
-                        type=str,
-                        help="original source file")
-    parser.add_argument('-o', '--out', type=str, help="output C file path")
-    parser.add_argument("file",
-                        nargs='+',
-                        help="object file path or '-' for stdin")
-    return parser.parse_args()
-
-
-def open_input(path):
-    """Open the file or stdin"""
-    if path == "-":
-        temp = TemporaryFile()
-        temp.write(sys.stdin.buffer.read())
-        return temp
-    return open(path, 'rb')
-
-
-def write_header(out, source):
-    """Write file intro header"""
-    print("/* SPDX-License-Identifier: BSD-3-Clause", file=out)
-    if source:
-        print(f' * Auto-generated from {source}', file=out)
-    print(" * This not the original source file. Do NOT edit it.", file=out)
-    print(" */\n", file=out)
-
-
-def main():
-    '''program main function'''
-    args = parse_args()
-
-    with open(args.out, 'w',
-              encoding="utf-8") if args.out else sys.stdout as out:
-        write_header(out, args.source)
-        for path in args.file:
-            elffile = ELFFile(open_input(path))
-            sections = load_sections(elffile)
-            for name, insns in sections:
-                dump_section(name, insns, out)
-
-
-if __name__ == "__main__":
-    main()
diff --git a/drivers/net/tap/bpf/meson.build b/drivers/net/tap/bpf/meson.build
new file mode 100644
index 000000000000..f2c03a19fd4d
--- /dev/null
+++ b/drivers/net/tap/bpf/meson.build
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2024 Stephen Hemminger <stephen@networkplumber.org>
+
+enable_tap_rss = false
+
+libbpf = dependency('libbpf', required: false, method: 'pkg-config')
+if not libbpf.found()
+    message('net/tap: no RSS support missing libbpf')
+    subdir_done()
+endif
+
+# Debian install this in /usr/sbin which is not in $PATH
+bpftool = find_program('bpftool', '/usr/sbin/bpftool', required: false, version: '>= 5.6.0')
+if not bpftool.found()
+    message('net/tap: no RSS support missing bpftool')
+    subdir_done()
+endif
+
+clang_supports_bpf = false
+clang = find_program('clang', required: false)
+if clang.found()
+    clang_supports_bpf = run_command(clang, '-target', 'bpf', '--print-supported-cpus',
+                                     check: false).returncode() == 0
+endif
+
+if not clang_supports_bpf
+    message('net/tap: no RSS support missing clang BPF')
+    subdir_done()
+endif
+
+enable_tap_rss = true
+
+libbpf_include_dir = libbpf.get_variable(pkgconfig : 'includedir')
+
+# The include files <linux/bpf.h> and others include <asm/types.h>
+# but <asm/types.h> is not defined for multi-lib environment target.
+# Workaround by using include directoriy from the host build environment.
+machine_name = run_command('uname', '-m').stdout().strip()
+march_include_dir = '/usr/include/' + machine_name + '-linux-gnu'
+
+clang_flags = [
+    '-O2',
+    '-Wall',
+    '-Wextra',
+    '-target',
+    'bpf',
+    '-g',
+    '-c',
+]
+
+bpf_o_cmd = [
+    clang,
+    clang_flags,
+    '-idirafter',
+    libbpf_include_dir,
+    '-idirafter',
+    march_include_dir,
+    '@INPUT@',
+    '-o',
+    '@OUTPUT@'
+]
+
+skel_h_cmd = [
+    bpftool,
+    'gen',
+    'skeleton',
+    '@INPUT@'
+]
+
+tap_rss_o = custom_target(
+    'tap_rss.bpf.o',
+    input: 'tap_rss.c',
+    output: 'tap_rss.o',
+    command: bpf_o_cmd)
+
+tap_rss_skel_h = custom_target(
+    'tap_rss.skel.h',
+    input: tap_rss_o,
+    output: 'tap_rss.skel.h',
+    command: skel_h_cmd,
+    capture: true)
diff --git a/drivers/net/tap/bpf/tap_bpf_program.c b/drivers/net/tap/bpf/tap_bpf_program.c
deleted file mode 100644
index f05aed021c30..000000000000
--- a/drivers/net/tap/bpf/tap_bpf_program.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
- * Copyright 2017 Mellanox Technologies, Ltd
- */
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <asm/types.h>
-#include <linux/in.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/if_tunnel.h>
-#include <linux/filter.h>
-
-#include "bpf_api.h"
-#include "bpf_elf.h"
-#include "../tap_rss.h"
-
-/** Create IPv4 address */
-#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
-		(((b) & 0xff) << 16) | \
-		(((c) & 0xff) << 8)  | \
-		((d) & 0xff))
-
-#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
-		((b) & 0xff))
-
-/*
- * The queue number is offset by a unique QUEUE_OFFSET, to distinguish
- * packets that have gone through this rule (skb->cb[1] != 0) from others.
- */
-#define QUEUE_OFFSET		0x7cafe800
-#define PIN_GLOBAL_NS		2
-
-#define KEY_IDX			0
-#define BPF_MAP_ID_KEY	1
-
-struct vlan_hdr {
-	__be16 proto;
-	__be16 tci;
-};
-
-struct bpf_elf_map __attribute__((section("maps"), used))
-map_keys = {
-	.type           =       BPF_MAP_TYPE_HASH,
-	.id             =       BPF_MAP_ID_KEY,
-	.size_key       =       sizeof(__u32),
-	.size_value     =       sizeof(struct rss_key),
-	.max_elem       =       256,
-	.pinning        =       PIN_GLOBAL_NS,
-};
-
-__section("cls_q") int
-match_q(struct __sk_buff *skb)
-{
-	__u32 queue = skb->cb[1];
-	/* queue is set by tap_flow_bpf_cls_q() before load */
-	volatile __u32 q = 0xdeadbeef;
-	__u32 match_queue = QUEUE_OFFSET + q;
-
-	/* printt("match_q$i() queue = %d\n", queue); */
-
-	if (queue != match_queue)
-		return TC_ACT_OK;
-
-	/* queue match */
-	skb->cb[1] = 0;
-	return TC_ACT_UNSPEC;
-}
-
-
-struct ipv4_l3_l4_tuple {
-	__u32    src_addr;
-	__u32    dst_addr;
-	__u16    dport;
-	__u16    sport;
-} __attribute__((packed));
-
-struct ipv6_l3_l4_tuple {
-	__u8        src_addr[16];
-	__u8        dst_addr[16];
-	__u16       dport;
-	__u16       sport;
-} __attribute__((packed));
-
-static const __u8 def_rss_key[TAP_RSS_HASH_KEY_SIZE] = {
-	0xd1, 0x81, 0xc6, 0x2c,
-	0xf7, 0xf4, 0xdb, 0x5b,
-	0x19, 0x83, 0xa2, 0xfc,
-	0x94, 0x3e, 0x1a, 0xdb,
-	0xd9, 0x38, 0x9e, 0x6b,
-	0xd1, 0x03, 0x9c, 0x2c,
-	0xa7, 0x44, 0x99, 0xad,
-	0x59, 0x3d, 0x56, 0xd9,
-	0xf3, 0x25, 0x3c, 0x06,
-	0x2a, 0xdc, 0x1f, 0xfc,
-};
-
-static __u32  __attribute__((always_inline))
-rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
-		__u8 input_len)
-{
-	__u32 i, j, hash = 0;
-#pragma unroll
-	for (j = 0; j < input_len; j++) {
-#pragma unroll
-		for (i = 0; i < 32; i++) {
-			if (input_tuple[j] & (1U << (31 - i))) {
-				hash ^= ((const __u32 *)def_rss_key)[j] << i |
-				(__u32)((uint64_t)
-				(((const __u32 *)def_rss_key)[j + 1])
-					>> (32 - i));
-			}
-		}
-	}
-	return hash;
-}
-
-static int __attribute__((always_inline))
-rss_l3_l4(struct __sk_buff *skb)
-{
-	void *data_end = (void *)(long)skb->data_end;
-	void *data = (void *)(long)skb->data;
-	__u16 proto = (__u16)skb->protocol;
-	__u32 key_idx = 0xdeadbeef;
-	__u32 hash;
-	struct rss_key *rsskey;
-	__u64 off = ETH_HLEN;
-	int j;
-	__u8 *key = 0;
-	__u32 len;
-	__u32 queue = 0;
-	bool mf = 0;
-	__u16 frag_off = 0;
-
-	rsskey = map_lookup_elem(&map_keys, &key_idx);
-	if (!rsskey) {
-		printt("hash(): rss key is not configured\n");
-		return TC_ACT_OK;
-	}
-	key = (__u8 *)rsskey->key;
-
-	/* Get correct proto for 802.1ad */
-	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
-		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
-		    sizeof(proto) > data_end)
-			return TC_ACT_OK;
-		proto = *(__u16 *)(data + ETH_ALEN * 2 +
-				   sizeof(struct vlan_hdr));
-		off += sizeof(struct vlan_hdr);
-	}
-
-	if (proto == htons(ETH_P_IP)) {
-		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
-			> data_end)
-			return TC_ACT_OK;
-
-		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
-		__u8 *frag_off_addr = data + off + offsetof(struct iphdr, frag_off);
-		__u8 *prot_addr = data + off + offsetof(struct iphdr, protocol);
-		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
-		struct ipv4_l3_l4_tuple v4_tuple = {
-			.src_addr = IPv4(*(src_dst_addr + 0),
-					*(src_dst_addr + 1),
-					*(src_dst_addr + 2),
-					*(src_dst_addr + 3)),
-			.dst_addr = IPv4(*(src_dst_addr + 4),
-					*(src_dst_addr + 5),
-					*(src_dst_addr + 6),
-					*(src_dst_addr + 7)),
-			.sport = 0,
-			.dport = 0,
-		};
-		/** Fetch the L4-payer port numbers only in-case of TCP/UDP
-		 ** and also if the packet is not fragmented. Since fragmented
-		 ** chunks do not have L4 TCP/UDP header.
-		 **/
-		if (*prot_addr == IPPROTO_UDP || *prot_addr == IPPROTO_TCP) {
-			frag_off = PORT(*(frag_off_addr + 0),
-					*(frag_off_addr + 1));
-			mf = frag_off & 0x2000;
-			frag_off = frag_off & 0x1fff;
-			if (mf == 0 && frag_off == 0) {
-				v4_tuple.sport = PORT(*(src_dst_port + 0),
-						*(src_dst_port + 1));
-				v4_tuple.dport = PORT(*(src_dst_port + 2),
-						*(src_dst_port + 3));
-			}
-		}
-		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
-	} else if (proto == htons(ETH_P_IPV6)) {
-		if (data + off + sizeof(struct ipv6hdr) +
-					sizeof(__u32) > data_end)
-			return TC_ACT_OK;
-		__u8 *src_dst_addr = data + off +
-					offsetof(struct ipv6hdr, saddr);
-		__u8 *src_dst_port = data + off +
-					sizeof(struct ipv6hdr);
-		__u8 *next_hdr = data + off +
-					offsetof(struct ipv6hdr, nexthdr);
-
-		struct ipv6_l3_l4_tuple v6_tuple;
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.src_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + j));
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.dst_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + 4 + j));
-
-		/** Fetch the L4 header port-numbers only if next-header
-		 * is TCP/UDP **/
-		if (*next_hdr == IPPROTO_UDP || *next_hdr == IPPROTO_TCP) {
-			v6_tuple.sport = PORT(*(src_dst_port + 0),
-				      *(src_dst_port + 1));
-			v6_tuple.dport = PORT(*(src_dst_port + 2),
-				      *(src_dst_port + 3));
-		} else {
-			v6_tuple.sport = 0;
-			v6_tuple.dport = 0;
-		}
-
-		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
-	} else {
-		return TC_ACT_PIPE;
-	}
-
-	queue = rsskey->queues[(hash % rsskey->nb_queues) &
-				       (TAP_MAX_QUEUES - 1)];
-	skb->cb[1] = QUEUE_OFFSET + queue;
-	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
-
-	return TC_ACT_RECLASSIFY;
-}
-
-#define RSS(L)						\
-	__section(#L) int				\
-		L ## _hash(struct __sk_buff *skb)	\
-	{						\
-		return rss_ ## L (skb);			\
-	}
-
-RSS(l3_l4)
-
-BPF_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/tap/bpf/tap_rss.c b/drivers/net/tap/bpf/tap_rss.c
new file mode 100644
index 000000000000..1abd18cb606e
--- /dev/null
+++ b/drivers/net/tap/bpf/tap_rss.c
@@ -0,0 +1,272 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+ * Copyright 2017 Mellanox Technologies, Ltd
+ */
+
+#include <linux/in.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/pkt_cls.h>
+#include <linux/bpf.h>
+
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+
+#include "../tap_rss.h"
+
+/*
+ * This map provides configuration information about flows
+ * which need BPF RSS.
+ *
+ * The hash is indexed by the tc_index.
+ */
+struct {
+	__uint(type, BPF_MAP_TYPE_HASH);
+	__uint(key_size, sizeof(__u16));
+	__uint(value_size, sizeof(struct rss_key));
+	__uint(max_entries, TAP_MAX_QUEUES);
+} rss_map SEC(".maps");
+
+
+#define IP_MF		0x2000		/** IP header Flags **/
+#define IP_OFFSET	0x1FFF		/** IP header fragment offset **/
+
+/*
+ * Compute Toeplitz hash over the input tuple.
+ * This is same as rte_softrss_be in lib/hash
+ * but loop needs to be setup to match BPF restrictions.
+ */
+static __u32 __attribute__((always_inline))
+softrss_be(const __u32 *input_tuple, __u32 input_len, const __u32 *key)
+{
+	__u32 i, j, hash = 0;
+
+#pragma unroll
+	for (j = 0; j < input_len; j++) {
+#pragma unroll
+		for (i = 0; i < 32; i++) {
+			if (input_tuple[j] & (1U << (31 - i)))
+				hash ^= key[j] << i | key[j + 1] >> (32 - i);
+		}
+	}
+	return hash;
+}
+
+/* Compute RSS hash for IPv4 packet.
+ * return in 0 if RSS not specified
+ */
+static __u32 __attribute__((always_inline))
+parse_ipv4(const struct __sk_buff *skb, __u32 hash_type, const __u32 *key)
+{
+	struct iphdr iph;
+	__u32 off = 0;
+
+	if (bpf_skb_load_bytes_relative(skb, off, &iph, sizeof(iph), BPF_HDR_START_NET))
+		return 0;	/* no IP header present */
+
+	struct {
+		__u32    src_addr;
+		__u32    dst_addr;
+		__u16    dport;
+		__u16    sport;
+	} v4_tuple = {
+		.src_addr = bpf_ntohl(iph.saddr),
+		.dst_addr = bpf_ntohl(iph.daddr),
+	};
+
+	/* If only calculating L3 hash, do it now */
+	if (hash_type & (1 << HASH_FIELD_IPV4_L3))
+		return softrss_be((__u32 *)&v4_tuple, sizeof(v4_tuple) / sizeof(__u32) - 1, key);
+
+	/* No L4 if packet is a fragmented */
+	if ((iph.frag_off & bpf_htons(IP_MF | IP_OFFSET)) != 0)
+		return 0;
+
+	/* Do RSS on UDP or TCP ports */
+	if (iph.protocol == IPPROTO_UDP || iph.protocol == IPPROTO_TCP) {
+		__u16 src_dst_port[2];
+
+		off += iph.ihl * 4;
+		if (bpf_skb_load_bytes_relative(skb, off, &src_dst_port, sizeof(src_dst_port),
+						BPF_HDR_START_NET))
+			return 0; /* TCP or UDP header missing */
+
+		v4_tuple.sport = bpf_ntohs(src_dst_port[0]);
+		v4_tuple.dport = bpf_ntohs(src_dst_port[1]);
+		return softrss_be((__u32 *)&v4_tuple, sizeof(v4_tuple) / sizeof(__u32), key);
+	}
+
+	/* Other protocol */
+	return 0;
+}
+
+/* parse ipv6 extended headers, update offset and return next proto.
+ * returns next proto on success, -1 on malformed header
+ */
+static int __attribute__((always_inline))
+skip_ip6_ext(__u16 proto, const struct __sk_buff *skb, __u32 *off, int *frag)
+{
+	struct ext_hdr {
+		__u8 next_hdr;
+		__u8 len;
+	} xh;
+	unsigned int i;
+
+	*frag = 0;
+
+#define MAX_EXT_HDRS 5
+#pragma unroll
+	for (i = 0; i < MAX_EXT_HDRS; i++) {
+		switch (proto) {
+		case IPPROTO_HOPOPTS:
+		case IPPROTO_ROUTING:
+		case IPPROTO_DSTOPTS:
+			if (bpf_skb_load_bytes_relative(skb, *off, &xh, sizeof(xh),
+							BPF_HDR_START_NET))
+				return -1;
+
+			*off += (xh.len + 1) * 8;
+			proto = xh.next_hdr;
+			break;
+		case IPPROTO_FRAGMENT:
+			if (bpf_skb_load_bytes_relative(skb, *off, &xh, sizeof(xh),
+							BPF_HDR_START_NET))
+				return -1;
+
+			*off += 8;
+			proto = xh.next_hdr;
+			*frag = 1;
+			return proto; /* this is always the last ext hdr */
+		default:
+			return proto;
+		}
+	}
+
+	/* too many extension headers give up */
+	return -1;
+}
+
+static __u32 __attribute__((always_inline))
+parse_ipv6(const struct __sk_buff *skb, __u32 hash_type, const __u32 *key)
+{
+	struct {
+		__u32       src_addr[4];
+		__u32       dst_addr[4];
+		__u16       dport;
+		__u16       sport;
+	} v6_tuple = { };
+	struct ipv6hdr ip6h;
+	__u32 off = 0, j;
+	int proto, frag;
+
+	if (bpf_skb_load_bytes_relative(skb, off, &ip6h, sizeof(ip6h), BPF_HDR_START_NET))
+		return 0;
+
+#pragma unroll
+	for (j = 0; j < 4; j++) {
+		v6_tuple.src_addr[j] = bpf_ntohl(ip6h.saddr.in6_u.u6_addr32[j]);
+		v6_tuple.dst_addr[j] = bpf_ntohl(ip6h.daddr.in6_u.u6_addr32[j]);
+	}
+
+	if (hash_type & (1 << HASH_FIELD_IPV6_L3))
+		return softrss_be((__u32 *)&v6_tuple, sizeof(v6_tuple) / sizeof(__u32) - 1, key);
+
+	off += sizeof(ip6h);
+	proto = skip_ip6_ext(ip6h.nexthdr, skb, &off, &frag);
+	if (proto < 0)
+		return 0;
+
+	if (frag)
+		return 0;
+
+	/* Do RSS on UDP or TCP ports */
+	if (proto == IPPROTO_UDP || proto == IPPROTO_TCP) {
+		__u16 src_dst_port[2];
+
+		if (bpf_skb_load_bytes_relative(skb, off, &src_dst_port, sizeof(src_dst_port),
+						BPF_HDR_START_NET))
+			return 0;
+
+		v6_tuple.sport = bpf_ntohs(src_dst_port[0]);
+		v6_tuple.dport = bpf_ntohs(src_dst_port[1]);
+
+		return softrss_be((__u32 *)&v6_tuple, sizeof(v6_tuple) / sizeof(__u32), key);
+	}
+
+	return 0;
+}
+
+/*
+ * Compute RSS hash for packets.
+ * Returns 0 if no hash is possible.
+ */
+static __u32 __attribute__((always_inline))
+calculate_rss_hash(const struct __sk_buff *skb, const struct rss_key *rsskey)
+{
+	const __u32 *key = (const __u32 *)rsskey->key;
+
+	if (skb->protocol == bpf_htons(ETH_P_IP))
+		return parse_ipv4(skb, rsskey->hash_fields, key);
+	else if (skb->protocol == bpf_htons(ETH_P_IPV6))
+		return parse_ipv6(skb, rsskey->hash_fields, key);
+	else
+		return 0;
+}
+
+/* scale value to be into range [0, n), assumes val is large */
+static __u32  __attribute__((always_inline))
+reciprocal_scale(__u32 val, __u32 n)
+{
+	return (__u32)(((__u64)val * n) >> 32);
+}
+
+/* layout of qdisc skb cb (from sch_generic.h) */
+struct qdisc_skb_cb {
+	struct {
+		unsigned int	pkt_len;
+		__u16		dev_queue_mapping;
+		__u16		tc_classid;
+	};
+#define QDISC_CB_PRIV_LEN 20
+	unsigned char		data[QDISC_CB_PRIV_LEN];
+};
+
+/*
+ * When this BPF program is run by tc from the filter classifier,
+ * it is able to read skb metadata and packet data.
+ *
+ * For packets where RSS is not possible, then just return TC_ACT_OK.
+ * When RSS is desired, change the skb->queue_mapping and set TC_ACT_PIPE
+ * to continue processing.
+ *
+ * This should be BPF_PROG_TYPE_SCHED_ACT so section needs to be "action"
+ */
+SEC("action") int
+rss_flow_action(struct __sk_buff *skb)
+{
+	const struct rss_key *rsskey;
+	__u16 classid;
+	__u32 hash;
+
+	/* TC layer puts the BPF_CLASSID into the skb cb area */
+	classid = ((const struct qdisc_skb_cb *)skb->cb)->tc_classid;
+
+	/* Lookup RSS configuration for that BPF class */
+	rsskey = bpf_map_lookup_elem(&rss_map, &classid);
+	if (rsskey == NULL) {
+		bpf_printk("hash(): rss not configured");
+		return TC_ACT_OK;
+	}
+
+	hash = calculate_rss_hash(skb, rsskey);
+	bpf_printk("hash %u\n", hash);
+	if (hash) {
+		/* Fold hash to the number of queues configured */
+		skb->queue_mapping = reciprocal_scale(hash, rsskey->nb_queues);
+		bpf_printk("queue %u\n", skb->queue_mapping);
+		return TC_ACT_PIPE;
+	}
+	return TC_ACT_OK;
+}
+
+char _license[] SEC("license") = "Dual BSD/GPL";
-- 
2.43.0


^ permalink raw reply	[relevance 2%]

* [PATCH v3 4/7] net/tap: rewrite the RSS BPF program
  @ 2024-02-08 17:41  2%   ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2024-02-08 17:41 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Rewrite the BPF program used to do queue based RSS.
Important changes:
	- uses newer BPF map format BTF
	- accepts key as parameter rather than constant default
	- can do L3 or L4 hashing
	- supports IPv4 options
	- supports IPv6 extension headers
	- restructured for readability

The usage of BPF is different as well:
	- the incoming configuration is looked up based on
	  class parameters rather than patching the BPF.
	- the resulting queue is placed in skb rather
	  than requiring a second pass through classifier step.

Note: This version only works with later patch to enable it on
the DPDK driver side. It is submitted as an incremental patch
to allow for easier review. Bisection still works because
the old instruction are still present for now.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 .gitignore                            |   3 -
 drivers/net/tap/bpf/Makefile          |  19 --
 drivers/net/tap/bpf/README            |  12 ++
 drivers/net/tap/bpf/bpf_api.h         | 276 --------------------------
 drivers/net/tap/bpf/bpf_elf.h         |  53 -----
 drivers/net/tap/bpf/bpf_extract.py    |  85 --------
 drivers/net/tap/bpf/meson.build       |  81 ++++++++
 drivers/net/tap/bpf/tap_bpf_program.c | 255 ------------------------
 drivers/net/tap/bpf/tap_rss.c         | 272 +++++++++++++++++++++++++
 9 files changed, 365 insertions(+), 691 deletions(-)
 delete mode 100644 drivers/net/tap/bpf/Makefile
 create mode 100644 drivers/net/tap/bpf/README
 delete mode 100644 drivers/net/tap/bpf/bpf_api.h
 delete mode 100644 drivers/net/tap/bpf/bpf_elf.h
 delete mode 100644 drivers/net/tap/bpf/bpf_extract.py
 create mode 100644 drivers/net/tap/bpf/meson.build
 delete mode 100644 drivers/net/tap/bpf/tap_bpf_program.c
 create mode 100644 drivers/net/tap/bpf/tap_rss.c

diff --git a/.gitignore b/.gitignore
index 3f444dcace2e..01a47a760660 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,9 +36,6 @@ TAGS
 # ignore python bytecode files
 *.pyc
 
-# ignore BPF programs
-drivers/net/tap/bpf/tap_bpf_program.o
-
 # DTS results
 dts/output
 
diff --git a/drivers/net/tap/bpf/Makefile b/drivers/net/tap/bpf/Makefile
deleted file mode 100644
index 9efeeb1bc704..000000000000
--- a/drivers/net/tap/bpf/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# This file is not built as part of normal DPDK build.
-# It is used to generate the eBPF code for TAP RSS.
-
-CLANG=clang
-CLANG_OPTS=-O2
-TARGET=../tap_bpf_insns.h
-
-all: $(TARGET)
-
-clean:
-	rm tap_bpf_program.o $(TARGET)
-
-tap_bpf_program.o: tap_bpf_program.c
-	$(CLANG) $(CLANG_OPTS) -emit-llvm -c $< -o - | \
-	llc -march=bpf -filetype=obj -o $@
-
-$(TARGET): tap_bpf_program.o
-	python3 bpf_extract.py -stap_bpf_program.c -o $@ $<
diff --git a/drivers/net/tap/bpf/README b/drivers/net/tap/bpf/README
new file mode 100644
index 000000000000..960a10da73b8
--- /dev/null
+++ b/drivers/net/tap/bpf/README
@@ -0,0 +1,12 @@
+This is the BPF program used to implement the RSS across queues
+flow action. It works like the skbedit tc filter but instead of mapping
+to only one queues, it maps to multiple queues based on RSS hash.
+
+This version is built the BPF Compile Once — Run Everywhere (CO-RE)
+framework and uses libbpf and bpftool.
+
+Limitations
+- requires libbpf version XX or later
+- rebuilding the BPF requires clang and bpftool
+- only Toeplitz hash with standard 40 byte key is supported
+- the number of queues per RSS action is limited to 16
diff --git a/drivers/net/tap/bpf/bpf_api.h b/drivers/net/tap/bpf/bpf_api.h
deleted file mode 100644
index 2638a8a4ac9a..000000000000
--- a/drivers/net/tap/bpf/bpf_api.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-
-#ifndef __BPF_API__
-#define __BPF_API__
-
-/* Note:
- *
- * This file can be included into eBPF kernel programs. It contains
- * a couple of useful helper functions, map/section ABI (bpf_elf.h),
- * misc macros and some eBPF specific LLVM built-ins.
- */
-
-#include <stdint.h>
-
-#include <linux/pkt_cls.h>
-#include <linux/bpf.h>
-#include <linux/filter.h>
-
-#include <asm/byteorder.h>
-
-#include "bpf_elf.h"
-
-/** libbpf pin type. */
-enum libbpf_pin_type {
-	LIBBPF_PIN_NONE,
-	/* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */
-	LIBBPF_PIN_BY_NAME,
-};
-
-/** Type helper macros. */
-
-#define __uint(name, val) int (*name)[val]
-#define __type(name, val) typeof(val) *name
-#define __array(name, val) typeof(val) *name[]
-
-/** Misc macros. */
-
-#ifndef __stringify
-# define __stringify(X)		#X
-#endif
-
-#ifndef __maybe_unused
-# define __maybe_unused		__attribute__((__unused__))
-#endif
-
-#ifndef offsetof
-# define offsetof(TYPE, MEMBER)	__builtin_offsetof(TYPE, MEMBER)
-#endif
-
-#ifndef likely
-# define likely(X)		__builtin_expect(!!(X), 1)
-#endif
-
-#ifndef unlikely
-# define unlikely(X)		__builtin_expect(!!(X), 0)
-#endif
-
-#ifndef htons
-# define htons(X)		__constant_htons((X))
-#endif
-
-#ifndef ntohs
-# define ntohs(X)		__constant_ntohs((X))
-#endif
-
-#ifndef htonl
-# define htonl(X)		__constant_htonl((X))
-#endif
-
-#ifndef ntohl
-# define ntohl(X)		__constant_ntohl((X))
-#endif
-
-#ifndef __inline__
-# define __inline__		__attribute__((always_inline))
-#endif
-
-/** Section helper macros. */
-
-#ifndef __section
-# define __section(NAME)						\
-	__attribute__((section(NAME), used))
-#endif
-
-#ifndef __section_tail
-# define __section_tail(ID, KEY)					\
-	__section(__stringify(ID) "/" __stringify(KEY))
-#endif
-
-#ifndef __section_xdp_entry
-# define __section_xdp_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_cls_entry
-# define __section_cls_entry						\
-	__section(ELF_SECTION_CLASSIFIER)
-#endif
-
-#ifndef __section_act_entry
-# define __section_act_entry						\
-	__section(ELF_SECTION_ACTION)
-#endif
-
-#ifndef __section_lwt_entry
-# define __section_lwt_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_license
-# define __section_license						\
-	__section(ELF_SECTION_LICENSE)
-#endif
-
-#ifndef __section_maps
-# define __section_maps							\
-	__section(ELF_SECTION_MAPS)
-#endif
-
-/** Declaration helper macros. */
-
-#ifndef BPF_LICENSE
-# define BPF_LICENSE(NAME)						\
-	char ____license[] __section_license = NAME
-#endif
-
-/** Classifier helper */
-
-#ifndef BPF_H_DEFAULT
-# define BPF_H_DEFAULT	-1
-#endif
-
-/** BPF helper functions for tc. Individual flags are in linux/bpf.h */
-
-#ifndef __BPF_FUNC
-# define __BPF_FUNC(NAME, ...)						\
-	(* NAME)(__VA_ARGS__) __maybe_unused
-#endif
-
-#ifndef BPF_FUNC
-# define BPF_FUNC(NAME, ...)						\
-	__BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME
-#endif
-
-/* Map access/manipulation */
-static void *BPF_FUNC(map_lookup_elem, void *map, const void *key);
-static int BPF_FUNC(map_update_elem, void *map, const void *key,
-		    const void *value, uint32_t flags);
-static int BPF_FUNC(map_delete_elem, void *map, const void *key);
-
-/* Time access */
-static uint64_t BPF_FUNC(ktime_get_ns);
-
-/* Debugging */
-
-/* FIXME: __attribute__ ((format(printf, 1, 3))) not possible unless
- * llvm bug https://llvm.org/bugs/show_bug.cgi?id=26243 gets resolved.
- * It would require ____fmt to be made const, which generates a reloc
- * entry (non-map).
- */
-static void BPF_FUNC(trace_printk, const char *fmt, int fmt_size, ...);
-
-#ifndef printt
-# define printt(fmt, ...)						\
-	({								\
-		char ____fmt[] = fmt;					\
-		trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__);	\
-	})
-#endif
-
-/* Random numbers */
-static uint32_t BPF_FUNC(get_prandom_u32);
-
-/* Tail calls */
-static void BPF_FUNC(tail_call, struct __sk_buff *skb, void *map,
-		     uint32_t index);
-
-/* System helpers */
-static uint32_t BPF_FUNC(get_smp_processor_id);
-static uint32_t BPF_FUNC(get_numa_node_id);
-
-/* Packet misc meta data */
-static uint32_t BPF_FUNC(get_cgroup_classid, struct __sk_buff *skb);
-static int BPF_FUNC(skb_under_cgroup, void *map, uint32_t index);
-
-static uint32_t BPF_FUNC(get_route_realm, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(get_hash_recalc, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(set_hash_invalid, struct __sk_buff *skb);
-
-/* Packet redirection */
-static int BPF_FUNC(redirect, int ifindex, uint32_t flags);
-static int BPF_FUNC(clone_redirect, struct __sk_buff *skb, int ifindex,
-		    uint32_t flags);
-
-/* Packet manipulation */
-static int BPF_FUNC(skb_load_bytes, struct __sk_buff *skb, uint32_t off,
-		    void *to, uint32_t len);
-static int BPF_FUNC(skb_store_bytes, struct __sk_buff *skb, uint32_t off,
-		    const void *from, uint32_t len, uint32_t flags);
-
-static int BPF_FUNC(l3_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(l4_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(csum_diff, const void *from, uint32_t from_size,
-		    const void *to, uint32_t to_size, uint32_t seed);
-static int BPF_FUNC(csum_update, struct __sk_buff *skb, uint32_t wsum);
-
-static int BPF_FUNC(skb_change_type, struct __sk_buff *skb, uint32_t type);
-static int BPF_FUNC(skb_change_proto, struct __sk_buff *skb, uint32_t proto,
-		    uint32_t flags);
-static int BPF_FUNC(skb_change_tail, struct __sk_buff *skb, uint32_t nlen,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_pull_data, struct __sk_buff *skb, uint32_t len);
-
-/* Event notification */
-static int __BPF_FUNC(skb_event_output, struct __sk_buff *skb, void *map,
-		      uint64_t index, const void *data, uint32_t size) =
-		      (void *) BPF_FUNC_perf_event_output;
-
-/* Packet vlan encap/decap */
-static int BPF_FUNC(skb_vlan_push, struct __sk_buff *skb, uint16_t proto,
-		    uint16_t vlan_tci);
-static int BPF_FUNC(skb_vlan_pop, struct __sk_buff *skb);
-
-/* Packet tunnel encap/decap */
-static int BPF_FUNC(skb_get_tunnel_key, struct __sk_buff *skb,
-		    struct bpf_tunnel_key *to, uint32_t size, uint32_t flags);
-static int BPF_FUNC(skb_set_tunnel_key, struct __sk_buff *skb,
-		    const struct bpf_tunnel_key *from, uint32_t size,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_get_tunnel_opt, struct __sk_buff *skb,
-		    void *to, uint32_t size);
-static int BPF_FUNC(skb_set_tunnel_opt, struct __sk_buff *skb,
-		    const void *from, uint32_t size);
-
-/** LLVM built-ins, mem*() routines work for constant size */
-
-#ifndef lock_xadd
-# define lock_xadd(ptr, val)	((void) __sync_fetch_and_add(ptr, val))
-#endif
-
-#ifndef memset
-# define memset(s, c, n)	__builtin_memset((s), (c), (n))
-#endif
-
-#ifndef memcpy
-# define memcpy(d, s, n)	__builtin_memcpy((d), (s), (n))
-#endif
-
-#ifndef memmove
-# define memmove(d, s, n)	__builtin_memmove((d), (s), (n))
-#endif
-
-/* FIXME: __builtin_memcmp() is not yet fully usable unless llvm bug
- * https://llvm.org/bugs/show_bug.cgi?id=26218 gets resolved. Also
- * this one would generate a reloc entry (non-map), otherwise.
- */
-#if 0
-#ifndef memcmp
-# define memcmp(a, b, n)	__builtin_memcmp((a), (b), (n))
-#endif
-#endif
-
-unsigned long long load_byte(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.byte");
-
-unsigned long long load_half(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.half");
-
-unsigned long long load_word(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.word");
-
-#endif /* __BPF_API__ */
diff --git a/drivers/net/tap/bpf/bpf_elf.h b/drivers/net/tap/bpf/bpf_elf.h
deleted file mode 100644
index ea8a11c95c0f..000000000000
--- a/drivers/net/tap/bpf/bpf_elf.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-#ifndef __BPF_ELF__
-#define __BPF_ELF__
-
-#include <asm/types.h>
-
-/* Note:
- *
- * Below ELF section names and bpf_elf_map structure definition
- * are not (!) kernel ABI. It's rather a "contract" between the
- * application and the BPF loader in tc. For compatibility, the
- * section names should stay as-is. Introduction of aliases, if
- * needed, are a possibility, though.
- */
-
-/* ELF section names, etc */
-#define ELF_SECTION_LICENSE	"license"
-#define ELF_SECTION_MAPS	"maps"
-#define ELF_SECTION_PROG	"prog"
-#define ELF_SECTION_CLASSIFIER	"classifier"
-#define ELF_SECTION_ACTION	"action"
-
-#define ELF_MAX_MAPS		64
-#define ELF_MAX_LICENSE_LEN	128
-
-/* Object pinning settings */
-#define PIN_NONE		0
-#define PIN_OBJECT_NS		1
-#define PIN_GLOBAL_NS		2
-
-/* ELF map definition */
-struct bpf_elf_map {
-	__u32 type;
-	__u32 size_key;
-	__u32 size_value;
-	__u32 max_elem;
-	__u32 flags;
-	__u32 id;
-	__u32 pinning;
-	__u32 inner_id;
-	__u32 inner_idx;
-};
-
-#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val)		\
-	struct ____btf_map_##name {				\
-		type_key key;					\
-		type_val value;					\
-	};							\
-	struct ____btf_map_##name				\
-	    __attribute__ ((section(".maps." #name), used))	\
-	    ____btf_map_##name = { }
-
-#endif /* __BPF_ELF__ */
diff --git a/drivers/net/tap/bpf/bpf_extract.py b/drivers/net/tap/bpf/bpf_extract.py
deleted file mode 100644
index 73c4dafe4eca..000000000000
--- a/drivers/net/tap/bpf/bpf_extract.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright (c) 2023 Stephen Hemminger <stephen@networkplumber.org>
-
-import argparse
-import sys
-import struct
-from tempfile import TemporaryFile
-from elftools.elf.elffile import ELFFile
-
-
-def load_sections(elffile):
-    """Get sections of interest from ELF"""
-    result = []
-    parts = [("cls_q", "cls_q_insns"), ("l3_l4", "l3_l4_hash_insns")]
-    for name, tag in parts:
-        section = elffile.get_section_by_name(name)
-        if section:
-            insns = struct.iter_unpack('<BBhL', section.data())
-            result.append([tag, insns])
-    return result
-
-
-def dump_section(name, insns, out):
-    """Dump the array of BPF instructions"""
-    print(f'\nstatic struct bpf_insn {name}[] = {{', file=out)
-    for bpf in insns:
-        code = bpf[0]
-        src = bpf[1] >> 4
-        dst = bpf[1] & 0xf
-        off = bpf[2]
-        imm = bpf[3]
-        print(f'\t{{{code:#04x}, {dst:4d}, {src:4d}, {off:8d}, {imm:#010x}}},',
-              file=out)
-    print('};', file=out)
-
-
-def parse_args():
-    """Parse command line arguments"""
-    parser = argparse.ArgumentParser()
-    parser.add_argument('-s',
-                        '--source',
-                        type=str,
-                        help="original source file")
-    parser.add_argument('-o', '--out', type=str, help="output C file path")
-    parser.add_argument("file",
-                        nargs='+',
-                        help="object file path or '-' for stdin")
-    return parser.parse_args()
-
-
-def open_input(path):
-    """Open the file or stdin"""
-    if path == "-":
-        temp = TemporaryFile()
-        temp.write(sys.stdin.buffer.read())
-        return temp
-    return open(path, 'rb')
-
-
-def write_header(out, source):
-    """Write file intro header"""
-    print("/* SPDX-License-Identifier: BSD-3-Clause", file=out)
-    if source:
-        print(f' * Auto-generated from {source}', file=out)
-    print(" * This not the original source file. Do NOT edit it.", file=out)
-    print(" */\n", file=out)
-
-
-def main():
-    '''program main function'''
-    args = parse_args()
-
-    with open(args.out, 'w',
-              encoding="utf-8") if args.out else sys.stdout as out:
-        write_header(out, args.source)
-        for path in args.file:
-            elffile = ELFFile(open_input(path))
-            sections = load_sections(elffile)
-            for name, insns in sections:
-                dump_section(name, insns, out)
-
-
-if __name__ == "__main__":
-    main()
diff --git a/drivers/net/tap/bpf/meson.build b/drivers/net/tap/bpf/meson.build
new file mode 100644
index 000000000000..f2c03a19fd4d
--- /dev/null
+++ b/drivers/net/tap/bpf/meson.build
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2024 Stephen Hemminger <stephen@networkplumber.org>
+
+enable_tap_rss = false
+
+libbpf = dependency('libbpf', required: false, method: 'pkg-config')
+if not libbpf.found()
+    message('net/tap: no RSS support missing libbpf')
+    subdir_done()
+endif
+
+# Debian install this in /usr/sbin which is not in $PATH
+bpftool = find_program('bpftool', '/usr/sbin/bpftool', required: false, version: '>= 5.6.0')
+if not bpftool.found()
+    message('net/tap: no RSS support missing bpftool')
+    subdir_done()
+endif
+
+clang_supports_bpf = false
+clang = find_program('clang', required: false)
+if clang.found()
+    clang_supports_bpf = run_command(clang, '-target', 'bpf', '--print-supported-cpus',
+                                     check: false).returncode() == 0
+endif
+
+if not clang_supports_bpf
+    message('net/tap: no RSS support missing clang BPF')
+    subdir_done()
+endif
+
+enable_tap_rss = true
+
+libbpf_include_dir = libbpf.get_variable(pkgconfig : 'includedir')
+
+# The include files <linux/bpf.h> and others include <asm/types.h>
+# but <asm/types.h> is not defined for multi-lib environment target.
+# Workaround by using include directoriy from the host build environment.
+machine_name = run_command('uname', '-m').stdout().strip()
+march_include_dir = '/usr/include/' + machine_name + '-linux-gnu'
+
+clang_flags = [
+    '-O2',
+    '-Wall',
+    '-Wextra',
+    '-target',
+    'bpf',
+    '-g',
+    '-c',
+]
+
+bpf_o_cmd = [
+    clang,
+    clang_flags,
+    '-idirafter',
+    libbpf_include_dir,
+    '-idirafter',
+    march_include_dir,
+    '@INPUT@',
+    '-o',
+    '@OUTPUT@'
+]
+
+skel_h_cmd = [
+    bpftool,
+    'gen',
+    'skeleton',
+    '@INPUT@'
+]
+
+tap_rss_o = custom_target(
+    'tap_rss.bpf.o',
+    input: 'tap_rss.c',
+    output: 'tap_rss.o',
+    command: bpf_o_cmd)
+
+tap_rss_skel_h = custom_target(
+    'tap_rss.skel.h',
+    input: tap_rss_o,
+    output: 'tap_rss.skel.h',
+    command: skel_h_cmd,
+    capture: true)
diff --git a/drivers/net/tap/bpf/tap_bpf_program.c b/drivers/net/tap/bpf/tap_bpf_program.c
deleted file mode 100644
index f05aed021c30..000000000000
--- a/drivers/net/tap/bpf/tap_bpf_program.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
- * Copyright 2017 Mellanox Technologies, Ltd
- */
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <asm/types.h>
-#include <linux/in.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/if_tunnel.h>
-#include <linux/filter.h>
-
-#include "bpf_api.h"
-#include "bpf_elf.h"
-#include "../tap_rss.h"
-
-/** Create IPv4 address */
-#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
-		(((b) & 0xff) << 16) | \
-		(((c) & 0xff) << 8)  | \
-		((d) & 0xff))
-
-#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
-		((b) & 0xff))
-
-/*
- * The queue number is offset by a unique QUEUE_OFFSET, to distinguish
- * packets that have gone through this rule (skb->cb[1] != 0) from others.
- */
-#define QUEUE_OFFSET		0x7cafe800
-#define PIN_GLOBAL_NS		2
-
-#define KEY_IDX			0
-#define BPF_MAP_ID_KEY	1
-
-struct vlan_hdr {
-	__be16 proto;
-	__be16 tci;
-};
-
-struct bpf_elf_map __attribute__((section("maps"), used))
-map_keys = {
-	.type           =       BPF_MAP_TYPE_HASH,
-	.id             =       BPF_MAP_ID_KEY,
-	.size_key       =       sizeof(__u32),
-	.size_value     =       sizeof(struct rss_key),
-	.max_elem       =       256,
-	.pinning        =       PIN_GLOBAL_NS,
-};
-
-__section("cls_q") int
-match_q(struct __sk_buff *skb)
-{
-	__u32 queue = skb->cb[1];
-	/* queue is set by tap_flow_bpf_cls_q() before load */
-	volatile __u32 q = 0xdeadbeef;
-	__u32 match_queue = QUEUE_OFFSET + q;
-
-	/* printt("match_q$i() queue = %d\n", queue); */
-
-	if (queue != match_queue)
-		return TC_ACT_OK;
-
-	/* queue match */
-	skb->cb[1] = 0;
-	return TC_ACT_UNSPEC;
-}
-
-
-struct ipv4_l3_l4_tuple {
-	__u32    src_addr;
-	__u32    dst_addr;
-	__u16    dport;
-	__u16    sport;
-} __attribute__((packed));
-
-struct ipv6_l3_l4_tuple {
-	__u8        src_addr[16];
-	__u8        dst_addr[16];
-	__u16       dport;
-	__u16       sport;
-} __attribute__((packed));
-
-static const __u8 def_rss_key[TAP_RSS_HASH_KEY_SIZE] = {
-	0xd1, 0x81, 0xc6, 0x2c,
-	0xf7, 0xf4, 0xdb, 0x5b,
-	0x19, 0x83, 0xa2, 0xfc,
-	0x94, 0x3e, 0x1a, 0xdb,
-	0xd9, 0x38, 0x9e, 0x6b,
-	0xd1, 0x03, 0x9c, 0x2c,
-	0xa7, 0x44, 0x99, 0xad,
-	0x59, 0x3d, 0x56, 0xd9,
-	0xf3, 0x25, 0x3c, 0x06,
-	0x2a, 0xdc, 0x1f, 0xfc,
-};
-
-static __u32  __attribute__((always_inline))
-rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
-		__u8 input_len)
-{
-	__u32 i, j, hash = 0;
-#pragma unroll
-	for (j = 0; j < input_len; j++) {
-#pragma unroll
-		for (i = 0; i < 32; i++) {
-			if (input_tuple[j] & (1U << (31 - i))) {
-				hash ^= ((const __u32 *)def_rss_key)[j] << i |
-				(__u32)((uint64_t)
-				(((const __u32 *)def_rss_key)[j + 1])
-					>> (32 - i));
-			}
-		}
-	}
-	return hash;
-}
-
-static int __attribute__((always_inline))
-rss_l3_l4(struct __sk_buff *skb)
-{
-	void *data_end = (void *)(long)skb->data_end;
-	void *data = (void *)(long)skb->data;
-	__u16 proto = (__u16)skb->protocol;
-	__u32 key_idx = 0xdeadbeef;
-	__u32 hash;
-	struct rss_key *rsskey;
-	__u64 off = ETH_HLEN;
-	int j;
-	__u8 *key = 0;
-	__u32 len;
-	__u32 queue = 0;
-	bool mf = 0;
-	__u16 frag_off = 0;
-
-	rsskey = map_lookup_elem(&map_keys, &key_idx);
-	if (!rsskey) {
-		printt("hash(): rss key is not configured\n");
-		return TC_ACT_OK;
-	}
-	key = (__u8 *)rsskey->key;
-
-	/* Get correct proto for 802.1ad */
-	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
-		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
-		    sizeof(proto) > data_end)
-			return TC_ACT_OK;
-		proto = *(__u16 *)(data + ETH_ALEN * 2 +
-				   sizeof(struct vlan_hdr));
-		off += sizeof(struct vlan_hdr);
-	}
-
-	if (proto == htons(ETH_P_IP)) {
-		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
-			> data_end)
-			return TC_ACT_OK;
-
-		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
-		__u8 *frag_off_addr = data + off + offsetof(struct iphdr, frag_off);
-		__u8 *prot_addr = data + off + offsetof(struct iphdr, protocol);
-		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
-		struct ipv4_l3_l4_tuple v4_tuple = {
-			.src_addr = IPv4(*(src_dst_addr + 0),
-					*(src_dst_addr + 1),
-					*(src_dst_addr + 2),
-					*(src_dst_addr + 3)),
-			.dst_addr = IPv4(*(src_dst_addr + 4),
-					*(src_dst_addr + 5),
-					*(src_dst_addr + 6),
-					*(src_dst_addr + 7)),
-			.sport = 0,
-			.dport = 0,
-		};
-		/** Fetch the L4-payer port numbers only in-case of TCP/UDP
-		 ** and also if the packet is not fragmented. Since fragmented
-		 ** chunks do not have L4 TCP/UDP header.
-		 **/
-		if (*prot_addr == IPPROTO_UDP || *prot_addr == IPPROTO_TCP) {
-			frag_off = PORT(*(frag_off_addr + 0),
-					*(frag_off_addr + 1));
-			mf = frag_off & 0x2000;
-			frag_off = frag_off & 0x1fff;
-			if (mf == 0 && frag_off == 0) {
-				v4_tuple.sport = PORT(*(src_dst_port + 0),
-						*(src_dst_port + 1));
-				v4_tuple.dport = PORT(*(src_dst_port + 2),
-						*(src_dst_port + 3));
-			}
-		}
-		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
-	} else if (proto == htons(ETH_P_IPV6)) {
-		if (data + off + sizeof(struct ipv6hdr) +
-					sizeof(__u32) > data_end)
-			return TC_ACT_OK;
-		__u8 *src_dst_addr = data + off +
-					offsetof(struct ipv6hdr, saddr);
-		__u8 *src_dst_port = data + off +
-					sizeof(struct ipv6hdr);
-		__u8 *next_hdr = data + off +
-					offsetof(struct ipv6hdr, nexthdr);
-
-		struct ipv6_l3_l4_tuple v6_tuple;
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.src_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + j));
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.dst_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + 4 + j));
-
-		/** Fetch the L4 header port-numbers only if next-header
-		 * is TCP/UDP **/
-		if (*next_hdr == IPPROTO_UDP || *next_hdr == IPPROTO_TCP) {
-			v6_tuple.sport = PORT(*(src_dst_port + 0),
-				      *(src_dst_port + 1));
-			v6_tuple.dport = PORT(*(src_dst_port + 2),
-				      *(src_dst_port + 3));
-		} else {
-			v6_tuple.sport = 0;
-			v6_tuple.dport = 0;
-		}
-
-		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
-	} else {
-		return TC_ACT_PIPE;
-	}
-
-	queue = rsskey->queues[(hash % rsskey->nb_queues) &
-				       (TAP_MAX_QUEUES - 1)];
-	skb->cb[1] = QUEUE_OFFSET + queue;
-	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
-
-	return TC_ACT_RECLASSIFY;
-}
-
-#define RSS(L)						\
-	__section(#L) int				\
-		L ## _hash(struct __sk_buff *skb)	\
-	{						\
-		return rss_ ## L (skb);			\
-	}
-
-RSS(l3_l4)
-
-BPF_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/tap/bpf/tap_rss.c b/drivers/net/tap/bpf/tap_rss.c
new file mode 100644
index 000000000000..1abd18cb606e
--- /dev/null
+++ b/drivers/net/tap/bpf/tap_rss.c
@@ -0,0 +1,272 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+ * Copyright 2017 Mellanox Technologies, Ltd
+ */
+
+#include <linux/in.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/pkt_cls.h>
+#include <linux/bpf.h>
+
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+
+#include "../tap_rss.h"
+
+/*
+ * This map provides configuration information about flows
+ * which need BPF RSS.
+ *
+ * The hash is indexed by the tc_index.
+ */
+struct {
+	__uint(type, BPF_MAP_TYPE_HASH);
+	__uint(key_size, sizeof(__u16));
+	__uint(value_size, sizeof(struct rss_key));
+	__uint(max_entries, TAP_MAX_QUEUES);
+} rss_map SEC(".maps");
+
+
+#define IP_MF		0x2000		/** IP header Flags **/
+#define IP_OFFSET	0x1FFF		/** IP header fragment offset **/
+
+/*
+ * Compute Toeplitz hash over the input tuple.
+ * This is same as rte_softrss_be in lib/hash
+ * but loop needs to be setup to match BPF restrictions.
+ */
+static __u32 __attribute__((always_inline))
+softrss_be(const __u32 *input_tuple, __u32 input_len, const __u32 *key)
+{
+	__u32 i, j, hash = 0;
+
+#pragma unroll
+	for (j = 0; j < input_len; j++) {
+#pragma unroll
+		for (i = 0; i < 32; i++) {
+			if (input_tuple[j] & (1U << (31 - i)))
+				hash ^= key[j] << i | key[j + 1] >> (32 - i);
+		}
+	}
+	return hash;
+}
+
+/* Compute RSS hash for IPv4 packet.
+ * return in 0 if RSS not specified
+ */
+static __u32 __attribute__((always_inline))
+parse_ipv4(const struct __sk_buff *skb, __u32 hash_type, const __u32 *key)
+{
+	struct iphdr iph;
+	__u32 off = 0;
+
+	if (bpf_skb_load_bytes_relative(skb, off, &iph, sizeof(iph), BPF_HDR_START_NET))
+		return 0;	/* no IP header present */
+
+	struct {
+		__u32    src_addr;
+		__u32    dst_addr;
+		__u16    dport;
+		__u16    sport;
+	} v4_tuple = {
+		.src_addr = bpf_ntohl(iph.saddr),
+		.dst_addr = bpf_ntohl(iph.daddr),
+	};
+
+	/* If only calculating L3 hash, do it now */
+	if (hash_type & (1 << HASH_FIELD_IPV4_L3))
+		return softrss_be((__u32 *)&v4_tuple, sizeof(v4_tuple) / sizeof(__u32) - 1, key);
+
+	/* No L4 if packet is a fragmented */
+	if ((iph.frag_off & bpf_htons(IP_MF | IP_OFFSET)) != 0)
+		return 0;
+
+	/* Do RSS on UDP or TCP ports */
+	if (iph.protocol == IPPROTO_UDP || iph.protocol == IPPROTO_TCP) {
+		__u16 src_dst_port[2];
+
+		off += iph.ihl * 4;
+		if (bpf_skb_load_bytes_relative(skb, off, &src_dst_port, sizeof(src_dst_port),
+						BPF_HDR_START_NET))
+			return 0; /* TCP or UDP header missing */
+
+		v4_tuple.sport = bpf_ntohs(src_dst_port[0]);
+		v4_tuple.dport = bpf_ntohs(src_dst_port[1]);
+		return softrss_be((__u32 *)&v4_tuple, sizeof(v4_tuple) / sizeof(__u32), key);
+	}
+
+	/* Other protocol */
+	return 0;
+}
+
+/* parse ipv6 extended headers, update offset and return next proto.
+ * returns next proto on success, -1 on malformed header
+ */
+static int __attribute__((always_inline))
+skip_ip6_ext(__u16 proto, const struct __sk_buff *skb, __u32 *off, int *frag)
+{
+	struct ext_hdr {
+		__u8 next_hdr;
+		__u8 len;
+	} xh;
+	unsigned int i;
+
+	*frag = 0;
+
+#define MAX_EXT_HDRS 5
+#pragma unroll
+	for (i = 0; i < MAX_EXT_HDRS; i++) {
+		switch (proto) {
+		case IPPROTO_HOPOPTS:
+		case IPPROTO_ROUTING:
+		case IPPROTO_DSTOPTS:
+			if (bpf_skb_load_bytes_relative(skb, *off, &xh, sizeof(xh),
+							BPF_HDR_START_NET))
+				return -1;
+
+			*off += (xh.len + 1) * 8;
+			proto = xh.next_hdr;
+			break;
+		case IPPROTO_FRAGMENT:
+			if (bpf_skb_load_bytes_relative(skb, *off, &xh, sizeof(xh),
+							BPF_HDR_START_NET))
+				return -1;
+
+			*off += 8;
+			proto = xh.next_hdr;
+			*frag = 1;
+			return proto; /* this is always the last ext hdr */
+		default:
+			return proto;
+		}
+	}
+
+	/* too many extension headers give up */
+	return -1;
+}
+
+static __u32 __attribute__((always_inline))
+parse_ipv6(const struct __sk_buff *skb, __u32 hash_type, const __u32 *key)
+{
+	struct {
+		__u32       src_addr[4];
+		__u32       dst_addr[4];
+		__u16       dport;
+		__u16       sport;
+	} v6_tuple = { };
+	struct ipv6hdr ip6h;
+	__u32 off = 0, j;
+	int proto, frag;
+
+	if (bpf_skb_load_bytes_relative(skb, off, &ip6h, sizeof(ip6h), BPF_HDR_START_NET))
+		return 0;
+
+#pragma unroll
+	for (j = 0; j < 4; j++) {
+		v6_tuple.src_addr[j] = bpf_ntohl(ip6h.saddr.in6_u.u6_addr32[j]);
+		v6_tuple.dst_addr[j] = bpf_ntohl(ip6h.daddr.in6_u.u6_addr32[j]);
+	}
+
+	if (hash_type & (1 << HASH_FIELD_IPV6_L3))
+		return softrss_be((__u32 *)&v6_tuple, sizeof(v6_tuple) / sizeof(__u32) - 1, key);
+
+	off += sizeof(ip6h);
+	proto = skip_ip6_ext(ip6h.nexthdr, skb, &off, &frag);
+	if (proto < 0)
+		return 0;
+
+	if (frag)
+		return 0;
+
+	/* Do RSS on UDP or TCP ports */
+	if (proto == IPPROTO_UDP || proto == IPPROTO_TCP) {
+		__u16 src_dst_port[2];
+
+		if (bpf_skb_load_bytes_relative(skb, off, &src_dst_port, sizeof(src_dst_port),
+						BPF_HDR_START_NET))
+			return 0;
+
+		v6_tuple.sport = bpf_ntohs(src_dst_port[0]);
+		v6_tuple.dport = bpf_ntohs(src_dst_port[1]);
+
+		return softrss_be((__u32 *)&v6_tuple, sizeof(v6_tuple) / sizeof(__u32), key);
+	}
+
+	return 0;
+}
+
+/*
+ * Compute RSS hash for packets.
+ * Returns 0 if no hash is possible.
+ */
+static __u32 __attribute__((always_inline))
+calculate_rss_hash(const struct __sk_buff *skb, const struct rss_key *rsskey)
+{
+	const __u32 *key = (const __u32 *)rsskey->key;
+
+	if (skb->protocol == bpf_htons(ETH_P_IP))
+		return parse_ipv4(skb, rsskey->hash_fields, key);
+	else if (skb->protocol == bpf_htons(ETH_P_IPV6))
+		return parse_ipv6(skb, rsskey->hash_fields, key);
+	else
+		return 0;
+}
+
+/* scale value to be into range [0, n), assumes val is large */
+static __u32  __attribute__((always_inline))
+reciprocal_scale(__u32 val, __u32 n)
+{
+	return (__u32)(((__u64)val * n) >> 32);
+}
+
+/* layout of qdisc skb cb (from sch_generic.h) */
+struct qdisc_skb_cb {
+	struct {
+		unsigned int	pkt_len;
+		__u16		dev_queue_mapping;
+		__u16		tc_classid;
+	};
+#define QDISC_CB_PRIV_LEN 20
+	unsigned char		data[QDISC_CB_PRIV_LEN];
+};
+
+/*
+ * When this BPF program is run by tc from the filter classifier,
+ * it is able to read skb metadata and packet data.
+ *
+ * For packets where RSS is not possible, then just return TC_ACT_OK.
+ * When RSS is desired, change the skb->queue_mapping and set TC_ACT_PIPE
+ * to continue processing.
+ *
+ * This should be BPF_PROG_TYPE_SCHED_ACT so section needs to be "action"
+ */
+SEC("action") int
+rss_flow_action(struct __sk_buff *skb)
+{
+	const struct rss_key *rsskey;
+	__u16 classid;
+	__u32 hash;
+
+	/* TC layer puts the BPF_CLASSID into the skb cb area */
+	classid = ((const struct qdisc_skb_cb *)skb->cb)->tc_classid;
+
+	/* Lookup RSS configuration for that BPF class */
+	rsskey = bpf_map_lookup_elem(&rss_map, &classid);
+	if (rsskey == NULL) {
+		bpf_printk("hash(): rss not configured");
+		return TC_ACT_OK;
+	}
+
+	hash = calculate_rss_hash(skb, rsskey);
+	bpf_printk("hash %u\n", hash);
+	if (hash) {
+		/* Fold hash to the number of queues configured */
+		skb->queue_mapping = reciprocal_scale(hash, rsskey->nb_queues);
+		bpf_printk("queue %u\n", skb->queue_mapping);
+		return TC_ACT_PIPE;
+	}
+	return TC_ACT_OK;
+}
+
+char _license[] SEC("license") = "Dual BSD/GPL";
-- 
2.43.0


^ permalink raw reply	[relevance 2%]

* Re: [v7 1/1] net/af_xdp: fix multi interface support for K8s
  2024-01-11 14:21  0%           ` Ferruh Yigit
@ 2024-02-07 23:24  0%             ` Ferruh Yigit
  2024-02-09 12:40  0%               ` Loftus, Ciara
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2024-02-07 23:24 UTC (permalink / raw)
  To: Maryam Tahhan, stephen, lihuisong, fengchengwen, liuyonglong,
	david.marchand
  Cc: dev, Ciara Loftus, Shibin Koikkara Reeny, Kevin Traynor, Luca Boccassi

On 1/11/2024 2:21 PM, Ferruh Yigit wrote:
> On 1/11/2024 12:21 PM, Maryam Tahhan wrote:
>> On 11/01/2024 11:35, Ferruh Yigit wrote:
>>> Devarg is user interface, changing it impacts the user.
>>>
>>> Assume that user of '22.11.3' using 'use_cni' dev_arg, it will be broken
>>> when user upgrades DPDK to '22.11.4', which is not expected.
>>>
>>> dev_arg is not API/ABI but as it impacts the user, it is in the gray
>>> area to backport to the LTS release.
>> Fair enough
>>> Current patch doesn't have Fixes tag or stable tag, so it doesn't
>>> request to be backported to LTS release. I took this as an improvement,
>>> more than a fix.
>>
>> This was overlooked by me apologies. It's been a while since I've
>> contributed to DPDK and I must've missed this detail in the contribution
>> guide.
>>> As far as I understand existing code (that use 'use_cni' dev_arg)
>>> supports only single netdev, this patch adds support for multiple netdevs.
>>
>> The use_cni implementation will no longer work with the AF_XDP DP as the
>> use_cni was originally implemented as it has hard coded what's now an
>> incorrect path for the UDS.
>>
>>> So what do you think keep LTS with 'use_cni' dev_arg, is there a
>>> requirement to update LTS release?
>>> If so, can it be an option to keep 'use_cni' for backward compatibility
>>> but add only add 'uds_path' and remove 'use_cni' in next LTS?
>>
>>
>> Yeah we can go back to the version of the patch that had the 'use_cni'
>> flag that was used in combination with the path argument. We can add
>> better documentation re the "use_cni" misnomer... What we can then do is
>> if no path argument is set by the user assume their intent and and
>> generate the path internally in the AF_XDP PMD (which was suggested by
>> Shibin at some stage). That way there should be no surprises to the End
>> User.
>>
> 
> Ack, this keeps backward compatibility,
> 
> BUT if 'use_cni' is already broken in v23.11 (that is what I understand
> from your above comment), means there is no user of it in LTS, and we
> can be more pragmatic and replace the dev_args, by backporting this
> patch, assuming LTS maintainer is also OK with it.
> 

Hi Maryam,

How do you want to continue with the patch, I think options we considered:

1. Fix 'use_cni' documentation (which we can backport to LTS) and
overload the argument for new purpose. This will enable new feature by
keeping backward compatibility. And requires new version of this patch.

2. If the 'use_cni' is completely broken in the 23.11 LTS, which means
there is no user or backward compatibility to worry about, we can merge
this patch and backport it to LTS.

3. Don't backport this fix to LTS, merge only to current release, which
means your new feature won't be available to some users as long as a few
years.


(1.) is most user friendly, but if 'use_cni' already broken in LTS we
can go with option (2.). What do you think?



btw, @Ciara, @Maryam, if (2.) is true, how we end up having a feature
('use_cni' dev_args) completely broken in an LTS release?



> 
>> Long term I would like to keep a (renamed) path argument (in case the
>> path does ever change from the AF_XDP DP POV) and use it also in
>> combination with another (maybe boolean) param for passing pinned bpf
>> maps rather than another separate path.
>>
>> WDYT? Would this work for the LTS release?
>>
>>
> 


^ permalink raw reply	[relevance 0%]

* [PATCH v2 4/7] net/tap: rewrite the RSS BPF program
  @ 2024-02-07 22:11  2%   ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2024-02-07 22:11 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Rewrite the BPF program used to do queue based RSS.
Important changes:
	- uses newer BPF map format BTF
	- accepts key as parameter rather than constant default
	- can do L3 or L4 hashing
	- supports IPv4 options
	- supports IPv6 extension headers
	- restructured for readability

The usage of BPF is different as well:
	- the incoming configuration is looked up based on
	  class parameters rather than patching the BPF.
	- the resulting queue is placed in skb rather
	  than requiring a second pass through classifier step.

Note: This version only works with later patch to enable it on
the DPDK driver side. It is submitted as an incremental patch
to allow for easier review. Bisection still works because
the old instruction are still present for now.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 .gitignore                            |   3 -
 drivers/net/tap/bpf/Makefile          |  19 --
 drivers/net/tap/bpf/README            |  12 ++
 drivers/net/tap/bpf/bpf_api.h         | 276 --------------------------
 drivers/net/tap/bpf/bpf_elf.h         |  53 -----
 drivers/net/tap/bpf/bpf_extract.py    |  85 --------
 drivers/net/tap/bpf/meson.build       |  81 ++++++++
 drivers/net/tap/bpf/tap_bpf_program.c | 255 ------------------------
 drivers/net/tap/bpf/tap_rss.c         | 272 +++++++++++++++++++++++++
 9 files changed, 365 insertions(+), 691 deletions(-)
 delete mode 100644 drivers/net/tap/bpf/Makefile
 create mode 100644 drivers/net/tap/bpf/README
 delete mode 100644 drivers/net/tap/bpf/bpf_api.h
 delete mode 100644 drivers/net/tap/bpf/bpf_elf.h
 delete mode 100644 drivers/net/tap/bpf/bpf_extract.py
 create mode 100644 drivers/net/tap/bpf/meson.build
 delete mode 100644 drivers/net/tap/bpf/tap_bpf_program.c
 create mode 100644 drivers/net/tap/bpf/tap_rss.c

diff --git a/.gitignore b/.gitignore
index 3f444dcace2e..01a47a760660 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,9 +36,6 @@ TAGS
 # ignore python bytecode files
 *.pyc
 
-# ignore BPF programs
-drivers/net/tap/bpf/tap_bpf_program.o
-
 # DTS results
 dts/output
 
diff --git a/drivers/net/tap/bpf/Makefile b/drivers/net/tap/bpf/Makefile
deleted file mode 100644
index 9efeeb1bc704..000000000000
--- a/drivers/net/tap/bpf/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# This file is not built as part of normal DPDK build.
-# It is used to generate the eBPF code for TAP RSS.
-
-CLANG=clang
-CLANG_OPTS=-O2
-TARGET=../tap_bpf_insns.h
-
-all: $(TARGET)
-
-clean:
-	rm tap_bpf_program.o $(TARGET)
-
-tap_bpf_program.o: tap_bpf_program.c
-	$(CLANG) $(CLANG_OPTS) -emit-llvm -c $< -o - | \
-	llc -march=bpf -filetype=obj -o $@
-
-$(TARGET): tap_bpf_program.o
-	python3 bpf_extract.py -stap_bpf_program.c -o $@ $<
diff --git a/drivers/net/tap/bpf/README b/drivers/net/tap/bpf/README
new file mode 100644
index 000000000000..960a10da73b8
--- /dev/null
+++ b/drivers/net/tap/bpf/README
@@ -0,0 +1,12 @@
+This is the BPF program used to implement the RSS across queues
+flow action. It works like the skbedit tc filter but instead of mapping
+to only one queues, it maps to multiple queues based on RSS hash.
+
+This version is built the BPF Compile Once — Run Everywhere (CO-RE)
+framework and uses libbpf and bpftool.
+
+Limitations
+- requires libbpf version XX or later
+- rebuilding the BPF requires clang and bpftool
+- only Toeplitz hash with standard 40 byte key is supported
+- the number of queues per RSS action is limited to 16
diff --git a/drivers/net/tap/bpf/bpf_api.h b/drivers/net/tap/bpf/bpf_api.h
deleted file mode 100644
index 2638a8a4ac9a..000000000000
--- a/drivers/net/tap/bpf/bpf_api.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-
-#ifndef __BPF_API__
-#define __BPF_API__
-
-/* Note:
- *
- * This file can be included into eBPF kernel programs. It contains
- * a couple of useful helper functions, map/section ABI (bpf_elf.h),
- * misc macros and some eBPF specific LLVM built-ins.
- */
-
-#include <stdint.h>
-
-#include <linux/pkt_cls.h>
-#include <linux/bpf.h>
-#include <linux/filter.h>
-
-#include <asm/byteorder.h>
-
-#include "bpf_elf.h"
-
-/** libbpf pin type. */
-enum libbpf_pin_type {
-	LIBBPF_PIN_NONE,
-	/* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */
-	LIBBPF_PIN_BY_NAME,
-};
-
-/** Type helper macros. */
-
-#define __uint(name, val) int (*name)[val]
-#define __type(name, val) typeof(val) *name
-#define __array(name, val) typeof(val) *name[]
-
-/** Misc macros. */
-
-#ifndef __stringify
-# define __stringify(X)		#X
-#endif
-
-#ifndef __maybe_unused
-# define __maybe_unused		__attribute__((__unused__))
-#endif
-
-#ifndef offsetof
-# define offsetof(TYPE, MEMBER)	__builtin_offsetof(TYPE, MEMBER)
-#endif
-
-#ifndef likely
-# define likely(X)		__builtin_expect(!!(X), 1)
-#endif
-
-#ifndef unlikely
-# define unlikely(X)		__builtin_expect(!!(X), 0)
-#endif
-
-#ifndef htons
-# define htons(X)		__constant_htons((X))
-#endif
-
-#ifndef ntohs
-# define ntohs(X)		__constant_ntohs((X))
-#endif
-
-#ifndef htonl
-# define htonl(X)		__constant_htonl((X))
-#endif
-
-#ifndef ntohl
-# define ntohl(X)		__constant_ntohl((X))
-#endif
-
-#ifndef __inline__
-# define __inline__		__attribute__((always_inline))
-#endif
-
-/** Section helper macros. */
-
-#ifndef __section
-# define __section(NAME)						\
-	__attribute__((section(NAME), used))
-#endif
-
-#ifndef __section_tail
-# define __section_tail(ID, KEY)					\
-	__section(__stringify(ID) "/" __stringify(KEY))
-#endif
-
-#ifndef __section_xdp_entry
-# define __section_xdp_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_cls_entry
-# define __section_cls_entry						\
-	__section(ELF_SECTION_CLASSIFIER)
-#endif
-
-#ifndef __section_act_entry
-# define __section_act_entry						\
-	__section(ELF_SECTION_ACTION)
-#endif
-
-#ifndef __section_lwt_entry
-# define __section_lwt_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_license
-# define __section_license						\
-	__section(ELF_SECTION_LICENSE)
-#endif
-
-#ifndef __section_maps
-# define __section_maps							\
-	__section(ELF_SECTION_MAPS)
-#endif
-
-/** Declaration helper macros. */
-
-#ifndef BPF_LICENSE
-# define BPF_LICENSE(NAME)						\
-	char ____license[] __section_license = NAME
-#endif
-
-/** Classifier helper */
-
-#ifndef BPF_H_DEFAULT
-# define BPF_H_DEFAULT	-1
-#endif
-
-/** BPF helper functions for tc. Individual flags are in linux/bpf.h */
-
-#ifndef __BPF_FUNC
-# define __BPF_FUNC(NAME, ...)						\
-	(* NAME)(__VA_ARGS__) __maybe_unused
-#endif
-
-#ifndef BPF_FUNC
-# define BPF_FUNC(NAME, ...)						\
-	__BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME
-#endif
-
-/* Map access/manipulation */
-static void *BPF_FUNC(map_lookup_elem, void *map, const void *key);
-static int BPF_FUNC(map_update_elem, void *map, const void *key,
-		    const void *value, uint32_t flags);
-static int BPF_FUNC(map_delete_elem, void *map, const void *key);
-
-/* Time access */
-static uint64_t BPF_FUNC(ktime_get_ns);
-
-/* Debugging */
-
-/* FIXME: __attribute__ ((format(printf, 1, 3))) not possible unless
- * llvm bug https://llvm.org/bugs/show_bug.cgi?id=26243 gets resolved.
- * It would require ____fmt to be made const, which generates a reloc
- * entry (non-map).
- */
-static void BPF_FUNC(trace_printk, const char *fmt, int fmt_size, ...);
-
-#ifndef printt
-# define printt(fmt, ...)						\
-	({								\
-		char ____fmt[] = fmt;					\
-		trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__);	\
-	})
-#endif
-
-/* Random numbers */
-static uint32_t BPF_FUNC(get_prandom_u32);
-
-/* Tail calls */
-static void BPF_FUNC(tail_call, struct __sk_buff *skb, void *map,
-		     uint32_t index);
-
-/* System helpers */
-static uint32_t BPF_FUNC(get_smp_processor_id);
-static uint32_t BPF_FUNC(get_numa_node_id);
-
-/* Packet misc meta data */
-static uint32_t BPF_FUNC(get_cgroup_classid, struct __sk_buff *skb);
-static int BPF_FUNC(skb_under_cgroup, void *map, uint32_t index);
-
-static uint32_t BPF_FUNC(get_route_realm, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(get_hash_recalc, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(set_hash_invalid, struct __sk_buff *skb);
-
-/* Packet redirection */
-static int BPF_FUNC(redirect, int ifindex, uint32_t flags);
-static int BPF_FUNC(clone_redirect, struct __sk_buff *skb, int ifindex,
-		    uint32_t flags);
-
-/* Packet manipulation */
-static int BPF_FUNC(skb_load_bytes, struct __sk_buff *skb, uint32_t off,
-		    void *to, uint32_t len);
-static int BPF_FUNC(skb_store_bytes, struct __sk_buff *skb, uint32_t off,
-		    const void *from, uint32_t len, uint32_t flags);
-
-static int BPF_FUNC(l3_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(l4_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(csum_diff, const void *from, uint32_t from_size,
-		    const void *to, uint32_t to_size, uint32_t seed);
-static int BPF_FUNC(csum_update, struct __sk_buff *skb, uint32_t wsum);
-
-static int BPF_FUNC(skb_change_type, struct __sk_buff *skb, uint32_t type);
-static int BPF_FUNC(skb_change_proto, struct __sk_buff *skb, uint32_t proto,
-		    uint32_t flags);
-static int BPF_FUNC(skb_change_tail, struct __sk_buff *skb, uint32_t nlen,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_pull_data, struct __sk_buff *skb, uint32_t len);
-
-/* Event notification */
-static int __BPF_FUNC(skb_event_output, struct __sk_buff *skb, void *map,
-		      uint64_t index, const void *data, uint32_t size) =
-		      (void *) BPF_FUNC_perf_event_output;
-
-/* Packet vlan encap/decap */
-static int BPF_FUNC(skb_vlan_push, struct __sk_buff *skb, uint16_t proto,
-		    uint16_t vlan_tci);
-static int BPF_FUNC(skb_vlan_pop, struct __sk_buff *skb);
-
-/* Packet tunnel encap/decap */
-static int BPF_FUNC(skb_get_tunnel_key, struct __sk_buff *skb,
-		    struct bpf_tunnel_key *to, uint32_t size, uint32_t flags);
-static int BPF_FUNC(skb_set_tunnel_key, struct __sk_buff *skb,
-		    const struct bpf_tunnel_key *from, uint32_t size,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_get_tunnel_opt, struct __sk_buff *skb,
-		    void *to, uint32_t size);
-static int BPF_FUNC(skb_set_tunnel_opt, struct __sk_buff *skb,
-		    const void *from, uint32_t size);
-
-/** LLVM built-ins, mem*() routines work for constant size */
-
-#ifndef lock_xadd
-# define lock_xadd(ptr, val)	((void) __sync_fetch_and_add(ptr, val))
-#endif
-
-#ifndef memset
-# define memset(s, c, n)	__builtin_memset((s), (c), (n))
-#endif
-
-#ifndef memcpy
-# define memcpy(d, s, n)	__builtin_memcpy((d), (s), (n))
-#endif
-
-#ifndef memmove
-# define memmove(d, s, n)	__builtin_memmove((d), (s), (n))
-#endif
-
-/* FIXME: __builtin_memcmp() is not yet fully usable unless llvm bug
- * https://llvm.org/bugs/show_bug.cgi?id=26218 gets resolved. Also
- * this one would generate a reloc entry (non-map), otherwise.
- */
-#if 0
-#ifndef memcmp
-# define memcmp(a, b, n)	__builtin_memcmp((a), (b), (n))
-#endif
-#endif
-
-unsigned long long load_byte(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.byte");
-
-unsigned long long load_half(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.half");
-
-unsigned long long load_word(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.word");
-
-#endif /* __BPF_API__ */
diff --git a/drivers/net/tap/bpf/bpf_elf.h b/drivers/net/tap/bpf/bpf_elf.h
deleted file mode 100644
index ea8a11c95c0f..000000000000
--- a/drivers/net/tap/bpf/bpf_elf.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-#ifndef __BPF_ELF__
-#define __BPF_ELF__
-
-#include <asm/types.h>
-
-/* Note:
- *
- * Below ELF section names and bpf_elf_map structure definition
- * are not (!) kernel ABI. It's rather a "contract" between the
- * application and the BPF loader in tc. For compatibility, the
- * section names should stay as-is. Introduction of aliases, if
- * needed, are a possibility, though.
- */
-
-/* ELF section names, etc */
-#define ELF_SECTION_LICENSE	"license"
-#define ELF_SECTION_MAPS	"maps"
-#define ELF_SECTION_PROG	"prog"
-#define ELF_SECTION_CLASSIFIER	"classifier"
-#define ELF_SECTION_ACTION	"action"
-
-#define ELF_MAX_MAPS		64
-#define ELF_MAX_LICENSE_LEN	128
-
-/* Object pinning settings */
-#define PIN_NONE		0
-#define PIN_OBJECT_NS		1
-#define PIN_GLOBAL_NS		2
-
-/* ELF map definition */
-struct bpf_elf_map {
-	__u32 type;
-	__u32 size_key;
-	__u32 size_value;
-	__u32 max_elem;
-	__u32 flags;
-	__u32 id;
-	__u32 pinning;
-	__u32 inner_id;
-	__u32 inner_idx;
-};
-
-#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val)		\
-	struct ____btf_map_##name {				\
-		type_key key;					\
-		type_val value;					\
-	};							\
-	struct ____btf_map_##name				\
-	    __attribute__ ((section(".maps." #name), used))	\
-	    ____btf_map_##name = { }
-
-#endif /* __BPF_ELF__ */
diff --git a/drivers/net/tap/bpf/bpf_extract.py b/drivers/net/tap/bpf/bpf_extract.py
deleted file mode 100644
index 73c4dafe4eca..000000000000
--- a/drivers/net/tap/bpf/bpf_extract.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright (c) 2023 Stephen Hemminger <stephen@networkplumber.org>
-
-import argparse
-import sys
-import struct
-from tempfile import TemporaryFile
-from elftools.elf.elffile import ELFFile
-
-
-def load_sections(elffile):
-    """Get sections of interest from ELF"""
-    result = []
-    parts = [("cls_q", "cls_q_insns"), ("l3_l4", "l3_l4_hash_insns")]
-    for name, tag in parts:
-        section = elffile.get_section_by_name(name)
-        if section:
-            insns = struct.iter_unpack('<BBhL', section.data())
-            result.append([tag, insns])
-    return result
-
-
-def dump_section(name, insns, out):
-    """Dump the array of BPF instructions"""
-    print(f'\nstatic struct bpf_insn {name}[] = {{', file=out)
-    for bpf in insns:
-        code = bpf[0]
-        src = bpf[1] >> 4
-        dst = bpf[1] & 0xf
-        off = bpf[2]
-        imm = bpf[3]
-        print(f'\t{{{code:#04x}, {dst:4d}, {src:4d}, {off:8d}, {imm:#010x}}},',
-              file=out)
-    print('};', file=out)
-
-
-def parse_args():
-    """Parse command line arguments"""
-    parser = argparse.ArgumentParser()
-    parser.add_argument('-s',
-                        '--source',
-                        type=str,
-                        help="original source file")
-    parser.add_argument('-o', '--out', type=str, help="output C file path")
-    parser.add_argument("file",
-                        nargs='+',
-                        help="object file path or '-' for stdin")
-    return parser.parse_args()
-
-
-def open_input(path):
-    """Open the file or stdin"""
-    if path == "-":
-        temp = TemporaryFile()
-        temp.write(sys.stdin.buffer.read())
-        return temp
-    return open(path, 'rb')
-
-
-def write_header(out, source):
-    """Write file intro header"""
-    print("/* SPDX-License-Identifier: BSD-3-Clause", file=out)
-    if source:
-        print(f' * Auto-generated from {source}', file=out)
-    print(" * This not the original source file. Do NOT edit it.", file=out)
-    print(" */\n", file=out)
-
-
-def main():
-    '''program main function'''
-    args = parse_args()
-
-    with open(args.out, 'w',
-              encoding="utf-8") if args.out else sys.stdout as out:
-        write_header(out, args.source)
-        for path in args.file:
-            elffile = ELFFile(open_input(path))
-            sections = load_sections(elffile)
-            for name, insns in sections:
-                dump_section(name, insns, out)
-
-
-if __name__ == "__main__":
-    main()
diff --git a/drivers/net/tap/bpf/meson.build b/drivers/net/tap/bpf/meson.build
new file mode 100644
index 000000000000..f2c03a19fd4d
--- /dev/null
+++ b/drivers/net/tap/bpf/meson.build
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2024 Stephen Hemminger <stephen@networkplumber.org>
+
+enable_tap_rss = false
+
+libbpf = dependency('libbpf', required: false, method: 'pkg-config')
+if not libbpf.found()
+    message('net/tap: no RSS support missing libbpf')
+    subdir_done()
+endif
+
+# Debian install this in /usr/sbin which is not in $PATH
+bpftool = find_program('bpftool', '/usr/sbin/bpftool', required: false, version: '>= 5.6.0')
+if not bpftool.found()
+    message('net/tap: no RSS support missing bpftool')
+    subdir_done()
+endif
+
+clang_supports_bpf = false
+clang = find_program('clang', required: false)
+if clang.found()
+    clang_supports_bpf = run_command(clang, '-target', 'bpf', '--print-supported-cpus',
+                                     check: false).returncode() == 0
+endif
+
+if not clang_supports_bpf
+    message('net/tap: no RSS support missing clang BPF')
+    subdir_done()
+endif
+
+enable_tap_rss = true
+
+libbpf_include_dir = libbpf.get_variable(pkgconfig : 'includedir')
+
+# The include files <linux/bpf.h> and others include <asm/types.h>
+# but <asm/types.h> is not defined for multi-lib environment target.
+# Workaround by using include directoriy from the host build environment.
+machine_name = run_command('uname', '-m').stdout().strip()
+march_include_dir = '/usr/include/' + machine_name + '-linux-gnu'
+
+clang_flags = [
+    '-O2',
+    '-Wall',
+    '-Wextra',
+    '-target',
+    'bpf',
+    '-g',
+    '-c',
+]
+
+bpf_o_cmd = [
+    clang,
+    clang_flags,
+    '-idirafter',
+    libbpf_include_dir,
+    '-idirafter',
+    march_include_dir,
+    '@INPUT@',
+    '-o',
+    '@OUTPUT@'
+]
+
+skel_h_cmd = [
+    bpftool,
+    'gen',
+    'skeleton',
+    '@INPUT@'
+]
+
+tap_rss_o = custom_target(
+    'tap_rss.bpf.o',
+    input: 'tap_rss.c',
+    output: 'tap_rss.o',
+    command: bpf_o_cmd)
+
+tap_rss_skel_h = custom_target(
+    'tap_rss.skel.h',
+    input: tap_rss_o,
+    output: 'tap_rss.skel.h',
+    command: skel_h_cmd,
+    capture: true)
diff --git a/drivers/net/tap/bpf/tap_bpf_program.c b/drivers/net/tap/bpf/tap_bpf_program.c
deleted file mode 100644
index f05aed021c30..000000000000
--- a/drivers/net/tap/bpf/tap_bpf_program.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
- * Copyright 2017 Mellanox Technologies, Ltd
- */
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <asm/types.h>
-#include <linux/in.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/if_tunnel.h>
-#include <linux/filter.h>
-
-#include "bpf_api.h"
-#include "bpf_elf.h"
-#include "../tap_rss.h"
-
-/** Create IPv4 address */
-#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
-		(((b) & 0xff) << 16) | \
-		(((c) & 0xff) << 8)  | \
-		((d) & 0xff))
-
-#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
-		((b) & 0xff))
-
-/*
- * The queue number is offset by a unique QUEUE_OFFSET, to distinguish
- * packets that have gone through this rule (skb->cb[1] != 0) from others.
- */
-#define QUEUE_OFFSET		0x7cafe800
-#define PIN_GLOBAL_NS		2
-
-#define KEY_IDX			0
-#define BPF_MAP_ID_KEY	1
-
-struct vlan_hdr {
-	__be16 proto;
-	__be16 tci;
-};
-
-struct bpf_elf_map __attribute__((section("maps"), used))
-map_keys = {
-	.type           =       BPF_MAP_TYPE_HASH,
-	.id             =       BPF_MAP_ID_KEY,
-	.size_key       =       sizeof(__u32),
-	.size_value     =       sizeof(struct rss_key),
-	.max_elem       =       256,
-	.pinning        =       PIN_GLOBAL_NS,
-};
-
-__section("cls_q") int
-match_q(struct __sk_buff *skb)
-{
-	__u32 queue = skb->cb[1];
-	/* queue is set by tap_flow_bpf_cls_q() before load */
-	volatile __u32 q = 0xdeadbeef;
-	__u32 match_queue = QUEUE_OFFSET + q;
-
-	/* printt("match_q$i() queue = %d\n", queue); */
-
-	if (queue != match_queue)
-		return TC_ACT_OK;
-
-	/* queue match */
-	skb->cb[1] = 0;
-	return TC_ACT_UNSPEC;
-}
-
-
-struct ipv4_l3_l4_tuple {
-	__u32    src_addr;
-	__u32    dst_addr;
-	__u16    dport;
-	__u16    sport;
-} __attribute__((packed));
-
-struct ipv6_l3_l4_tuple {
-	__u8        src_addr[16];
-	__u8        dst_addr[16];
-	__u16       dport;
-	__u16       sport;
-} __attribute__((packed));
-
-static const __u8 def_rss_key[TAP_RSS_HASH_KEY_SIZE] = {
-	0xd1, 0x81, 0xc6, 0x2c,
-	0xf7, 0xf4, 0xdb, 0x5b,
-	0x19, 0x83, 0xa2, 0xfc,
-	0x94, 0x3e, 0x1a, 0xdb,
-	0xd9, 0x38, 0x9e, 0x6b,
-	0xd1, 0x03, 0x9c, 0x2c,
-	0xa7, 0x44, 0x99, 0xad,
-	0x59, 0x3d, 0x56, 0xd9,
-	0xf3, 0x25, 0x3c, 0x06,
-	0x2a, 0xdc, 0x1f, 0xfc,
-};
-
-static __u32  __attribute__((always_inline))
-rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
-		__u8 input_len)
-{
-	__u32 i, j, hash = 0;
-#pragma unroll
-	for (j = 0; j < input_len; j++) {
-#pragma unroll
-		for (i = 0; i < 32; i++) {
-			if (input_tuple[j] & (1U << (31 - i))) {
-				hash ^= ((const __u32 *)def_rss_key)[j] << i |
-				(__u32)((uint64_t)
-				(((const __u32 *)def_rss_key)[j + 1])
-					>> (32 - i));
-			}
-		}
-	}
-	return hash;
-}
-
-static int __attribute__((always_inline))
-rss_l3_l4(struct __sk_buff *skb)
-{
-	void *data_end = (void *)(long)skb->data_end;
-	void *data = (void *)(long)skb->data;
-	__u16 proto = (__u16)skb->protocol;
-	__u32 key_idx = 0xdeadbeef;
-	__u32 hash;
-	struct rss_key *rsskey;
-	__u64 off = ETH_HLEN;
-	int j;
-	__u8 *key = 0;
-	__u32 len;
-	__u32 queue = 0;
-	bool mf = 0;
-	__u16 frag_off = 0;
-
-	rsskey = map_lookup_elem(&map_keys, &key_idx);
-	if (!rsskey) {
-		printt("hash(): rss key is not configured\n");
-		return TC_ACT_OK;
-	}
-	key = (__u8 *)rsskey->key;
-
-	/* Get correct proto for 802.1ad */
-	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
-		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
-		    sizeof(proto) > data_end)
-			return TC_ACT_OK;
-		proto = *(__u16 *)(data + ETH_ALEN * 2 +
-				   sizeof(struct vlan_hdr));
-		off += sizeof(struct vlan_hdr);
-	}
-
-	if (proto == htons(ETH_P_IP)) {
-		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
-			> data_end)
-			return TC_ACT_OK;
-
-		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
-		__u8 *frag_off_addr = data + off + offsetof(struct iphdr, frag_off);
-		__u8 *prot_addr = data + off + offsetof(struct iphdr, protocol);
-		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
-		struct ipv4_l3_l4_tuple v4_tuple = {
-			.src_addr = IPv4(*(src_dst_addr + 0),
-					*(src_dst_addr + 1),
-					*(src_dst_addr + 2),
-					*(src_dst_addr + 3)),
-			.dst_addr = IPv4(*(src_dst_addr + 4),
-					*(src_dst_addr + 5),
-					*(src_dst_addr + 6),
-					*(src_dst_addr + 7)),
-			.sport = 0,
-			.dport = 0,
-		};
-		/** Fetch the L4-payer port numbers only in-case of TCP/UDP
-		 ** and also if the packet is not fragmented. Since fragmented
-		 ** chunks do not have L4 TCP/UDP header.
-		 **/
-		if (*prot_addr == IPPROTO_UDP || *prot_addr == IPPROTO_TCP) {
-			frag_off = PORT(*(frag_off_addr + 0),
-					*(frag_off_addr + 1));
-			mf = frag_off & 0x2000;
-			frag_off = frag_off & 0x1fff;
-			if (mf == 0 && frag_off == 0) {
-				v4_tuple.sport = PORT(*(src_dst_port + 0),
-						*(src_dst_port + 1));
-				v4_tuple.dport = PORT(*(src_dst_port + 2),
-						*(src_dst_port + 3));
-			}
-		}
-		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
-	} else if (proto == htons(ETH_P_IPV6)) {
-		if (data + off + sizeof(struct ipv6hdr) +
-					sizeof(__u32) > data_end)
-			return TC_ACT_OK;
-		__u8 *src_dst_addr = data + off +
-					offsetof(struct ipv6hdr, saddr);
-		__u8 *src_dst_port = data + off +
-					sizeof(struct ipv6hdr);
-		__u8 *next_hdr = data + off +
-					offsetof(struct ipv6hdr, nexthdr);
-
-		struct ipv6_l3_l4_tuple v6_tuple;
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.src_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + j));
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.dst_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + 4 + j));
-
-		/** Fetch the L4 header port-numbers only if next-header
-		 * is TCP/UDP **/
-		if (*next_hdr == IPPROTO_UDP || *next_hdr == IPPROTO_TCP) {
-			v6_tuple.sport = PORT(*(src_dst_port + 0),
-				      *(src_dst_port + 1));
-			v6_tuple.dport = PORT(*(src_dst_port + 2),
-				      *(src_dst_port + 3));
-		} else {
-			v6_tuple.sport = 0;
-			v6_tuple.dport = 0;
-		}
-
-		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
-	} else {
-		return TC_ACT_PIPE;
-	}
-
-	queue = rsskey->queues[(hash % rsskey->nb_queues) &
-				       (TAP_MAX_QUEUES - 1)];
-	skb->cb[1] = QUEUE_OFFSET + queue;
-	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
-
-	return TC_ACT_RECLASSIFY;
-}
-
-#define RSS(L)						\
-	__section(#L) int				\
-		L ## _hash(struct __sk_buff *skb)	\
-	{						\
-		return rss_ ## L (skb);			\
-	}
-
-RSS(l3_l4)
-
-BPF_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/tap/bpf/tap_rss.c b/drivers/net/tap/bpf/tap_rss.c
new file mode 100644
index 000000000000..1abd18cb606e
--- /dev/null
+++ b/drivers/net/tap/bpf/tap_rss.c
@@ -0,0 +1,272 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+ * Copyright 2017 Mellanox Technologies, Ltd
+ */
+
+#include <linux/in.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/pkt_cls.h>
+#include <linux/bpf.h>
+
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+
+#include "../tap_rss.h"
+
+/*
+ * This map provides configuration information about flows
+ * which need BPF RSS.
+ *
+ * The hash is indexed by the tc_index.
+ */
+struct {
+	__uint(type, BPF_MAP_TYPE_HASH);
+	__uint(key_size, sizeof(__u16));
+	__uint(value_size, sizeof(struct rss_key));
+	__uint(max_entries, TAP_MAX_QUEUES);
+} rss_map SEC(".maps");
+
+
+#define IP_MF		0x2000		/** IP header Flags **/
+#define IP_OFFSET	0x1FFF		/** IP header fragment offset **/
+
+/*
+ * Compute Toeplitz hash over the input tuple.
+ * This is same as rte_softrss_be in lib/hash
+ * but loop needs to be setup to match BPF restrictions.
+ */
+static __u32 __attribute__((always_inline))
+softrss_be(const __u32 *input_tuple, __u32 input_len, const __u32 *key)
+{
+	__u32 i, j, hash = 0;
+
+#pragma unroll
+	for (j = 0; j < input_len; j++) {
+#pragma unroll
+		for (i = 0; i < 32; i++) {
+			if (input_tuple[j] & (1U << (31 - i)))
+				hash ^= key[j] << i | key[j + 1] >> (32 - i);
+		}
+	}
+	return hash;
+}
+
+/* Compute RSS hash for IPv4 packet.
+ * return in 0 if RSS not specified
+ */
+static __u32 __attribute__((always_inline))
+parse_ipv4(const struct __sk_buff *skb, __u32 hash_type, const __u32 *key)
+{
+	struct iphdr iph;
+	__u32 off = 0;
+
+	if (bpf_skb_load_bytes_relative(skb, off, &iph, sizeof(iph), BPF_HDR_START_NET))
+		return 0;	/* no IP header present */
+
+	struct {
+		__u32    src_addr;
+		__u32    dst_addr;
+		__u16    dport;
+		__u16    sport;
+	} v4_tuple = {
+		.src_addr = bpf_ntohl(iph.saddr),
+		.dst_addr = bpf_ntohl(iph.daddr),
+	};
+
+	/* If only calculating L3 hash, do it now */
+	if (hash_type & (1 << HASH_FIELD_IPV4_L3))
+		return softrss_be((__u32 *)&v4_tuple, sizeof(v4_tuple) / sizeof(__u32) - 1, key);
+
+	/* No L4 if packet is a fragmented */
+	if ((iph.frag_off & bpf_htons(IP_MF | IP_OFFSET)) != 0)
+		return 0;
+
+	/* Do RSS on UDP or TCP ports */
+	if (iph.protocol == IPPROTO_UDP || iph.protocol == IPPROTO_TCP) {
+		__u16 src_dst_port[2];
+
+		off += iph.ihl * 4;
+		if (bpf_skb_load_bytes_relative(skb, off, &src_dst_port, sizeof(src_dst_port),
+						BPF_HDR_START_NET))
+			return 0; /* TCP or UDP header missing */
+
+		v4_tuple.sport = bpf_ntohs(src_dst_port[0]);
+		v4_tuple.dport = bpf_ntohs(src_dst_port[1]);
+		return softrss_be((__u32 *)&v4_tuple, sizeof(v4_tuple) / sizeof(__u32), key);
+	}
+
+	/* Other protocol */
+	return 0;
+}
+
+/* parse ipv6 extended headers, update offset and return next proto.
+ * returns next proto on success, -1 on malformed header
+ */
+static int __attribute__((always_inline))
+skip_ip6_ext(__u16 proto, const struct __sk_buff *skb, __u32 *off, int *frag)
+{
+	struct ext_hdr {
+		__u8 next_hdr;
+		__u8 len;
+	} xh;
+	unsigned int i;
+
+	*frag = 0;
+
+#define MAX_EXT_HDRS 5
+#pragma unroll
+	for (i = 0; i < MAX_EXT_HDRS; i++) {
+		switch (proto) {
+		case IPPROTO_HOPOPTS:
+		case IPPROTO_ROUTING:
+		case IPPROTO_DSTOPTS:
+			if (bpf_skb_load_bytes_relative(skb, *off, &xh, sizeof(xh),
+							BPF_HDR_START_NET))
+				return -1;
+
+			*off += (xh.len + 1) * 8;
+			proto = xh.next_hdr;
+			break;
+		case IPPROTO_FRAGMENT:
+			if (bpf_skb_load_bytes_relative(skb, *off, &xh, sizeof(xh),
+							BPF_HDR_START_NET))
+				return -1;
+
+			*off += 8;
+			proto = xh.next_hdr;
+			*frag = 1;
+			return proto; /* this is always the last ext hdr */
+		default:
+			return proto;
+		}
+	}
+
+	/* too many extension headers give up */
+	return -1;
+}
+
+static __u32 __attribute__((always_inline))
+parse_ipv6(const struct __sk_buff *skb, __u32 hash_type, const __u32 *key)
+{
+	struct {
+		__u32       src_addr[4];
+		__u32       dst_addr[4];
+		__u16       dport;
+		__u16       sport;
+	} v6_tuple = { };
+	struct ipv6hdr ip6h;
+	__u32 off = 0, j;
+	int proto, frag;
+
+	if (bpf_skb_load_bytes_relative(skb, off, &ip6h, sizeof(ip6h), BPF_HDR_START_NET))
+		return 0;
+
+#pragma unroll
+	for (j = 0; j < 4; j++) {
+		v6_tuple.src_addr[j] = bpf_ntohl(ip6h.saddr.in6_u.u6_addr32[j]);
+		v6_tuple.dst_addr[j] = bpf_ntohl(ip6h.daddr.in6_u.u6_addr32[j]);
+	}
+
+	if (hash_type & (1 << HASH_FIELD_IPV6_L3))
+		return softrss_be((__u32 *)&v6_tuple, sizeof(v6_tuple) / sizeof(__u32) - 1, key);
+
+	off += sizeof(ip6h);
+	proto = skip_ip6_ext(ip6h.nexthdr, skb, &off, &frag);
+	if (proto < 0)
+		return 0;
+
+	if (frag)
+		return 0;
+
+	/* Do RSS on UDP or TCP ports */
+	if (proto == IPPROTO_UDP || proto == IPPROTO_TCP) {
+		__u16 src_dst_port[2];
+
+		if (bpf_skb_load_bytes_relative(skb, off, &src_dst_port, sizeof(src_dst_port),
+						BPF_HDR_START_NET))
+			return 0;
+
+		v6_tuple.sport = bpf_ntohs(src_dst_port[0]);
+		v6_tuple.dport = bpf_ntohs(src_dst_port[1]);
+
+		return softrss_be((__u32 *)&v6_tuple, sizeof(v6_tuple) / sizeof(__u32), key);
+	}
+
+	return 0;
+}
+
+/*
+ * Compute RSS hash for packets.
+ * Returns 0 if no hash is possible.
+ */
+static __u32 __attribute__((always_inline))
+calculate_rss_hash(const struct __sk_buff *skb, const struct rss_key *rsskey)
+{
+	const __u32 *key = (const __u32 *)rsskey->key;
+
+	if (skb->protocol == bpf_htons(ETH_P_IP))
+		return parse_ipv4(skb, rsskey->hash_fields, key);
+	else if (skb->protocol == bpf_htons(ETH_P_IPV6))
+		return parse_ipv6(skb, rsskey->hash_fields, key);
+	else
+		return 0;
+}
+
+/* scale value to be into range [0, n), assumes val is large */
+static __u32  __attribute__((always_inline))
+reciprocal_scale(__u32 val, __u32 n)
+{
+	return (__u32)(((__u64)val * n) >> 32);
+}
+
+/* layout of qdisc skb cb (from sch_generic.h) */
+struct qdisc_skb_cb {
+	struct {
+		unsigned int	pkt_len;
+		__u16		dev_queue_mapping;
+		__u16		tc_classid;
+	};
+#define QDISC_CB_PRIV_LEN 20
+	unsigned char		data[QDISC_CB_PRIV_LEN];
+};
+
+/*
+ * When this BPF program is run by tc from the filter classifier,
+ * it is able to read skb metadata and packet data.
+ *
+ * For packets where RSS is not possible, then just return TC_ACT_OK.
+ * When RSS is desired, change the skb->queue_mapping and set TC_ACT_PIPE
+ * to continue processing.
+ *
+ * This should be BPF_PROG_TYPE_SCHED_ACT so section needs to be "action"
+ */
+SEC("action") int
+rss_flow_action(struct __sk_buff *skb)
+{
+	const struct rss_key *rsskey;
+	__u16 classid;
+	__u32 hash;
+
+	/* TC layer puts the BPF_CLASSID into the skb cb area */
+	classid = ((const struct qdisc_skb_cb *)skb->cb)->tc_classid;
+
+	/* Lookup RSS configuration for that BPF class */
+	rsskey = bpf_map_lookup_elem(&rss_map, &classid);
+	if (rsskey == NULL) {
+		bpf_printk("hash(): rss not configured");
+		return TC_ACT_OK;
+	}
+
+	hash = calculate_rss_hash(skb, rsskey);
+	bpf_printk("hash %u\n", hash);
+	if (hash) {
+		/* Fold hash to the number of queues configured */
+		skb->queue_mapping = reciprocal_scale(hash, rsskey->nb_queues);
+		bpf_printk("queue %u\n", skb->queue_mapping);
+		return TC_ACT_PIPE;
+	}
+	return TC_ACT_OK;
+}
+
+char _license[] SEC("license") = "Dual BSD/GPL";
-- 
2.43.0


^ permalink raw reply	[relevance 2%]

* Re: [PATCH v2 1/7] ethdev: support report register names and filter
  2024-02-05 10:51  8%   ` [PATCH v2 1/7] ethdev: support report register names and filter Jie Hai
@ 2024-02-07 17:00  3%     ` Ferruh Yigit
  2024-02-20  8:43  3%       ` Jie Hai
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2024-02-07 17:00 UTC (permalink / raw)
  To: Jie Hai, dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui

On 2/5/2024 10:51 AM, Jie Hai wrote:
> This patch adds "filter" and "names" fields to "rte_dev_reg_info"
> structure. Names of registers in data fields can be reported and
> the registers can be filtered by their names.
> 
> For compatibility, the original API rte_eth_dev_get_reg_info()
> does not use the name and filter fields. The new API
> rte_eth_dev_get_reg_info_ext() is added to support reporting
> names and filtering by names. If the drivers does not report
> the names, set them to "offset_XXX".
> 
> Signed-off-by: Jie Hai <haijie1@huawei.com>
> ---
>  doc/guides/rel_notes/release_24_03.rst |  8 ++++++
>  lib/ethdev/rte_dev_info.h              | 11 ++++++++
>  lib/ethdev/rte_ethdev.c                | 36 ++++++++++++++++++++++++++
>  lib/ethdev/rte_ethdev.h                | 22 ++++++++++++++++
>  4 files changed, 77 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
> index 84d3144215c6..5d402341223a 100644
> --- a/doc/guides/rel_notes/release_24_03.rst
> +++ b/doc/guides/rel_notes/release_24_03.rst
> @@ -75,6 +75,11 @@ New Features
>    * Added support for Atomic Rules' TK242 packet-capture family of devices
>      with PCI IDs: ``0x1024, 0x1025, 0x1026``.
>  
> +* **Added support for dumping regiters with names and filter.**
>

s/regiters/registers/

> +
> +  * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
> +  * the registers by their names and get the information of registers(names,
> +  * values and other attributes).
>  

'*' makes a bullet, but above seems one sentences, if so please only
keep the first '*'.

>  Removed Items
>  -------------
> @@ -124,6 +129,9 @@ ABI Changes
>  
>  * No ABI change that would break compatibility with 23.11.
>  
> +* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
> +  structure for reporting names of regiters and filtering them by names.
> +
>  

This will break the ABI.

Think about a case, an application compiled with an old version of DPDK,
later same application started to use this version without re-compile,
application will send old version of 'struct rte_dev_reg_info', but new
version of DPDK will try to access or update new fields of the 'struct
rte_dev_reg_info'

One option is:
- to add a new 'struct rte_dev_reg_info_ext',
- 'rte_eth_dev_get_reg_info()' still uses old 'struct rte_dev_reg_info'
- 'get_reg()' dev_ops will use this new 'struct rte_dev_reg_info_ext'
- Add deprecation notice to update 'rte_eth_dev_get_reg_info()' to use
new struct in next LTS release


>  Known Issues
>  ------------
> diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
> index 67cf0ae52668..2f4541bd46c8 100644
> --- a/lib/ethdev/rte_dev_info.h
> +++ b/lib/ethdev/rte_dev_info.h
> @@ -11,6 +11,11 @@ extern "C" {
>  
>  #include <stdint.h>
>  
> +#define RTE_ETH_REG_NAME_SIZE 128
> +struct rte_eth_reg_name {
> +	char name[RTE_ETH_REG_NAME_SIZE];
> +};
> +
>  /*
>   * Placeholder for accessing device registers
>   */
> @@ -20,6 +25,12 @@ struct rte_dev_reg_info {
>  	uint32_t length; /**< Number of registers to fetch */
>  	uint32_t width; /**< Size of device register */
>  	uint32_t version; /**< Device version */
> +	/**
> +	 * Filter for target subset of registers.
> +	 * This field could affects register selection for data/length/names.
> +	 */
> +	char *filter;
> +	struct rte_eth_reg_name *names; /**< Registers name saver */
>  };
>  
>  /*
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index f1c658f49e80..3e0294e49092 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -6388,8 +6388,39 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
>  
>  int
>  rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
> +{
> +	struct rte_dev_reg_info reg_info;
> +	int ret;
> +
> +	if (info == NULL) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +			"Cannot get ethdev port %u register info to NULL",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
> +	reg_info.length = info->length;
> +	reg_info.data = info->data;
> +	reg_info.names = NULL;
> +	reg_info.filter = NULL;
> +
> +	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
> +	if (ret != 0)
> +		return ret;
> +
> +	info->length = reg_info.length;
> +	info->width = reg_info.width;
> +	info->version = reg_info.version;
> +	info->offset = reg_info.offset;
> +
> +	return 0;
> +}
> +
> +int
> +rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
>  {
>  	struct rte_eth_dev *dev;
> +	uint32_t i;
>  	int ret;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> @@ -6408,6 +6439,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
>  
>  	rte_ethdev_trace_get_reg_info(port_id, info, ret);
>  
> +	/* Report the default names if drivers not report. */
> +	if (info->names != NULL && strlen(info->names[0].name) == 0)
> +		for (i = 0; i < info->length; i++)
> +			sprintf(info->names[i].name, "offset_%x",
> +				info->offset + i * info->width);
>

Better to use 'snprintf()'

>  	return ret;
>  }
>  
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index 2687c23fa6fb..3abc2ad3f865 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -5053,6 +5053,28 @@ __rte_experimental
>  int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
>  		struct rte_power_monitor_cond *pmc);
>  
> +/**
> + * Retrieve the filtered device registers (values and names) and
> + * register attributes (number of registers and register size)
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param info
> + *   Pointer to rte_dev_reg_info structure to fill in. If info->data is
> + *   NULL, the function fills in the width and length fields. If non-NULL,
> + *   the values of registers whose name contains the filter string are put
> + *   into the buffer pointed at by the data field. Do the same for the names
> + *   of registers if info->names is not NULL.
>

May be good to mention if info->names is not NULL, but driver doesn't
support names, ehtdev fills the names automatically.

As both 'rte_eth_dev_get_reg_info()' & 'rte_eth_dev_get_reg_info_ext()'
use same dev_ops ('get_reg()'), it is possible that driver doesn't
support filtering, so if the user provides info->filter but driver
doesn't support it, I think API should return error, what do you think?

And can you please make it clear above, if filtering is provided with
info->data = NULL, are the returned width and length fields for filtered
number of registers or all registers?


> + * @return
> + *   - (0) if successful.
> + *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-EINVAL) if bad parameter.
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - (-EIO) if device is removed.
> + *   - others depends on the specific operations implementation.
> + */
> +int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
> +
>

Can you please make the new API as experimental. That is the requirement
for new APIs.

Also need to add the API to version.map


>  /**
>   * Retrieve device registers and register attributes (number of registers and
>   * register size)


^ permalink raw reply	[relevance 3%]

* Re: [PATCH v7 0/4] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE
  2024-02-06  2:06  3% ` [PATCH v7 0/4] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Suanming Mou
  2024-02-06  2:06  3%   ` [PATCH v7 1/4] ethdev: rename action modify field data structure Suanming Mou
@ 2024-02-06 21:24  0%   ` Ferruh Yigit
  1 sibling, 0 replies; 200+ results
From: Ferruh Yigit @ 2024-02-06 21:24 UTC (permalink / raw)
  To: Suanming Mou, thomas; +Cc: dev, orika

On 2/6/2024 2:06 AM, Suanming Mou wrote:
> The new item type is added for the case user wants to match traffic
> based on packet field compare result with other fields or immediate
> value.
> 
> e.g. take advantage the compare item user will be able to accumulate
> a IPv4/TCP packet's TCP data_offset and IPv4 IHL field to a tag
> register, then compare the tag register with IPv4 header total length
> to understand the packet has payload or not.
> 
> The supported operations can be as below:
>  - RTE_FLOW_ITEM_COMPARE_EQ (equal)
>  - RTE_FLOW_ITEM_COMPARE_NE (not equal)
>  - RTE_FLOW_ITEM_COMPARE_LT (less than)
>  - RTE_FLOW_ITEM_COMPARE_LE (less than or equal)
>  - RTE_FLOW_ITEM_COMPARE_GT (great than)
>  - RTE_FLOW_ITEM_COMPARE_GE (great than or equal)
> 
> V7:
>  - Moved release notes to API.
>  - Optimize comment descriptions.
> 
> V6:
>  - fix typo and style issue.
>  - adjust flow_field description.
> 
> V5:
>  - rebase on top of next-net
>  - add sample detail for rte_flow_field.
> 
> V4:
>  - rebase on top of the latest version.
>  - move ACTION_MODIFY_PATTERN_SIZE and modify_field_ids rename
>    to first patch.
>  - add comparison flow create sample in testpmd_funcs.rst.
> 
> V3:
>  - fix code style missing empty line in rte_flow.rst.
>  - fix missing the ABI change release notes.
> 
> V2:
>  - Since modify field data struct is experiment, rename modify
>    field data directly instead of adding new flow field struct.
> 
> 
> Suanming Mou (4):
>   ethdev: rename action modify field data structure
>   ethdev: move flow field data structures
>   ethdev: add compare item
>   net/mlx5: add compare item support
>

Series applied to dpdk-next-net/main, thanks.


^ permalink raw reply	[relevance 0%]

* [PATCH v3] ethdev: fast path async flow API
  2024-01-31  9:35  1% ` [PATCH v2] " Dariusz Sosnowski
@ 2024-02-06 17:36  1%   ` Dariusz Sosnowski
  0 siblings, 0 replies; 200+ results
From: Dariusz Sosnowski @ 2024-02-06 17:36 UTC (permalink / raw)
  To: Matan Azrad, Viacheslav Ovsiienko, Ori Kam, Suanming Mou,
	Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
  Cc: dev

This patch reworks the async flow API functions called in data path,
to reduce the overhead during flow operations at the library level.
Main source of the overhead was indirection and checks done while
ethdev library was fetching rte_flow_ops from a given driver.

This patch introduces rte_flow_fp_ops struct which holds callbacks
to driver's implementation of fast path async flow API functions.
Each driver implementing these functions must populate flow_fp_ops
field inside rte_eth_dev structure with a reference to
its own implementation.
By default, ethdev library provides dummy callbacks with
implementations returning ENOSYS.
Such design provides a few assumptions:

- rte_flow_fp_ops struct for given port is always available.
- Each callback is either:
    - Default provided by library.
    - Set up by driver.

As a result, no checks for availability of the implementation
are needed at library level in data path.
Any library-level validation checks in async flow API are compiled
if and only if RTE_FLOW_DEBUG macro is defined.

This design was based on changes in ethdev library introduced in [1].

These changes apply only to the following API functions:

- rte_flow_async_create()
- rte_flow_async_create_by_index()
- rte_flow_async_actions_update()
- rte_flow_async_destroy()
- rte_flow_push()
- rte_flow_pull()
- rte_flow_async_action_handle_create()
- rte_flow_async_action_handle_destroy()
- rte_flow_async_action_handle_update()
- rte_flow_async_action_handle_query()
- rte_flow_async_action_handle_query_update()
- rte_flow_async_action_list_handle_create()
- rte_flow_async_action_list_handle_destroy()
- rte_flow_async_action_list_handle_query_update()

This patch also adjusts the mlx5 PMD to the introduced flow API changes.

[1]
commit c87d435a4d79 ("ethdev: copy fast-path API into separate structure")

Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
v3:
- Documented RTE_FLOW_DEBUG build option.
- Enabled RTE_FLOW_DEBUG automatically on debug builds.
- Fixed pointer checks to compare against NULL explicitly.

v2:
- Fixed mlx5 PMD build issue with older versions of rdma-core.
---
 doc/guides/nics/build_and_test.rst     |   9 +-
 doc/guides/rel_notes/release_24_03.rst |  37 ++
 drivers/net/mlx5/mlx5_flow.c           | 608 +------------------------
 drivers/net/mlx5/mlx5_flow_hw.c        |  25 +
 lib/ethdev/ethdev_driver.c             |   4 +
 lib/ethdev/ethdev_driver.h             |   4 +
 lib/ethdev/meson.build                 |   4 +
 lib/ethdev/rte_flow.c                  | 519 ++++++++++++++++-----
 lib/ethdev/rte_flow_driver.h           | 277 ++++++-----
 lib/ethdev/version.map                 |   2 +
 10 files changed, 647 insertions(+), 842 deletions(-)

diff --git a/doc/guides/nics/build_and_test.rst b/doc/guides/nics/build_and_test.rst
index e8b29c2277..453fa74b39 100644
--- a/doc/guides/nics/build_and_test.rst
+++ b/doc/guides/nics/build_and_test.rst
@@ -36,11 +36,16 @@ The ethdev layer supports below build options for debug purpose:

   Build with debug code on Tx path.

+- ``RTE_FLOW_DEBUG`` (default **disabled**; enabled automatically on debug builds)
+
+  Build with debug code in asynchronous flow APIs.
+
 .. Note::

-   The ethdev library use above options to wrap debug code to trace invalid parameters
+   The ethdev library uses above options to wrap debug code to trace invalid parameters
    on data path APIs, so performance downgrade is expected when enabling those options.
-   Each PMD can decide to reuse them to wrap their own debug code in the Rx/Tx path.
+   Each PMD can decide to reuse them to wrap their own debug code in the Rx/Tx path
+   and in asynchronous flow APIs implementation.

 Running testpmd in Linux
 ------------------------
diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 6f8ad27808..b62330b8b1 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -86,6 +86,43 @@ API Changes

 * gso: ``rte_gso_segment`` now returns -ENOTSUP for unknown protocols.

+* ethdev: PMDs implementing asynchronous flow operations are required to provide relevant functions
+  implementation through ``rte_flow_fp_ops`` struct, instead of ``rte_flow_ops`` struct.
+  Pointer to device-dependent ``rte_flow_fp_ops`` should be provided to ``rte_eth_dev.flow_fp_ops``.
+  This change applies to the following API functions:
+
+   * ``rte_flow_async_create``
+   * ``rte_flow_async_create_by_index``
+   * ``rte_flow_async_actions_update``
+   * ``rte_flow_async_destroy``
+   * ``rte_flow_push``
+   * ``rte_flow_pull``
+   * ``rte_flow_async_action_handle_create``
+   * ``rte_flow_async_action_handle_destroy``
+   * ``rte_flow_async_action_handle_update``
+   * ``rte_flow_async_action_handle_query``
+   * ``rte_flow_async_action_handle_query_update``
+   * ``rte_flow_async_action_list_handle_create``
+   * ``rte_flow_async_action_list_handle_destroy``
+   * ``rte_flow_async_action_list_handle_query_update``
+
+* ethdev: Removed the following fields from ``rte_flow_ops`` struct:
+
+   * ``async_create``
+   * ``async_create_by_index``
+   * ``async_actions_update``
+   * ``async_destroy``
+   * ``push``
+   * ``pull``
+   * ``async_action_handle_create``
+   * ``async_action_handle_destroy``
+   * ``async_action_handle_update``
+   * ``async_action_handle_query``
+   * ``async_action_handle_query_update``
+   * ``async_action_list_handle_create``
+   * ``async_action_list_handle_destroy``
+   * ``async_action_list_handle_query_update``
+

 ABI Changes
 -----------
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 85e8c77c81..0ff3b91596 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -1055,98 +1055,13 @@ mlx5_flow_group_set_miss_actions(struct rte_eth_dev *dev,
 				 const struct rte_flow_group_attr *attr,
 				 const struct rte_flow_action actions[],
 				 struct rte_flow_error *error);
-static struct rte_flow *
-mlx5_flow_async_flow_create(struct rte_eth_dev *dev,
-			    uint32_t queue,
-			    const struct rte_flow_op_attr *attr,
-			    struct rte_flow_template_table *table,
-			    const struct rte_flow_item items[],
-			    uint8_t pattern_template_index,
-			    const struct rte_flow_action actions[],
-			    uint8_t action_template_index,
-			    void *user_data,
-			    struct rte_flow_error *error);
-static struct rte_flow *
-mlx5_flow_async_flow_create_by_index(struct rte_eth_dev *dev,
-			    uint32_t queue,
-			    const struct rte_flow_op_attr *attr,
-			    struct rte_flow_template_table *table,
-			    uint32_t rule_index,
-			    const struct rte_flow_action actions[],
-			    uint8_t action_template_index,
-			    void *user_data,
-			    struct rte_flow_error *error);
-static int
-mlx5_flow_async_flow_update(struct rte_eth_dev *dev,
-			     uint32_t queue,
-			     const struct rte_flow_op_attr *attr,
-			     struct rte_flow *flow,
-			     const struct rte_flow_action actions[],
-			     uint8_t action_template_index,
-			     void *user_data,
-			     struct rte_flow_error *error);
-static int
-mlx5_flow_async_flow_destroy(struct rte_eth_dev *dev,
-			     uint32_t queue,
-			     const struct rte_flow_op_attr *attr,
-			     struct rte_flow *flow,
-			     void *user_data,
-			     struct rte_flow_error *error);
-static int
-mlx5_flow_pull(struct rte_eth_dev *dev,
-	       uint32_t queue,
-	       struct rte_flow_op_result res[],
-	       uint16_t n_res,
-	       struct rte_flow_error *error);
-static int
-mlx5_flow_push(struct rte_eth_dev *dev,
-	       uint32_t queue,
-	       struct rte_flow_error *error);
-
-static struct rte_flow_action_handle *
-mlx5_flow_async_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
-				 const struct rte_flow_op_attr *attr,
-				 const struct rte_flow_indir_action_conf *conf,
-				 const struct rte_flow_action *action,
-				 void *user_data,
-				 struct rte_flow_error *error);
-
-static int
-mlx5_flow_async_action_handle_update(struct rte_eth_dev *dev, uint32_t queue,
-				 const struct rte_flow_op_attr *attr,
-				 struct rte_flow_action_handle *handle,
-				 const void *update,
-				 void *user_data,
-				 struct rte_flow_error *error);

 static int
-mlx5_flow_async_action_handle_destroy(struct rte_eth_dev *dev, uint32_t queue,
-				  const struct rte_flow_op_attr *attr,
-				  struct rte_flow_action_handle *handle,
-				  void *user_data,
-				  struct rte_flow_error *error);
-
-static int
-mlx5_flow_async_action_handle_query(struct rte_eth_dev *dev, uint32_t queue,
-				 const struct rte_flow_op_attr *attr,
-				 const struct rte_flow_action_handle *handle,
-				 void *data,
-				 void *user_data,
-				 struct rte_flow_error *error);
-static int
 mlx5_action_handle_query_update(struct rte_eth_dev *dev,
 				struct rte_flow_action_handle *handle,
 				const void *update, void *query,
 				enum rte_flow_query_update_mode qu_mode,
 				struct rte_flow_error *error);
-static int
-mlx5_flow_async_action_handle_query_update
-	(struct rte_eth_dev *dev, uint32_t queue_id,
-	 const struct rte_flow_op_attr *op_attr,
-	 struct rte_flow_action_handle *action_handle,
-	 const void *update, void *query,
-	 enum rte_flow_query_update_mode qu_mode,
-	 void *user_data, struct rte_flow_error *error);

 static struct rte_flow_action_list_handle *
 mlx5_action_list_handle_create(struct rte_eth_dev *dev,
@@ -1159,20 +1074,6 @@ mlx5_action_list_handle_destroy(struct rte_eth_dev *dev,
 				struct rte_flow_action_list_handle *handle,
 				struct rte_flow_error *error);

-static struct rte_flow_action_list_handle *
-mlx5_flow_async_action_list_handle_create(struct rte_eth_dev *dev, uint32_t queue_id,
-					  const struct rte_flow_op_attr *attr,
-					  const struct
-					  rte_flow_indir_action_conf *conf,
-					  const struct rte_flow_action *actions,
-					  void *user_data,
-					  struct rte_flow_error *error);
-static int
-mlx5_flow_async_action_list_handle_destroy
-			(struct rte_eth_dev *dev, uint32_t queue_id,
-			 const struct rte_flow_op_attr *op_attr,
-			 struct rte_flow_action_list_handle *action_handle,
-			 void *user_data, struct rte_flow_error *error);
 static int
 mlx5_flow_action_list_handle_query_update(struct rte_eth_dev *dev,
 					  const
@@ -1180,17 +1081,7 @@ mlx5_flow_action_list_handle_query_update(struct rte_eth_dev *dev,
 					  const void **update, void **query,
 					  enum rte_flow_query_update_mode mode,
 					  struct rte_flow_error *error);
-static int
-mlx5_flow_async_action_list_handle_query_update(struct rte_eth_dev *dev,
-						uint32_t queue_id,
-						const struct rte_flow_op_attr *attr,
-						const struct
-						rte_flow_action_list_handle *handle,
-						const void **update,
-						void **query,
-						enum rte_flow_query_update_mode mode,
-						void *user_data,
-						struct rte_flow_error *error);
+
 static int
 mlx5_flow_calc_table_hash(struct rte_eth_dev *dev,
 			  const struct rte_flow_template_table *table,
@@ -1232,26 +1123,8 @@ static const struct rte_flow_ops mlx5_flow_ops = {
 	.template_table_create = mlx5_flow_table_create,
 	.template_table_destroy = mlx5_flow_table_destroy,
 	.group_set_miss_actions = mlx5_flow_group_set_miss_actions,
-	.async_create = mlx5_flow_async_flow_create,
-	.async_create_by_index = mlx5_flow_async_flow_create_by_index,
-	.async_destroy = mlx5_flow_async_flow_destroy,
-	.pull = mlx5_flow_pull,
-	.push = mlx5_flow_push,
-	.async_action_handle_create = mlx5_flow_async_action_handle_create,
-	.async_action_handle_update = mlx5_flow_async_action_handle_update,
-	.async_action_handle_query_update =
-		mlx5_flow_async_action_handle_query_update,
-	.async_action_handle_query = mlx5_flow_async_action_handle_query,
-	.async_action_handle_destroy = mlx5_flow_async_action_handle_destroy,
-	.async_actions_update = mlx5_flow_async_flow_update,
-	.async_action_list_handle_create =
-		mlx5_flow_async_action_list_handle_create,
-	.async_action_list_handle_destroy =
-		mlx5_flow_async_action_list_handle_destroy,
 	.action_list_handle_query_update =
 		mlx5_flow_action_list_handle_query_update,
-	.async_action_list_handle_query_update =
-		mlx5_flow_async_action_list_handle_query_update,
 	.flow_calc_table_hash = mlx5_flow_calc_table_hash,
 };

@@ -9427,424 +9300,6 @@ mlx5_flow_group_set_miss_actions(struct rte_eth_dev *dev,
 	return fops->group_set_miss_actions(dev, group_id, attr, actions, error);
 }

-/**
- * Enqueue flow creation.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue_id
- *   The queue to create the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] items
- *   Items with flow spec value.
- * @param[in] pattern_template_index
- *   The item pattern flow follows from the table.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    Flow pointer on success, NULL otherwise and rte_errno is set.
- */
-static struct rte_flow *
-mlx5_flow_async_flow_create(struct rte_eth_dev *dev,
-			    uint32_t queue_id,
-			    const struct rte_flow_op_attr *attr,
-			    struct rte_flow_template_table *table,
-			    const struct rte_flow_item items[],
-			    uint8_t pattern_template_index,
-			    const struct rte_flow_action actions[],
-			    uint8_t action_template_index,
-			    void *user_data,
-			    struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr fattr = {0};
-
-	if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW) {
-		rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q create with incorrect steering mode");
-		return NULL;
-	}
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->async_flow_create(dev, queue_id, attr, table,
-				       items, pattern_template_index,
-				       actions, action_template_index,
-				       user_data, error);
-}
-
-/**
- * Enqueue flow creation by index.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue_id
- *   The queue to create the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] rule_index
- *   The item pattern flow follows from the table.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    Flow pointer on success, NULL otherwise and rte_errno is set.
- */
-static struct rte_flow *
-mlx5_flow_async_flow_create_by_index(struct rte_eth_dev *dev,
-			    uint32_t queue_id,
-			    const struct rte_flow_op_attr *attr,
-			    struct rte_flow_template_table *table,
-			    uint32_t rule_index,
-			    const struct rte_flow_action actions[],
-			    uint8_t action_template_index,
-			    void *user_data,
-			    struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr fattr = {0};
-
-	if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW) {
-		rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q create with incorrect steering mode");
-		return NULL;
-	}
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->async_flow_create_by_index(dev, queue_id, attr, table,
-				       rule_index, actions, action_template_index,
-				       user_data, error);
-}
-
-/**
- * Enqueue flow update.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to destroy the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] flow
- *   Pointer to the flow to be destroyed.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_flow_update(struct rte_eth_dev *dev,
-			     uint32_t queue,
-			     const struct rte_flow_op_attr *attr,
-			     struct rte_flow *flow,
-			     const struct rte_flow_action actions[],
-			     uint8_t action_template_index,
-			     void *user_data,
-			     struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr fattr = {0};
-
-	if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW)
-		return rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q update with incorrect steering mode");
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->async_flow_update(dev, queue, attr, flow,
-					actions, action_template_index, user_data, error);
-}
-
-/**
- * Enqueue flow destruction.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to destroy the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] flow
- *   Pointer to the flow to be destroyed.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_flow_destroy(struct rte_eth_dev *dev,
-			     uint32_t queue,
-			     const struct rte_flow_op_attr *attr,
-			     struct rte_flow *flow,
-			     void *user_data,
-			     struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr fattr = {0};
-
-	if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW)
-		return rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q destroy with incorrect steering mode");
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->async_flow_destroy(dev, queue, attr, flow,
-					user_data, error);
-}
-
-/**
- * Pull the enqueued flows.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to pull the result.
- * @param[in/out] res
- *   Array to save the results.
- * @param[in] n_res
- *   Available result with the array.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    Result number on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_pull(struct rte_eth_dev *dev,
-	       uint32_t queue,
-	       struct rte_flow_op_result res[],
-	       uint16_t n_res,
-	       struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr attr = {0};
-
-	if (flow_get_drv_type(dev, &attr) != MLX5_FLOW_TYPE_HW)
-		return rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q pull with incorrect steering mode");
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->pull(dev, queue, res, n_res, error);
-}
-
-/**
- * Push the enqueued flows.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to push the flows.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_push(struct rte_eth_dev *dev,
-	       uint32_t queue,
-	       struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr attr = {0};
-
-	if (flow_get_drv_type(dev, &attr) != MLX5_FLOW_TYPE_HW)
-		return rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q push with incorrect steering mode");
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->push(dev, queue, error);
-}
-
-/**
- * Create shared action.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   Which queue to be used..
- * @param[in] attr
- *   Operation attribute.
- * @param[in] conf
- *   Indirect action configuration.
- * @param[in] action
- *   rte_flow action detail.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *   Action handle on success, NULL otherwise and rte_errno is set.
- */
-static struct rte_flow_action_handle *
-mlx5_flow_async_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
-				 const struct rte_flow_op_attr *attr,
-				 const struct rte_flow_indir_action_conf *conf,
-				 const struct rte_flow_action *action,
-				 void *user_data,
-				 struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	return fops->async_action_create(dev, queue, attr, conf, action,
-					 user_data, error);
-}
-
-/**
- * Update shared action.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   Which queue to be used..
- * @param[in] attr
- *   Operation attribute.
- * @param[in] handle
- *   Action handle to be updated.
- * @param[in] update
- *   Update value.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *   0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_action_handle_update(struct rte_eth_dev *dev, uint32_t queue,
-				     const struct rte_flow_op_attr *attr,
-				     struct rte_flow_action_handle *handle,
-				     const void *update,
-				     void *user_data,
-				     struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	return fops->async_action_update(dev, queue, attr, handle,
-					 update, user_data, error);
-}
-
-static int
-mlx5_flow_async_action_handle_query_update
-	(struct rte_eth_dev *dev, uint32_t queue_id,
-	 const struct rte_flow_op_attr *op_attr,
-	 struct rte_flow_action_handle *action_handle,
-	 const void *update, void *query,
-	 enum rte_flow_query_update_mode qu_mode,
-	 void *user_data, struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-		flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	if (!fops || !fops->async_action_query_update)
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-					  "async query_update not supported");
-	return fops->async_action_query_update
-			   (dev, queue_id, op_attr, action_handle,
-			    update, query, qu_mode, user_data, error);
-}
-
-/**
- * Query shared action.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   Which queue to be used..
- * @param[in] attr
- *   Operation attribute.
- * @param[in] handle
- *   Action handle to be updated.
- * @param[in] data
- *   Pointer query result data.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *   0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_action_handle_query(struct rte_eth_dev *dev, uint32_t queue,
-				    const struct rte_flow_op_attr *attr,
-				    const struct rte_flow_action_handle *handle,
-				    void *data,
-				    void *user_data,
-				    struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	return fops->async_action_query(dev, queue, attr, handle,
-					data, user_data, error);
-}
-
-/**
- * Destroy shared action.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   Which queue to be used..
- * @param[in] attr
- *   Operation attribute.
- * @param[in] handle
- *   Action handle to be destroyed.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *   0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_action_handle_destroy(struct rte_eth_dev *dev, uint32_t queue,
-				      const struct rte_flow_op_attr *attr,
-				      struct rte_flow_action_handle *handle,
-				      void *user_data,
-				      struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	return fops->async_action_destroy(dev, queue, attr, handle,
-					  user_data, error);
-}
-
 /**
  * Allocate a new memory for the counter values wrapped by all the needed
  * management.
@@ -11015,41 +10470,6 @@ mlx5_action_list_handle_destroy(struct rte_eth_dev *dev,
 	return fops->action_list_handle_destroy(dev, handle, error);
 }

-static struct rte_flow_action_list_handle *
-mlx5_flow_async_action_list_handle_create(struct rte_eth_dev *dev,
-					  uint32_t queue_id,
-					  const struct
-					  rte_flow_op_attr *op_attr,
-					  const struct
-					  rte_flow_indir_action_conf *conf,
-					  const struct rte_flow_action *actions,
-					  void *user_data,
-					  struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-
-	MLX5_DRV_FOPS_OR_ERR(dev, fops, async_action_list_handle_create, NULL);
-	return fops->async_action_list_handle_create(dev, queue_id, op_attr,
-						     conf, actions, user_data,
-						     error);
-}
-
-static int
-mlx5_flow_async_action_list_handle_destroy
-	(struct rte_eth_dev *dev, uint32_t queue_id,
-	 const struct rte_flow_op_attr *op_attr,
-	 struct rte_flow_action_list_handle *action_handle,
-	 void *user_data, struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-
-	MLX5_DRV_FOPS_OR_ERR(dev, fops,
-			     async_action_list_handle_destroy, ENOTSUP);
-	return fops->async_action_list_handle_destroy(dev, queue_id, op_attr,
-						      action_handle, user_data,
-						      error);
-}
-
 static int
 mlx5_flow_action_list_handle_query_update(struct rte_eth_dev *dev,
 					  const
@@ -11065,32 +10485,6 @@ mlx5_flow_action_list_handle_query_update(struct rte_eth_dev *dev,
 	return fops->action_list_handle_query_update(dev, handle, update, query,
 						     mode, error);
 }
-
-static int
-mlx5_flow_async_action_list_handle_query_update(struct rte_eth_dev *dev,
-						uint32_t queue_id,
-						const
-						struct rte_flow_op_attr *op_attr,
-						const struct
-						rte_flow_action_list_handle *handle,
-						const void **update,
-						void **query,
-						enum
-						rte_flow_query_update_mode mode,
-						void *user_data,
-						struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-
-	MLX5_DRV_FOPS_OR_ERR(dev, fops,
-			     async_action_list_handle_query_update, ENOTSUP);
-	return fops->async_action_list_handle_query_update(dev, queue_id, op_attr,
-							   handle, update,
-							   query, mode,
-							   user_data, error);
-}
-
-
 static int
 mlx5_flow_calc_table_hash(struct rte_eth_dev *dev,
 			  const struct rte_flow_template_table *table,
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index da873ae2e2..c65ebfbba2 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -3,6 +3,7 @@
  */

 #include <rte_flow.h>
+#include <rte_flow_driver.h>

 #include <mlx5_malloc.h>

@@ -14,6 +15,9 @@
 #if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H)
 #include "mlx5_hws_cnt.h"

+/** Fast path async flow API functions. */
+static struct rte_flow_fp_ops mlx5_flow_hw_fp_ops;
+
 /* The maximum actions support in the flow. */
 #define MLX5_HW_MAX_ACTS 16

@@ -9543,6 +9547,7 @@ flow_hw_configure(struct rte_eth_dev *dev,
 		mlx5_free(_queue_attr);
 	if (port_attr->flags & RTE_FLOW_PORT_FLAG_STRICT_QUEUE)
 		priv->hws_strict_queue = 1;
+	dev->flow_fp_ops = &mlx5_flow_hw_fp_ops;
 	return 0;
 err:
 	if (priv->hws_ctpool) {
@@ -9617,6 +9622,7 @@ flow_hw_resource_release(struct rte_eth_dev *dev)

 	if (!priv->dr_ctx)
 		return;
+	dev->flow_fp_ops = &rte_flow_fp_default_ops;
 	flow_hw_rxq_flag_set(dev, false);
 	flow_hw_flush_all_ctrl_flows(dev);
 	flow_hw_cleanup_tx_repr_tagging(dev);
@@ -12992,4 +12998,23 @@ mlx5_reformat_action_destroy(struct rte_eth_dev *dev,
 	mlx5_free(handle);
 	return 0;
 }
+
+static struct rte_flow_fp_ops mlx5_flow_hw_fp_ops = {
+	.async_create = flow_hw_async_flow_create,
+	.async_create_by_index = flow_hw_async_flow_create_by_index,
+	.async_actions_update = flow_hw_async_flow_update,
+	.async_destroy = flow_hw_async_flow_destroy,
+	.push = flow_hw_push,
+	.pull = flow_hw_pull,
+	.async_action_handle_create = flow_hw_action_handle_create,
+	.async_action_handle_destroy = flow_hw_action_handle_destroy,
+	.async_action_handle_update = flow_hw_action_handle_update,
+	.async_action_handle_query = flow_hw_action_handle_query,
+	.async_action_handle_query_update = flow_hw_async_action_handle_query_update,
+	.async_action_list_handle_create = flow_hw_async_action_list_handle_create,
+	.async_action_list_handle_destroy = flow_hw_async_action_list_handle_destroy,
+	.async_action_list_handle_query_update =
+		flow_hw_async_action_list_handle_query_update,
+};
+
 #endif
diff --git a/lib/ethdev/ethdev_driver.c b/lib/ethdev/ethdev_driver.c
index bd917a15fc..34909a3018 100644
--- a/lib/ethdev/ethdev_driver.c
+++ b/lib/ethdev/ethdev_driver.c
@@ -10,6 +10,7 @@

 #include "ethdev_driver.h"
 #include "ethdev_private.h"
+#include "rte_flow_driver.h"

 /**
  * A set of values to describe the possible states of a switch domain.
@@ -110,6 +111,7 @@ rte_eth_dev_allocate(const char *name)
 	}

 	eth_dev = eth_dev_get(port_id);
+	eth_dev->flow_fp_ops = &rte_flow_fp_default_ops;
 	strlcpy(eth_dev->data->name, name, sizeof(eth_dev->data->name));
 	eth_dev->data->port_id = port_id;
 	eth_dev->data->backer_port_id = RTE_MAX_ETHPORTS;
@@ -245,6 +247,8 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)

 	eth_dev_fp_ops_reset(rte_eth_fp_ops + eth_dev->data->port_id);

+	eth_dev->flow_fp_ops = &rte_flow_fp_default_ops;
+
 	rte_spinlock_lock(rte_mcfg_ethdev_get_lock());

 	eth_dev->state = RTE_ETH_DEV_UNUSED;
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index b482cd12bb..b2e879ae1d 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -71,6 +71,10 @@ struct rte_eth_dev {
 	struct rte_eth_dev_data *data;
 	void *process_private; /**< Pointer to per-process device data */
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
+	/**
+	 * Fast path flow API functions exported by PMD.
+	 */
+	const struct rte_flow_fp_ops *flow_fp_ops;
 	struct rte_device *device; /**< Backing device */
 	struct rte_intr_handle *intr_handle; /**< Device interrupt handle */

diff --git a/lib/ethdev/meson.build b/lib/ethdev/meson.build
index 3497aa1548..b8859de11b 100644
--- a/lib/ethdev/meson.build
+++ b/lib/ethdev/meson.build
@@ -49,3 +49,7 @@ deps += ['net', 'kvargs', 'meter', 'telemetry']
 if is_freebsd
     annotate_locks = false
 endif
+
+if get_option('buildtype').contains('debug')
+    cflags += ['-DRTE_FLOW_DEBUG']
+endif
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index f49d1d3767..02522730b3 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -2013,16 +2013,26 @@ rte_flow_async_create(uint16_t port_id,
 		      struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	struct rte_flow *flow;

-	flow = ops->async_create(dev, queue_id,
-				 op_attr, template_table,
-				 pattern, pattern_template_index,
-				 actions, actions_template_index,
-				 user_data, error);
-	if (flow == NULL)
-		flow_err(port_id, -rte_errno, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENODEV));
+		return NULL;
+	}
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_create == NULL) {
+		rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENOSYS));
+		return NULL;
+	}
+#endif
+
+	flow = dev->flow_fp_ops->async_create(dev, queue_id,
+					      op_attr, template_table,
+					      pattern, pattern_template_index,
+					      actions, actions_template_index,
+					      user_data, error);

 	rte_flow_trace_async_create(port_id, queue_id, op_attr, template_table,
 				    pattern, pattern_template_index, actions,
@@ -2043,16 +2053,24 @@ rte_flow_async_create_by_index(uint16_t port_id,
 			       struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
-	struct rte_flow *flow;

-	flow = ops->async_create_by_index(dev, queue_id,
-					  op_attr, template_table, rule_index,
-					  actions, actions_template_index,
-					  user_data, error);
-	if (flow == NULL)
-		flow_err(port_id, -rte_errno, error);
-	return flow;
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENODEV));
+		return NULL;
+	}
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_create_by_index == NULL) {
+		rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENOSYS));
+		return NULL;
+	}
+#endif
+
+	return dev->flow_fp_ops->async_create_by_index(dev, queue_id,
+						       op_attr, template_table, rule_index,
+						       actions, actions_template_index,
+						       user_data, error);
 }

 int
@@ -2064,14 +2082,20 @@ rte_flow_async_destroy(uint16_t port_id,
 		       struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;

-	ret = flow_err(port_id,
-		       ops->async_destroy(dev, queue_id,
-					  op_attr, flow,
-					  user_data, error),
-		       error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_destroy == NULL)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_destroy(dev, queue_id,
+					      op_attr, flow,
+					      user_data, error);

 	rte_flow_trace_async_destroy(port_id, queue_id, op_attr, flow,
 				     user_data, ret);
@@ -2090,15 +2114,21 @@ rte_flow_async_actions_update(uint16_t port_id,
 			      struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;

-	ret = flow_err(port_id,
-		       ops->async_actions_update(dev, queue_id, op_attr,
-						 flow, actions,
-						 actions_template_index,
-						 user_data, error),
-		       error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_actions_update == NULL)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_actions_update(dev, queue_id, op_attr,
+						     flow, actions,
+						     actions_template_index,
+						     user_data, error);

 	rte_flow_trace_async_actions_update(port_id, queue_id, op_attr, flow,
 					    actions, actions_template_index,
@@ -2113,12 +2143,18 @@ rte_flow_push(uint16_t port_id,
 	      struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;

-	ret = flow_err(port_id,
-		       ops->push(dev, queue_id, error),
-		       error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->push == NULL)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->push(dev, queue_id, error);

 	rte_flow_trace_push(port_id, queue_id, ret);

@@ -2133,16 +2169,22 @@ rte_flow_pull(uint16_t port_id,
 	      struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
-	int rc;

-	ret = ops->pull(dev, queue_id, res, n_res, error);
-	rc = ret ? ret : flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->pull == NULL)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->pull(dev, queue_id, res, n_res, error);

-	rte_flow_trace_pull(port_id, queue_id, res, n_res, rc);
+	rte_flow_trace_pull(port_id, queue_id, res, n_res, ret);

-	return rc;
+	return ret;
 }

 struct rte_flow_action_handle *
@@ -2155,13 +2197,24 @@ rte_flow_async_action_handle_create(uint16_t port_id,
 		struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	struct rte_flow_action_handle *handle;

-	handle = ops->async_action_handle_create(dev, queue_id, op_attr,
-					     indir_action_conf, action, user_data, error);
-	if (handle == NULL)
-		flow_err(port_id, -rte_errno, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENODEV));
+		return NULL;
+	}
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_handle_create == NULL) {
+		rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENOSYS));
+		return NULL;
+	}
+#endif
+
+	handle = dev->flow_fp_ops->async_action_handle_create(dev, queue_id, op_attr,
+							      indir_action_conf, action,
+							      user_data, error);

 	rte_flow_trace_async_action_handle_create(port_id, queue_id, op_attr,
 						  indir_action_conf, action,
@@ -2179,12 +2232,19 @@ rte_flow_async_action_handle_destroy(uint16_t port_id,
 		struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;

-	ret = ops->async_action_handle_destroy(dev, queue_id, op_attr,
-					   action_handle, user_data, error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_handle_destroy == NULL)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_handle_destroy(dev, queue_id, op_attr,
+							    action_handle, user_data, error);

 	rte_flow_trace_async_action_handle_destroy(port_id, queue_id, op_attr,
 						   action_handle, user_data, ret);
@@ -2202,12 +2262,19 @@ rte_flow_async_action_handle_update(uint16_t port_id,
 		struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;

-	ret = ops->async_action_handle_update(dev, queue_id, op_attr,
-					  action_handle, update, user_data, error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_handle_update == NULL)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_handle_update(dev, queue_id, op_attr,
+							   action_handle, update, user_data, error);

 	rte_flow_trace_async_action_handle_update(port_id, queue_id, op_attr,
 						  action_handle, update,
@@ -2226,14 +2293,19 @@ rte_flow_async_action_handle_query(uint16_t port_id,
 		struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;

-	if (unlikely(!ops))
-		return -rte_errno;
-	ret = ops->async_action_handle_query(dev, queue_id, op_attr,
-					  action_handle, data, user_data, error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_handle_query == NULL)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_handle_query(dev, queue_id, op_attr,
+							  action_handle, data, user_data, error);

 	rte_flow_trace_async_action_handle_query(port_id, queue_id, op_attr,
 						 action_handle, data, user_data,
@@ -2276,24 +2348,21 @@ rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id,
 					  void *user_data,
 					  struct rte_flow_error *error)
 {
-	int ret;
-	struct rte_eth_dev *dev;
-	const struct rte_flow_ops *ops;
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];

-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (!handle)
-		return -EINVAL;
-	if (!update && !query)
-		return -EINVAL;
-	dev = &rte_eth_devices[port_id];
-	ops = rte_flow_ops_get(port_id, error);
-	if (!ops || !ops->async_action_handle_query_update)
-		return -ENOTSUP;
-	ret = ops->async_action_handle_query_update(dev, queue_id, attr,
-						    handle, update,
-						    query, mode,
-						    user_data, error);
-	return flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_handle_query_update == NULL)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	return dev->flow_fp_ops->async_action_handle_query_update(dev, queue_id, attr,
+								  handle, update,
+								  query, mode,
+								  user_data, error);
 }

 struct rte_flow_action_list_handle *
@@ -2353,24 +2422,28 @@ rte_flow_async_action_list_handle_create(uint16_t port_id, uint32_t queue_id,
 					 void *user_data,
 					 struct rte_flow_error *error)
 {
-	int ret;
-	struct rte_eth_dev *dev;
-	const struct rte_flow_ops *ops;
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	struct rte_flow_action_list_handle *handle;
+	int ret;

-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
-	ops = rte_flow_ops_get(port_id, error);
-	if (!ops || !ops->async_action_list_handle_create) {
-		rte_flow_error_set(error, ENOTSUP,
-				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-				   "action_list handle not supported");
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENODEV));
 		return NULL;
 	}
-	dev = &rte_eth_devices[port_id];
-	handle = ops->async_action_list_handle_create(dev, queue_id, attr, conf,
-						      actions, user_data,
-						      error);
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_list_handle_create == NULL) {
+		rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENOSYS));
+		return NULL;
+	}
+#endif
+
+	handle = dev->flow_fp_ops->async_action_list_handle_create(dev, queue_id, attr, conf,
+								   actions, user_data,
+								   error);
 	ret = flow_err(port_id, -rte_errno, error);
+
 	rte_flow_trace_async_action_list_handle_create(port_id, queue_id, attr,
 						       conf, actions, user_data,
 						       ret);
@@ -2383,20 +2456,21 @@ rte_flow_async_action_list_handle_destroy(uint16_t port_id, uint32_t queue_id,
 				 struct rte_flow_action_list_handle *handle,
 				 void *user_data, struct rte_flow_error *error)
 {
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	int ret;
-	struct rte_eth_dev *dev;
-	const struct rte_flow_ops *ops;

-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	ops = rte_flow_ops_get(port_id, error);
-	if (!ops || !ops->async_action_list_handle_destroy)
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "async action_list handle not supported");
-	dev = &rte_eth_devices[port_id];
-	ret = ops->async_action_list_handle_destroy(dev, queue_id, op_attr,
-						    handle, user_data, error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (dev->flow_fp_ops == NULL || dev->flow_fp_ops->async_action_list_handle_destroy == NULL)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_list_handle_destroy(dev, queue_id, op_attr,
+								 handle, user_data, error);
+
 	rte_flow_trace_async_action_list_handle_destroy(port_id, queue_id,
 							op_attr, handle,
 							user_data, ret);
@@ -2437,22 +2511,24 @@ rte_flow_async_action_list_handle_query_update(uint16_t port_id, uint32_t queue_
 			 enum rte_flow_query_update_mode mode,
 			 void *user_data, struct rte_flow_error *error)
 {
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	int ret;
-	struct rte_eth_dev *dev;
-	const struct rte_flow_ops *ops;

-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	ops = rte_flow_ops_get(port_id, error);
-	if (!ops || !ops->async_action_list_handle_query_update)
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "action_list async query_update not supported");
-	dev = &rte_eth_devices[port_id];
-	ret = ops->async_action_list_handle_query_update(dev, queue_id, attr,
-							 handle, update, query,
-							 mode, user_data,
-							 error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (dev->flow_fp_ops == NULL ||
+	    dev->flow_fp_ops->async_action_list_handle_query_update == NULL)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_list_handle_query_update(dev, queue_id, attr,
+								      handle, update, query,
+								      mode, user_data,
+								      error);
+
 	rte_flow_trace_async_action_list_handle_query_update(port_id, queue_id,
 							     attr, handle,
 							     update, query,
@@ -2481,3 +2557,216 @@ rte_flow_calc_table_hash(uint16_t port_id, const struct rte_flow_template_table
 					hash, error);
 	return flow_err(port_id, ret, error);
 }
+
+static struct rte_flow *
+rte_flow_dummy_async_create(struct rte_eth_dev *dev __rte_unused,
+			    uint32_t queue __rte_unused,
+			    const struct rte_flow_op_attr *attr __rte_unused,
+			    struct rte_flow_template_table *table __rte_unused,
+			    const struct rte_flow_item items[] __rte_unused,
+			    uint8_t pattern_template_index __rte_unused,
+			    const struct rte_flow_action actions[] __rte_unused,
+			    uint8_t action_template_index __rte_unused,
+			    void *user_data __rte_unused,
+			    struct rte_flow_error *error)
+{
+	rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			   rte_strerror(ENOSYS));
+	return NULL;
+}
+
+static struct rte_flow *
+rte_flow_dummy_async_create_by_index(struct rte_eth_dev *dev __rte_unused,
+				     uint32_t queue __rte_unused,
+				     const struct rte_flow_op_attr *attr __rte_unused,
+				     struct rte_flow_template_table *table __rte_unused,
+				     uint32_t rule_index __rte_unused,
+				     const struct rte_flow_action actions[] __rte_unused,
+				     uint8_t action_template_index __rte_unused,
+				     void *user_data __rte_unused,
+				     struct rte_flow_error *error)
+{
+	rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			   rte_strerror(ENOSYS));
+	return NULL;
+}
+
+static int
+rte_flow_dummy_async_actions_update(struct rte_eth_dev *dev __rte_unused,
+				    uint32_t queue_id __rte_unused,
+				    const struct rte_flow_op_attr *op_attr __rte_unused,
+				    struct rte_flow *flow __rte_unused,
+				    const struct rte_flow_action actions[] __rte_unused,
+				    uint8_t actions_template_index __rte_unused,
+				    void *user_data __rte_unused,
+				    struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_destroy(struct rte_eth_dev *dev __rte_unused,
+			     uint32_t queue_id __rte_unused,
+			     const struct rte_flow_op_attr *op_attr __rte_unused,
+			     struct rte_flow *flow __rte_unused,
+			     void *user_data __rte_unused,
+			     struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_push(struct rte_eth_dev *dev __rte_unused,
+		    uint32_t queue_id __rte_unused,
+		    struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_pull(struct rte_eth_dev *dev __rte_unused,
+		    uint32_t queue_id __rte_unused,
+		    struct rte_flow_op_result res[] __rte_unused,
+		    uint16_t n_res __rte_unused,
+		    struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static struct rte_flow_action_handle *
+rte_flow_dummy_async_action_handle_create(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	const struct rte_flow_indir_action_conf *indir_action_conf __rte_unused,
+	const struct rte_flow_action *action __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			   rte_strerror(ENOSYS));
+	return NULL;
+}
+
+static int
+rte_flow_dummy_async_action_handle_destroy(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	struct rte_flow_action_handle *action_handle __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_action_handle_update(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	struct rte_flow_action_handle *action_handle __rte_unused,
+	const void *update __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_action_handle_query(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	const struct rte_flow_action_handle *action_handle __rte_unused,
+	void *data __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_action_handle_query_update(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *attr __rte_unused,
+	struct rte_flow_action_handle *handle __rte_unused,
+	const void *update __rte_unused,
+	void *query __rte_unused,
+	enum rte_flow_query_update_mode mode __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static struct rte_flow_action_list_handle *
+rte_flow_dummy_async_action_list_handle_create(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *attr __rte_unused,
+	const struct rte_flow_indir_action_conf *conf __rte_unused,
+	const struct rte_flow_action *actions __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			   rte_strerror(ENOSYS));
+	return NULL;
+}
+
+static int
+rte_flow_dummy_async_action_list_handle_destroy(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	struct rte_flow_action_list_handle *handle __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_action_list_handle_query_update(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *attr __rte_unused,
+	const struct rte_flow_action_list_handle *handle __rte_unused,
+	const void **update __rte_unused,
+	void **query __rte_unused,
+	enum rte_flow_query_update_mode mode __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+struct rte_flow_fp_ops rte_flow_fp_default_ops = {
+	.async_create = rte_flow_dummy_async_create,
+	.async_create_by_index = rte_flow_dummy_async_create_by_index,
+	.async_actions_update = rte_flow_dummy_async_actions_update,
+	.async_destroy = rte_flow_dummy_async_destroy,
+	.push = rte_flow_dummy_push,
+	.pull = rte_flow_dummy_pull,
+	.async_action_handle_create = rte_flow_dummy_async_action_handle_create,
+	.async_action_handle_destroy = rte_flow_dummy_async_action_handle_destroy,
+	.async_action_handle_update = rte_flow_dummy_async_action_handle_update,
+	.async_action_handle_query = rte_flow_dummy_async_action_handle_query,
+	.async_action_handle_query_update = rte_flow_dummy_async_action_handle_query_update,
+	.async_action_list_handle_create = rte_flow_dummy_async_action_list_handle_create,
+	.async_action_list_handle_destroy = rte_flow_dummy_async_action_list_handle_destroy,
+	.async_action_list_handle_query_update =
+		rte_flow_dummy_async_action_list_handle_query_update,
+};
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index f35f659503..dd9d01045d 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -234,122 +234,12 @@ struct rte_flow_ops {
 		 const struct rte_flow_group_attr *attr,
 		 const struct rte_flow_action actions[],
 		 struct rte_flow_error *err);
-	/** See rte_flow_async_create() */
-	struct rte_flow *(*async_create)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_template_table *template_table,
-		 const struct rte_flow_item pattern[],
-		 uint8_t pattern_template_index,
-		 const struct rte_flow_action actions[],
-		 uint8_t actions_template_index,
-		 void *user_data,
-		 struct rte_flow_error *err);
-	/** See rte_flow_async_create_by_index() */
-	struct rte_flow *(*async_create_by_index)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_template_table *template_table,
-		 uint32_t rule_index,
-		 const struct rte_flow_action actions[],
-		 uint8_t actions_template_index,
-		 void *user_data,
-		 struct rte_flow_error *err);
-	/** See rte_flow_async_destroy() */
-	int (*async_destroy)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow *flow,
-		 void *user_data,
-		 struct rte_flow_error *err);
-	/** See rte_flow_push() */
-	int (*push)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 struct rte_flow_error *err);
-	/** See rte_flow_pull() */
-	int (*pull)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 struct rte_flow_op_result res[],
-		 uint16_t n_res,
-		 struct rte_flow_error *error);
-	/** See rte_flow_async_action_handle_create() */
-	struct rte_flow_action_handle *(*async_action_handle_create)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 const struct rte_flow_indir_action_conf *indir_action_conf,
-		 const struct rte_flow_action *action,
-		 void *user_data,
-		 struct rte_flow_error *err);
-	/** See rte_flow_async_action_handle_destroy() */
-	int (*async_action_handle_destroy)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_action_handle *action_handle,
-		 void *user_data,
-		 struct rte_flow_error *error);
-	/** See rte_flow_async_action_handle_update() */
-	int (*async_action_handle_update)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_action_handle *action_handle,
-		 const void *update,
-		 void *user_data,
-		 struct rte_flow_error *error);
-	/** See rte_flow_async_action_handle_query() */
-	int (*async_action_handle_query)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 const struct rte_flow_action_handle *action_handle,
-		 void *data,
-		 void *user_data,
-		 struct rte_flow_error *error);
-	/** See rte_flow_async_action_handle_query_update */
-	int (*async_action_handle_query_update)
-		(struct rte_eth_dev *dev, uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_action_handle *action_handle,
-		 const void *update, void *query,
-		 enum rte_flow_query_update_mode qu_mode,
-		 void *user_data, struct rte_flow_error *error);
 	/** See rte_flow_actions_update(). */
 	int (*actions_update)
 		(struct rte_eth_dev *dev,
 		 struct rte_flow *flow,
 		 const struct rte_flow_action actions[],
 		 struct rte_flow_error *error);
-	/** See rte_flow_async_actions_update() */
-	int (*async_actions_update)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow *flow,
-		 const struct rte_flow_action actions[],
-		 uint8_t actions_template_index,
-		 void *user_data,
-		 struct rte_flow_error *error);
-	/** @see rte_flow_async_action_list_handle_create() */
-	struct rte_flow_action_list_handle *
-	(*async_action_list_handle_create)
-		(struct rte_eth_dev *dev, uint32_t queue_id,
-		 const struct rte_flow_op_attr *attr,
-		 const struct rte_flow_indir_action_conf *conf,
-		 const struct rte_flow_action *actions,
-		 void *user_data, struct rte_flow_error *error);
-	/** @see rte_flow_async_action_list_handle_destroy() */
-	int (*async_action_list_handle_destroy)
-		(struct rte_eth_dev *dev, uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_action_list_handle *action_handle,
-		 void *user_data, struct rte_flow_error *error);
 	/** @see rte_flow_action_list_handle_query_update() */
 	int (*action_list_handle_query_update)
 		(struct rte_eth_dev *dev,
@@ -357,14 +247,6 @@ struct rte_flow_ops {
 		 const void **update, void **query,
 		 enum rte_flow_query_update_mode mode,
 		 struct rte_flow_error *error);
-	/** @see rte_flow_async_action_list_handle_query_update() */
-	int (*async_action_list_handle_query_update)
-		(struct rte_eth_dev *dev, uint32_t queue_id,
-		 const struct rte_flow_op_attr *attr,
-		 const struct rte_flow_action_list_handle *handle,
-		 const void **update, void **query,
-		 enum rte_flow_query_update_mode mode,
-		 void *user_data, struct rte_flow_error *error);
 	/** @see rte_flow_calc_table_hash() */
 	int (*flow_calc_table_hash)
 		(struct rte_eth_dev *dev, const struct rte_flow_template_table *table,
@@ -394,6 +276,165 @@ rte_flow_ops_get(uint16_t port_id, struct rte_flow_error *error);
 int
 rte_flow_restore_info_dynflag_register(void);

+/** @internal Enqueue rule creation operation. */
+typedef struct rte_flow *(*rte_flow_async_create_t)(struct rte_eth_dev *dev,
+						    uint32_t queue,
+						    const struct rte_flow_op_attr *attr,
+						    struct rte_flow_template_table *table,
+						    const struct rte_flow_item *items,
+						    uint8_t pattern_template_index,
+						    const struct rte_flow_action *actions,
+						    uint8_t action_template_index,
+						    void *user_data,
+						    struct rte_flow_error *error);
+
+/** @internal Enqueue rule creation by index operation. */
+typedef struct rte_flow *(*rte_flow_async_create_by_index_t)(struct rte_eth_dev *dev,
+							     uint32_t queue,
+							     const struct rte_flow_op_attr *attr,
+							     struct rte_flow_template_table *table,
+							     uint32_t rule_index,
+							     const struct rte_flow_action *actions,
+							     uint8_t action_template_index,
+							     void *user_data,
+							     struct rte_flow_error *error);
+
+/** @internal Enqueue rule update operation. */
+typedef int (*rte_flow_async_actions_update_t)(struct rte_eth_dev *dev,
+					       uint32_t queue_id,
+					       const struct rte_flow_op_attr *op_attr,
+					       struct rte_flow *flow,
+					       const struct rte_flow_action *actions,
+					       uint8_t actions_template_index,
+					       void *user_data,
+					       struct rte_flow_error *error);
+
+/** @internal Enqueue rule destruction operation. */
+typedef int (*rte_flow_async_destroy_t)(struct rte_eth_dev *dev,
+					uint32_t queue_id,
+					const struct rte_flow_op_attr *op_attr,
+					struct rte_flow *flow,
+					void *user_data,
+					struct rte_flow_error *error);
+
+/** @internal Push all internally stored rules to the HW. */
+typedef int (*rte_flow_push_t)(struct rte_eth_dev *dev,
+			       uint32_t queue_id,
+			       struct rte_flow_error *error);
+
+/** @internal Pull the flow rule operations results from the HW. */
+typedef int (*rte_flow_pull_t)(struct rte_eth_dev *dev,
+			       uint32_t queue_id,
+			       struct rte_flow_op_result *res,
+			       uint16_t n_res,
+			       struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action creation operation. */
+typedef struct rte_flow_action_handle *(*rte_flow_async_action_handle_create_t)(
+					struct rte_eth_dev *dev,
+					uint32_t queue_id,
+					const struct rte_flow_op_attr *op_attr,
+					const struct rte_flow_indir_action_conf *indir_action_conf,
+					const struct rte_flow_action *action,
+					void *user_data,
+					struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action destruction operation. */
+typedef int (*rte_flow_async_action_handle_destroy_t)(struct rte_eth_dev *dev,
+						      uint32_t queue_id,
+						      const struct rte_flow_op_attr *op_attr,
+						      struct rte_flow_action_handle *action_handle,
+						      void *user_data,
+						      struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action update operation. */
+typedef int (*rte_flow_async_action_handle_update_t)(struct rte_eth_dev *dev,
+						     uint32_t queue_id,
+						     const struct rte_flow_op_attr *op_attr,
+						     struct rte_flow_action_handle *action_handle,
+						     const void *update,
+						     void *user_data,
+						     struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action query operation. */
+typedef int (*rte_flow_async_action_handle_query_t)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 const struct rte_flow_op_attr *op_attr,
+		 const struct rte_flow_action_handle *action_handle,
+		 void *data,
+		 void *user_data,
+		 struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action query and/or update operation. */
+typedef int (*rte_flow_async_action_handle_query_update_t)(struct rte_eth_dev *dev,
+							   uint32_t queue_id,
+							   const struct rte_flow_op_attr *attr,
+							   struct rte_flow_action_handle *handle,
+							   const void *update, void *query,
+							   enum rte_flow_query_update_mode mode,
+							   void *user_data,
+							   struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action list creation operation. */
+typedef struct rte_flow_action_list_handle *(*rte_flow_async_action_list_handle_create_t)(
+	struct rte_eth_dev *dev,
+	uint32_t queue_id,
+	const struct rte_flow_op_attr *attr,
+	const struct rte_flow_indir_action_conf *conf,
+	const struct rte_flow_action *actions,
+	void *user_data,
+	struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action list destruction operation. */
+typedef int (*rte_flow_async_action_list_handle_destroy_t)(
+	struct rte_eth_dev *dev,
+	uint32_t queue_id,
+	const struct rte_flow_op_attr *op_attr,
+	struct rte_flow_action_list_handle *handle,
+	void *user_data,
+	struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action list query and/or update operation. */
+typedef int (*rte_flow_async_action_list_handle_query_update_t)(
+	struct rte_eth_dev *dev,
+	uint32_t queue_id,
+	const struct rte_flow_op_attr *attr,
+	const struct rte_flow_action_list_handle *handle,
+	const void **update,
+	void **query,
+	enum rte_flow_query_update_mode mode,
+	void *user_data,
+	struct rte_flow_error *error);
+
+/**
+ * @internal
+ *
+ * Fast path async flow functions are held in a flat array, one entry per ethdev.
+ */
+struct rte_flow_fp_ops {
+	rte_flow_async_create_t async_create;
+	rte_flow_async_create_by_index_t async_create_by_index;
+	rte_flow_async_actions_update_t async_actions_update;
+	rte_flow_async_destroy_t async_destroy;
+	rte_flow_push_t push;
+	rte_flow_pull_t pull;
+	rte_flow_async_action_handle_create_t async_action_handle_create;
+	rte_flow_async_action_handle_destroy_t async_action_handle_destroy;
+	rte_flow_async_action_handle_update_t async_action_handle_update;
+	rte_flow_async_action_handle_query_t async_action_handle_query;
+	rte_flow_async_action_handle_query_update_t async_action_handle_query_update;
+	rte_flow_async_action_list_handle_create_t async_action_list_handle_create;
+	rte_flow_async_action_list_handle_destroy_t async_action_list_handle_destroy;
+	rte_flow_async_action_list_handle_query_update_t async_action_list_handle_query_update;
+} __rte_cache_aligned;
+
+/**
+ * @internal
+ * Default implementation of fast path flow API functions.
+ */
+extern struct rte_flow_fp_ops rte_flow_fp_default_ops;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 5c4917c020..a8758084f6 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -345,4 +345,6 @@ INTERNAL {
 	rte_eth_representor_id_get;
 	rte_eth_switch_domain_alloc;
 	rte_eth_switch_domain_free;
+
+	rte_flow_fp_default_ops;
 };
--
2.25.1


^ permalink raw reply	[relevance 1%]

* [PATCH v7 1/4] ethdev: rename action modify field data structure
  2024-02-06  2:06  3% ` [PATCH v7 0/4] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Suanming Mou
@ 2024-02-06  2:06  3%   ` Suanming Mou
  2024-02-06 21:24  0%   ` [PATCH v7 0/4] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Ferruh Yigit
  1 sibling, 0 replies; 200+ results
From: Suanming Mou @ 2024-02-06  2:06 UTC (permalink / raw)
  To: thomas, ferruh.yigit, Ori Kam, Aman Singh, Yuying Zhang,
	Dariusz Sosnowski, Viacheslav Ovsiienko, Matan Azrad,
	Andrew Rybchenko
  Cc: dev

Current rte_flow_action_modify_data struct describes the pkt
field perfectly and is used only in action.

It is planned to be used for item as well. This commit renames
it to "rte_flow_field_data" making it compatible to be used by item.

Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c            | 22 +++++++++++-----------
 doc/guides/prog_guide/rte_flow.rst     |  2 +-
 doc/guides/rel_notes/release_24_03.rst |  3 +++
 drivers/net/mlx5/mlx5_flow.c           |  4 ++--
 drivers/net/mlx5/mlx5_flow.h           |  6 +++---
 drivers/net/mlx5/mlx5_flow_dv.c        | 10 +++++-----
 lib/ethdev/rte_flow.h                  | 10 +++++-----
 7 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 4d26e81d26..35030b5c47 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -744,13 +744,13 @@ enum index {
 #define ITEM_RAW_SIZE \
 	(sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE)
 
-/** Maximum size for external pattern in struct rte_flow_action_modify_data. */
-#define ACTION_MODIFY_PATTERN_SIZE 32
+/** Maximum size for external pattern in struct rte_flow_field_data. */
+#define FLOW_FIELD_PATTERN_SIZE 32
 
 /** Storage size for struct rte_flow_action_modify_field including pattern. */
 #define ACTION_MODIFY_SIZE \
 	(sizeof(struct rte_flow_action_modify_field) + \
-	ACTION_MODIFY_PATTERN_SIZE)
+	FLOW_FIELD_PATTERN_SIZE)
 
 /** Maximum number of queue indices in struct rte_flow_action_rss. */
 #define ACTION_RSS_QUEUE_NUM 128
@@ -944,7 +944,7 @@ static const char *const modify_field_ops[] = {
 	"set", "add", "sub", NULL
 };
 
-static const char *const modify_field_ids[] = {
+static const char *const flow_field_ids[] = {
 	"start", "mac_dst", "mac_src",
 	"vlan_type", "vlan_id", "mac_type",
 	"ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst",
@@ -6995,7 +6995,7 @@ static const struct token token_list[] = {
 			     ARGS_ENTRY_ARB(0, 0),
 			     ARGS_ENTRY_ARB
 				(sizeof(struct rte_flow_action_modify_field),
-				 ACTION_MODIFY_PATTERN_SIZE)),
+				 FLOW_FIELD_PATTERN_SIZE)),
 		.call = parse_vc_conf,
 	},
 	[ACTION_MODIFY_FIELD_WIDTH] = {
@@ -9821,10 +9821,10 @@ parse_vc_modify_field_id(struct context *ctx, const struct token *token,
 	if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE &&
 		ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)
 		return -1;
-	for (i = 0; modify_field_ids[i]; ++i)
-		if (!strcmp_partial(modify_field_ids[i], str, len))
+	for (i = 0; flow_field_ids[i]; ++i)
+		if (!strcmp_partial(flow_field_ids[i], str, len))
 			break;
-	if (!modify_field_ids[i])
+	if (!flow_field_ids[i])
 		return -1;
 	if (!ctx->object)
 		return len;
@@ -12051,10 +12051,10 @@ comp_set_modify_field_id(struct context *ctx, const struct token *token,
 
 	RTE_SET_USED(token);
 	if (!buf)
-		return RTE_DIM(modify_field_ids);
-	if (ent >= RTE_DIM(modify_field_ids) - 1)
+		return RTE_DIM(flow_field_ids);
+	if (ent >= RTE_DIM(flow_field_ids) - 1)
 		return -1;
-	name = modify_field_ids[ent];
+	name = flow_field_ids[ent];
 	if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE ||
 	    (strcmp(name, "pointer") && strcmp(name, "value")))
 		return strlcpy(buf, name, size);
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 7af329bd93..9192d6ab01 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3185,7 +3185,7 @@ destination offset as ``48``, and provide immediate value ``0xXXXX85XX``.
    | ``width``     | number of bits to use   |
    +---------------+-------------------------+
 
-.. _table_rte_flow_action_modify_data:
+.. _table_rte_flow_field_data:
 
 .. table:: destination/source field definition
 
diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 84d3144215..222a091e8b 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -106,6 +106,9 @@ API Changes
 
 * gso: ``rte_gso_segment`` now returns -ENOTSUP for unknown protocols.
 
+* ethdev: Renamed structure ``rte_flow_action_modify_data`` to be
+  ``rte_flow_field_data`` for more generic usage.
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 85e8c77c81..5788a7fb57 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2493,7 +2493,7 @@ mlx5_validate_action_ct(struct rte_eth_dev *dev,
  * Validate the level value for modify field action.
  *
  * @param[in] data
- *   Pointer to the rte_flow_action_modify_data structure either src or dst.
+ *   Pointer to the rte_flow_field_data structure either src or dst.
  * @param[out] error
  *   Pointer to error structure.
  *
@@ -2501,7 +2501,7 @@ mlx5_validate_action_ct(struct rte_eth_dev *dev,
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-flow_validate_modify_field_level(const struct rte_flow_action_modify_data *data,
+flow_validate_modify_field_level(const struct rte_flow_field_data *data,
 				 struct rte_flow_error *error)
 {
 	if (data->level == 0)
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 6dde9de688..ecfb04ead2 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -1121,7 +1121,7 @@ flow_items_to_tunnel(const struct rte_flow_item items[])
  *   Tag array index.
  */
 static inline uint8_t
-flow_tag_index_get(const struct rte_flow_action_modify_data *data)
+flow_tag_index_get(const struct rte_flow_field_data *data)
 {
 	return data->tag_index ? data->tag_index : data->level;
 }
@@ -2523,7 +2523,7 @@ int mlx5_flow_validate_action_default_miss(uint64_t action_flags,
 				const struct rte_flow_attr *attr,
 				struct rte_flow_error *error);
 int flow_validate_modify_field_level
-			(const struct rte_flow_action_modify_data *data,
+			(const struct rte_flow_field_data *data,
 			 struct rte_flow_error *error);
 int mlx5_flow_item_acceptable(const struct rte_flow_item *item,
 			      const uint8_t *mask,
@@ -2828,7 +2828,7 @@ size_t flow_dv_get_item_hdr_len(const enum rte_flow_item_type item_type);
 int flow_dv_convert_encap_data(const struct rte_flow_item *items, uint8_t *buf,
 			   size_t *size, struct rte_flow_error *error);
 void mlx5_flow_field_id_to_modify_info
-		(const struct rte_flow_action_modify_data *data,
+		(const struct rte_flow_field_data *data,
 		 struct field_modify_info *info, uint32_t *mask,
 		 uint32_t width, struct rte_eth_dev *dev,
 		 const struct rte_flow_attr *attr, struct rte_flow_error *error);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 115d730317..52620be262 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1441,7 +1441,7 @@ flow_modify_info_mask_32_masked(uint32_t length, uint32_t off, uint32_t post_mas
 }
 
 static __rte_always_inline enum mlx5_modification_field
-mlx5_mpls_modi_field_get(const struct rte_flow_action_modify_data *data)
+mlx5_mpls_modi_field_get(const struct rte_flow_field_data *data)
 {
 	return MLX5_MODI_IN_MPLS_LABEL_0 + data->tag_index;
 }
@@ -1449,7 +1449,7 @@ mlx5_mpls_modi_field_get(const struct rte_flow_action_modify_data *data)
 static void
 mlx5_modify_flex_item(const struct rte_eth_dev *dev,
 		      const struct mlx5_flex_item *flex,
-		      const struct rte_flow_action_modify_data *data,
+		      const struct rte_flow_field_data *data,
 		      struct field_modify_info *info,
 		      uint32_t *mask, uint32_t width)
 {
@@ -1573,7 +1573,7 @@ mlx5_modify_flex_item(const struct rte_eth_dev *dev,
 
 void
 mlx5_flow_field_id_to_modify_info
-		(const struct rte_flow_action_modify_data *data,
+		(const struct rte_flow_field_data *data,
 		 struct field_modify_info *info, uint32_t *mask,
 		 uint32_t width, struct rte_eth_dev *dev,
 		 const struct rte_flow_attr *attr, struct rte_flow_error *error)
@@ -5284,8 +5284,8 @@ flow_dv_validate_action_modify_field(struct rte_eth_dev *dev,
 	struct mlx5_sh_config *config = &priv->sh->config;
 	struct mlx5_hca_attr *hca_attr = &priv->sh->cdev->config.hca_attr;
 	const struct rte_flow_action_modify_field *conf = action->conf;
-	const struct rte_flow_action_modify_data *src_data = &conf->src;
-	const struct rte_flow_action_modify_data *dst_data = &conf->dst;
+	const struct rte_flow_field_data *src_data = &conf->src;
+	const struct rte_flow_field_data *dst_data = &conf->dst;
 	uint32_t dst_width, src_width, width = conf->width;
 
 	ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 1dded812ec..eb46cfe09e 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3893,7 +3893,7 @@ struct rte_flow_action_ethdev {
 };
 
 /**
- * Field IDs for MODIFY_FIELD action.
+ * Packet header field IDs, used by RTE_FLOW_ACTION_TYPE_MODIFY_FIELD.
  */
 enum rte_flow_field_id {
 	RTE_FLOW_FIELD_START = 0,	/**< Start of a packet. */
@@ -3947,9 +3947,9 @@ enum rte_flow_field_id {
  * @warning
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
- * Field description for MODIFY_FIELD action.
+ * Packet header field descriptions, used by RTE_FLOW_ACTION_TYPE_MODIFY_FIELD.
  */
-struct rte_flow_action_modify_data {
+struct rte_flow_field_data {
 	enum rte_flow_field_id field; /**< Field or memory type ID. */
 	union {
 		struct {
@@ -4058,8 +4058,8 @@ enum rte_flow_modify_op {
  */
 struct rte_flow_action_modify_field {
 	enum rte_flow_modify_op operation; /**< Operation to perform. */
-	struct rte_flow_action_modify_data dst; /**< Destination field. */
-	struct rte_flow_action_modify_data src; /**< Source field. */
+	struct rte_flow_field_data dst; /**< Destination field. */
+	struct rte_flow_field_data src; /**< Source field. */
 	uint32_t width; /**< Number of bits to use from a source field. */
 };
 
-- 
2.34.1


^ permalink raw reply	[relevance 3%]

* [PATCH v7 0/4] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE
                     ` (2 preceding siblings ...)
  2024-02-02  0:42  3% ` [PATCH v6 " Suanming Mou
@ 2024-02-06  2:06  3% ` Suanming Mou
  2024-02-06  2:06  3%   ` [PATCH v7 1/4] ethdev: rename action modify field data structure Suanming Mou
  2024-02-06 21:24  0%   ` [PATCH v7 0/4] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Ferruh Yigit
  3 siblings, 2 replies; 200+ results
From: Suanming Mou @ 2024-02-06  2:06 UTC (permalink / raw)
  To: thomas, ferruh.yigit; +Cc: dev, orika

The new item type is added for the case user wants to match traffic
based on packet field compare result with other fields or immediate
value.

e.g. take advantage the compare item user will be able to accumulate
a IPv4/TCP packet's TCP data_offset and IPv4 IHL field to a tag
register, then compare the tag register with IPv4 header total length
to understand the packet has payload or not.

The supported operations can be as below:
 - RTE_FLOW_ITEM_COMPARE_EQ (equal)
 - RTE_FLOW_ITEM_COMPARE_NE (not equal)
 - RTE_FLOW_ITEM_COMPARE_LT (less than)
 - RTE_FLOW_ITEM_COMPARE_LE (less than or equal)
 - RTE_FLOW_ITEM_COMPARE_GT (great than)
 - RTE_FLOW_ITEM_COMPARE_GE (great than or equal)

V7:
 - Moved release notes to API.
 - Optimize comment descriptions.

V6:
 - fix typo and style issue.
 - adjust flow_field description.

V5:
 - rebase on top of next-net
 - add sample detail for rte_flow_field.

V4:
 - rebase on top of the latest version.
 - move ACTION_MODIFY_PATTERN_SIZE and modify_field_ids rename
   to first patch.
 - add comparison flow create sample in testpmd_funcs.rst.

V3:
 - fix code style missing empty line in rte_flow.rst.
 - fix missing the ABI change release notes.

V2:
 - Since modify field data struct is experiment, rename modify
   field data directly instead of adding new flow field struct.


Suanming Mou (4):
  ethdev: rename action modify field data structure
  ethdev: move flow field data structures
  ethdev: add compare item
  net/mlx5: add compare item support

 app/test-pmd/cmdline_flow.c                 | 416 +++++++++++++++++++-
 doc/guides/nics/features/default.ini        |   1 +
 doc/guides/nics/features/mlx5.ini           |   1 +
 doc/guides/nics/mlx5.rst                    |   7 +
 doc/guides/prog_guide/rte_flow.rst          |   9 +-
 doc/guides/rel_notes/release_24_03.rst      |  10 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  24 ++
 drivers/net/mlx5/mlx5_flow.c                |   4 +-
 drivers/net/mlx5/mlx5_flow.h                |   9 +-
 drivers/net/mlx5/mlx5_flow_dv.c             |  10 +-
 drivers/net/mlx5/mlx5_flow_hw.c             |  73 ++++
 lib/ethdev/rte_flow.c                       |   1 +
 lib/ethdev/rte_flow.h                       | 330 +++++++++-------
 13 files changed, 726 insertions(+), 169 deletions(-)

-- 
2.34.1


^ permalink raw reply	[relevance 3%]

* [PATCH v9 05/23] mbuf: replace term sanity check
  @ 2024-02-05 17:43  2%   ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2024-02-05 17:43 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, Andrew Rybchenko, Morten Brørup,
	Steven Webster, Matt Peters

Replace rte_mbuf_sanity_check() with rte_mbuf_verify()
to match the similar macro RTE_VERIFY() in rte_debug.h

Good wording from discussion english.stackexchange.com:
  The phrase "sanity check" is ableist language as it implies that
  there is something wrong with people who have mental illnesses
  and the word "sanity" has been used to discriminate against such people.
  Therefore, it should should be avoided.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Acked-by: Morten Brørup <mb@smartsharesystems.com>
---
 app/test/test_mbuf.c                 | 28 +++++------
 doc/guides/prog_guide/mbuf_lib.rst   |  4 +-
 doc/guides/rel_notes/deprecation.rst |  3 ++
 drivers/net/avp/avp_ethdev.c         | 18 +++----
 drivers/net/sfc/sfc_ef100_rx.c       |  6 +--
 drivers/net/sfc/sfc_ef10_essb_rx.c   |  4 +-
 drivers/net/sfc/sfc_ef10_rx.c        |  4 +-
 drivers/net/sfc/sfc_rx.c             |  2 +-
 examples/ipv4_multicast/main.c       |  2 +-
 lib/mbuf/rte_mbuf.c                  | 23 +++++----
 lib/mbuf/rte_mbuf.h                  | 71 +++++++++++++++-------------
 lib/mbuf/version.map                 |  1 +
 12 files changed, 90 insertions(+), 76 deletions(-)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index d7393df7eb5d..261c6e5d71e9 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -261,8 +261,8 @@ test_one_pktmbuf(struct rte_mempool *pktmbuf_pool)
 		GOTO_FAIL("Buffer should be continuous");
 	memset(hdr, 0x55, MBUF_TEST_HDR2_LEN);
 
-	rte_mbuf_sanity_check(m, 1);
-	rte_mbuf_sanity_check(m, 0);
+	rte_mbuf_verify(m, 1);
+	rte_mbuf_verify(m, 0);
 	rte_pktmbuf_dump(stdout, m, 0);
 
 	/* this prepend should fail */
@@ -1161,7 +1161,7 @@ test_refcnt_mbuf(void)
 
 #ifdef RTE_EXEC_ENV_WINDOWS
 static int
-test_failing_mbuf_sanity_check(struct rte_mempool *pktmbuf_pool)
+test_failing_mbuf_verify(struct rte_mempool *pktmbuf_pool)
 {
 	RTE_SET_USED(pktmbuf_pool);
 	return TEST_SKIPPED;
@@ -1180,12 +1180,12 @@ mbuf_check_pass(struct rte_mbuf *buf)
 }
 
 static int
-test_failing_mbuf_sanity_check(struct rte_mempool *pktmbuf_pool)
+test_failing_mbuf_verify(struct rte_mempool *pktmbuf_pool)
 {
 	struct rte_mbuf *buf;
 	struct rte_mbuf badbuf;
 
-	printf("Checking rte_mbuf_sanity_check for failure conditions\n");
+	printf("Checking rte_mbuf_verify for failure conditions\n");
 
 	/* get a good mbuf to use to make copies */
 	buf = rte_pktmbuf_alloc(pktmbuf_pool);
@@ -1707,7 +1707,7 @@ test_mbuf_validate_tx_offload(const char *test_name,
 		GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("%s: Bad packet length\n", __func__);
-	rte_mbuf_sanity_check(m, 0);
+	rte_mbuf_verify(m, 0);
 	m->ol_flags = ol_flags;
 	m->tso_segsz = segsize;
 	ret = rte_validate_tx_offload(m);
@@ -1914,7 +1914,7 @@ test_pktmbuf_read(struct rte_mempool *pktmbuf_pool)
 		GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("%s: Bad packet length\n", __func__);
-	rte_mbuf_sanity_check(m, 0);
+	rte_mbuf_verify(m, 0);
 
 	data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN2);
 	if (data == NULL)
@@ -1963,7 +1963,7 @@ test_pktmbuf_read_from_offset(struct rte_mempool *pktmbuf_pool)
 
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("%s: Bad packet length\n", __func__);
-	rte_mbuf_sanity_check(m, 0);
+	rte_mbuf_verify(m, 0);
 
 	/* prepend an ethernet header */
 	hdr = (struct ether_hdr *)rte_pktmbuf_prepend(m, hdr_len);
@@ -2108,7 +2108,7 @@ create_packet(struct rte_mempool *pktmbuf_pool,
 			GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
 		if (rte_pktmbuf_pkt_len(pkt_seg) != 0)
 			GOTO_FAIL("%s: Bad packet length\n", __func__);
-		rte_mbuf_sanity_check(pkt_seg, 0);
+		rte_mbuf_verify(pkt_seg, 0);
 		/* Add header only for the first segment */
 		if (test_data->flags == MBUF_HEADER && seg == 0) {
 			hdr_len = sizeof(struct rte_ether_hdr);
@@ -2320,7 +2320,7 @@ test_pktmbuf_ext_shinfo_init_helper(struct rte_mempool *pktmbuf_pool)
 		GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("%s: Bad packet length\n", __func__);
-	rte_mbuf_sanity_check(m, 0);
+	rte_mbuf_verify(m, 0);
 
 	ext_buf_addr = rte_malloc("External buffer", buf_len,
 			RTE_CACHE_LINE_SIZE);
@@ -2484,8 +2484,8 @@ test_pktmbuf_ext_pinned_buffer(struct rte_mempool *std_pool)
 		GOTO_FAIL("%s: test_pktmbuf_copy(pinned) failed\n",
 			  __func__);
 
-	if (test_failing_mbuf_sanity_check(pinned_pool) < 0)
-		GOTO_FAIL("%s: test_failing_mbuf_sanity_check(pinned)"
+	if (test_failing_mbuf_verify(pinned_pool) < 0)
+		GOTO_FAIL("%s: test_failing_mbuf_verify(pinned)"
 			  " failed\n", __func__);
 
 	if (test_mbuf_linearize_check(pinned_pool) < 0)
@@ -2859,8 +2859,8 @@ test_mbuf(void)
 		goto err;
 	}
 
-	if (test_failing_mbuf_sanity_check(pktmbuf_pool) < 0) {
-		printf("test_failing_mbuf_sanity_check() failed\n");
+	if (test_failing_mbuf_verify(pktmbuf_pool) < 0) {
+		printf("test_failing_mbuf_verify() failed\n");
 		goto err;
 	}
 
diff --git a/doc/guides/prog_guide/mbuf_lib.rst b/doc/guides/prog_guide/mbuf_lib.rst
index 049357c75563..0accb51a98c7 100644
--- a/doc/guides/prog_guide/mbuf_lib.rst
+++ b/doc/guides/prog_guide/mbuf_lib.rst
@@ -266,8 +266,8 @@ can be found in several of the sample applications, for example, the IPv4 Multic
 Debug
 -----
 
-In debug mode, the functions of the mbuf library perform sanity checks before any operation (such as, buffer corruption,
-bad type, and so on).
+In debug mode, the functions of the mbuf library perform consistency checks
+before any operation (such as, buffer corruption, bad type, and so on).
 
 Use Cases
 ---------
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 81b93515cbd9..1e1544b5b644 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -146,3 +146,6 @@ Deprecation Notices
   will be deprecated and subsequently removed in DPDK 24.11 release.
   Before this, the new port library API (functions rte_swx_port_*)
   will gradually transition from experimental to stable status.
+
+* mbuf: The function ``rte_mbuf_sanity_check`` is deprecated.
+  Use the new function ``rte_mbuf_verify`` instead.
diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c
index 53d9e38c939b..ae76fad84948 100644
--- a/drivers/net/avp/avp_ethdev.c
+++ b/drivers/net/avp/avp_ethdev.c
@@ -1231,7 +1231,7 @@ _avp_mac_filter(struct avp_dev *avp, struct rte_mbuf *m)
 
 #ifdef RTE_LIBRTE_AVP_DEBUG_BUFFERS
 static inline void
-__avp_dev_buffer_sanity_check(struct avp_dev *avp, struct rte_avp_desc *buf)
+__avp_dev_buffer_check(struct avp_dev *avp, struct rte_avp_desc *buf)
 {
 	struct rte_avp_desc *first_buf;
 	struct rte_avp_desc *pkt_buf;
@@ -1272,12 +1272,12 @@ __avp_dev_buffer_sanity_check(struct avp_dev *avp, struct rte_avp_desc *buf)
 			  first_buf->pkt_len, pkt_len);
 }
 
-#define avp_dev_buffer_sanity_check(a, b) \
-	__avp_dev_buffer_sanity_check((a), (b))
+#define avp_dev_buffer_check(a, b) \
+	__avp_dev_buffer_check((a), (b))
 
 #else /* RTE_LIBRTE_AVP_DEBUG_BUFFERS */
 
-#define avp_dev_buffer_sanity_check(a, b) do {} while (0)
+#define avp_dev_buffer_check(a, b) do {} while (0)
 
 #endif
 
@@ -1302,7 +1302,7 @@ avp_dev_copy_from_buffers(struct avp_dev *avp,
 	void *pkt_data;
 	unsigned int i;
 
-	avp_dev_buffer_sanity_check(avp, buf);
+	avp_dev_buffer_check(avp, buf);
 
 	/* setup the first source buffer */
 	pkt_buf = avp_dev_translate_buffer(avp, buf);
@@ -1370,7 +1370,7 @@ avp_dev_copy_from_buffers(struct avp_dev *avp,
 	rte_pktmbuf_pkt_len(m) = total_length;
 	m->vlan_tci = vlan_tci;
 
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	return m;
 }
@@ -1614,7 +1614,7 @@ avp_dev_copy_to_buffers(struct avp_dev *avp,
 	char *pkt_data;
 	unsigned int i;
 
-	__rte_mbuf_sanity_check(mbuf, 1);
+	__rte_mbuf_verify(mbuf, 1);
 
 	m = mbuf;
 	src_offset = 0;
@@ -1680,7 +1680,7 @@ avp_dev_copy_to_buffers(struct avp_dev *avp,
 		first_buf->vlan_tci = mbuf->vlan_tci;
 	}
 
-	avp_dev_buffer_sanity_check(avp, buffers[0]);
+	avp_dev_buffer_check(avp, buffers[0]);
 
 	return total_length;
 }
@@ -1798,7 +1798,7 @@ avp_xmit_scattered_pkts(void *tx_queue,
 
 #ifdef RTE_LIBRTE_AVP_DEBUG_BUFFERS
 	for (i = 0; i < nb_pkts; i++)
-		avp_dev_buffer_sanity_check(avp, tx_bufs[i]);
+		avp_dev_buffer_check(avp, tx_bufs[i]);
 #endif
 
 	/* send the packets */
diff --git a/drivers/net/sfc/sfc_ef100_rx.c b/drivers/net/sfc/sfc_ef100_rx.c
index 2677003da326..8199b56f2740 100644
--- a/drivers/net/sfc/sfc_ef100_rx.c
+++ b/drivers/net/sfc/sfc_ef100_rx.c
@@ -179,7 +179,7 @@ sfc_ef100_rx_qrefill(struct sfc_ef100_rxq *rxq)
 			struct sfc_ef100_rx_sw_desc *rxd;
 			rte_iova_t dma_addr;
 
-			__rte_mbuf_raw_sanity_check(m);
+			__rte_mbuf_raw_verify(m);
 
 			dma_addr = rte_mbuf_data_iova_default(m);
 			if (rxq->flags & SFC_EF100_RXQ_NIC_DMA_MAP) {
@@ -551,7 +551,7 @@ sfc_ef100_rx_process_ready_pkts(struct sfc_ef100_rxq *rxq,
 		rxq->ready_pkts--;
 
 		pkt = sfc_ef100_rx_next_mbuf(rxq);
-		__rte_mbuf_raw_sanity_check(pkt);
+		__rte_mbuf_raw_verify(pkt);
 
 		RTE_BUILD_BUG_ON(sizeof(pkt->rearm_data[0]) !=
 				 sizeof(rxq->rearm_data));
@@ -575,7 +575,7 @@ sfc_ef100_rx_process_ready_pkts(struct sfc_ef100_rxq *rxq,
 			struct rte_mbuf *seg;
 
 			seg = sfc_ef100_rx_next_mbuf(rxq);
-			__rte_mbuf_raw_sanity_check(seg);
+			__rte_mbuf_raw_verify(seg);
 
 			seg->data_off = RTE_PKTMBUF_HEADROOM;
 
diff --git a/drivers/net/sfc/sfc_ef10_essb_rx.c b/drivers/net/sfc/sfc_ef10_essb_rx.c
index 78bd430363b1..74647e2792b1 100644
--- a/drivers/net/sfc/sfc_ef10_essb_rx.c
+++ b/drivers/net/sfc/sfc_ef10_essb_rx.c
@@ -125,7 +125,7 @@ sfc_ef10_essb_next_mbuf(const struct sfc_ef10_essb_rxq *rxq,
 	struct rte_mbuf *m;
 
 	m = (struct rte_mbuf *)((uintptr_t)mbuf + rxq->buf_stride);
-	__rte_mbuf_raw_sanity_check(m);
+	__rte_mbuf_raw_verify(m);
 	return m;
 }
 
@@ -136,7 +136,7 @@ sfc_ef10_essb_mbuf_by_index(const struct sfc_ef10_essb_rxq *rxq,
 	struct rte_mbuf *m;
 
 	m = (struct rte_mbuf *)((uintptr_t)mbuf + idx * rxq->buf_stride);
-	__rte_mbuf_raw_sanity_check(m);
+	__rte_mbuf_raw_verify(m);
 	return m;
 }
 
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 30a320d0791c..72b03b3bba7a 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -148,7 +148,7 @@ sfc_ef10_rx_qrefill(struct sfc_ef10_rxq *rxq)
 			struct sfc_ef10_rx_sw_desc *rxd;
 			rte_iova_t phys_addr;
 
-			__rte_mbuf_raw_sanity_check(m);
+			__rte_mbuf_raw_verify(m);
 
 			SFC_ASSERT((id & ~ptr_mask) == 0);
 			rxd = &rxq->sw_ring[id];
@@ -297,7 +297,7 @@ sfc_ef10_rx_process_event(struct sfc_ef10_rxq *rxq, efx_qword_t rx_ev,
 		rxd = &rxq->sw_ring[pending++ & ptr_mask];
 		m = rxd->mbuf;
 
-		__rte_mbuf_raw_sanity_check(m);
+		__rte_mbuf_raw_verify(m);
 
 		m->data_off = RTE_PKTMBUF_HEADROOM;
 		rte_pktmbuf_data_len(m) = seg_len;
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 1dde2c111001..645c8643d1c1 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -120,7 +120,7 @@ sfc_efx_rx_qrefill(struct sfc_efx_rxq *rxq)
 		     ++i, id = (id + 1) & rxq->ptr_mask) {
 			m = objs[i];
 
-			__rte_mbuf_raw_sanity_check(m);
+			__rte_mbuf_raw_verify(m);
 
 			rxd = &rxq->sw_desc[id];
 			rxd->mbuf = m;
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 6d0a8501eff5..f39658f4e249 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -258,7 +258,7 @@ mcast_out_pkt(struct rte_mbuf *pkt, int use_clone)
 	hdr->pkt_len = (uint16_t)(hdr->data_len + pkt->pkt_len);
 	hdr->nb_segs = pkt->nb_segs + 1;
 
-	__rte_mbuf_sanity_check(hdr, 1);
+	__rte_mbuf_verify(hdr, 1);
 	return hdr;
 }
 /* >8 End of mcast_out_kt. */
diff --git a/lib/mbuf/rte_mbuf.c b/lib/mbuf/rte_mbuf.c
index 559d5ad8a71c..fc5d4ba29db1 100644
--- a/lib/mbuf/rte_mbuf.c
+++ b/lib/mbuf/rte_mbuf.c
@@ -367,9 +367,9 @@ rte_pktmbuf_pool_create_extbuf(const char *name, unsigned int n,
 	return mp;
 }
 
-/* do some sanity checks on a mbuf: panic if it fails */
+/* do some checks on a mbuf: panic if it fails */
 void
-rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
+rte_mbuf_verify(const struct rte_mbuf *m, int is_header)
 {
 	const char *reason;
 
@@ -377,6 +377,13 @@ rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
 		rte_panic("%s\n", reason);
 }
 
+/* For ABI compatibility, to be removed in next release */
+void
+rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
+{
+	rte_mbuf_verify(m, is_header);
+}
+
 int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
 		   const char **reason)
 {
@@ -496,7 +503,7 @@ void rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned int count)
 		if (unlikely(m == NULL))
 			continue;
 
-		__rte_mbuf_sanity_check(m, 1);
+		__rte_mbuf_verify(m, 1);
 
 		do {
 			m_next = m->next;
@@ -546,7 +553,7 @@ rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp)
 		return NULL;
 	}
 
-	__rte_mbuf_sanity_check(mc, 1);
+	__rte_mbuf_verify(mc, 1);
 	return mc;
 }
 
@@ -596,7 +603,7 @@ rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp,
 	struct rte_mbuf *mc, *m_last, **prev;
 
 	/* garbage in check */
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	/* check for request to copy at offset past end of mbuf */
 	if (unlikely(off >= m->pkt_len))
@@ -660,7 +667,7 @@ rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp,
 	}
 
 	/* garbage out check */
-	__rte_mbuf_sanity_check(mc, 1);
+	__rte_mbuf_verify(mc, 1);
 	return mc;
 }
 
@@ -671,7 +678,7 @@ rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len)
 	unsigned int len;
 	unsigned int nb_segs;
 
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	fprintf(f, "dump mbuf at %p, iova=%#" PRIx64 ", buf_len=%u\n", m, rte_mbuf_iova_get(m),
 		m->buf_len);
@@ -689,7 +696,7 @@ rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len)
 	nb_segs = m->nb_segs;
 
 	while (m && nb_segs != 0) {
-		__rte_mbuf_sanity_check(m, 0);
+		__rte_mbuf_verify(m, 0);
 
 		fprintf(f, "  segment at %p, data=%p, len=%u, off=%u, refcnt=%u\n",
 			m, rte_pktmbuf_mtod(m, void *),
diff --git a/lib/mbuf/rte_mbuf.h b/lib/mbuf/rte_mbuf.h
index 286b32b788a5..380663a0893b 100644
--- a/lib/mbuf/rte_mbuf.h
+++ b/lib/mbuf/rte_mbuf.h
@@ -339,13 +339,13 @@ rte_pktmbuf_priv_flags(struct rte_mempool *mp)
 
 #ifdef RTE_LIBRTE_MBUF_DEBUG
 
-/**  check mbuf type in debug mode */
-#define __rte_mbuf_sanity_check(m, is_h) rte_mbuf_sanity_check(m, is_h)
+/**  do mbuf type in debug mode */
+#define __rte_mbuf_verify(m, is_h) rte_mbuf_verify(m, is_h)
 
 #else /*  RTE_LIBRTE_MBUF_DEBUG */
 
-/**  check mbuf type in debug mode */
-#define __rte_mbuf_sanity_check(m, is_h) do { } while (0)
+/**  ignore mbuf checks if not in debug mode */
+#define __rte_mbuf_verify(m, is_h) do { } while (0)
 
 #endif /*  RTE_LIBRTE_MBUF_DEBUG */
 
@@ -514,10 +514,9 @@ rte_mbuf_ext_refcnt_update(struct rte_mbuf_ext_shared_info *shinfo,
 
 
 /**
- * Sanity checks on an mbuf.
+ * Check that the mbuf is valid and panic if corrupted.
  *
- * Check the consistency of the given mbuf. The function will cause a
- * panic if corruption is detected.
+ * Acts assertion that mbuf is consistent. If not it calls rte_panic().
  *
  * @param m
  *   The mbuf to be checked.
@@ -526,13 +525,17 @@ rte_mbuf_ext_refcnt_update(struct rte_mbuf_ext_shared_info *shinfo,
  *   of a packet (in this case, some fields like nb_segs are not checked)
  */
 void
+rte_mbuf_verify(const struct rte_mbuf *m, int is_header);
+
+/* Older deprecated name for rte_mbuf_verify() */
+void __rte_deprecated
 rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header);
 
 /**
- * Sanity checks on a mbuf.
+ * Do consistency checks on a mbuf.
  *
- * Almost like rte_mbuf_sanity_check(), but this function gives the reason
- * if corruption is detected rather than panic.
+ * Check the consistency of the given mbuf and if not valid
+ * return the reason.
  *
  * @param m
  *   The mbuf to be checked.
@@ -551,7 +554,7 @@ int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
 		   const char **reason);
 
 /**
- * Sanity checks on a reinitialized mbuf in debug mode.
+ * Do checks on a reinitialized mbuf in debug mode.
  *
  * Check the consistency of the given reinitialized mbuf.
  * The function will cause a panic if corruption is detected.
@@ -563,16 +566,16 @@ int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
  *   The mbuf to be checked.
  */
 static __rte_always_inline void
-__rte_mbuf_raw_sanity_check(__rte_unused const struct rte_mbuf *m)
+__rte_mbuf_raw_verify(__rte_unused const struct rte_mbuf *m)
 {
 	RTE_ASSERT(rte_mbuf_refcnt_read(m) == 1);
 	RTE_ASSERT(m->next == NULL);
 	RTE_ASSERT(m->nb_segs == 1);
-	__rte_mbuf_sanity_check(m, 0);
+	__rte_mbuf_verify(m, 0);
 }
 
 /** For backwards compatibility. */
-#define MBUF_RAW_ALLOC_CHECK(m) __rte_mbuf_raw_sanity_check(m)
+#define MBUF_RAW_ALLOC_CHECK(m) __rte_mbuf_raw_verify(m)
 
 /**
  * Allocate an uninitialized mbuf from mempool *mp*.
@@ -599,7 +602,7 @@ static inline struct rte_mbuf *rte_mbuf_raw_alloc(struct rte_mempool *mp)
 
 	if (rte_mempool_get(mp, (void **)&m) < 0)
 		return NULL;
-	__rte_mbuf_raw_sanity_check(m);
+	__rte_mbuf_raw_verify(m);
 	return m;
 }
 
@@ -622,7 +625,7 @@ rte_mbuf_raw_free(struct rte_mbuf *m)
 {
 	RTE_ASSERT(!RTE_MBUF_CLONED(m) &&
 		  (!RTE_MBUF_HAS_EXTBUF(m) || RTE_MBUF_HAS_PINNED_EXTBUF(m)));
-	__rte_mbuf_raw_sanity_check(m);
+	__rte_mbuf_raw_verify(m);
 	rte_mempool_put(m->pool, m);
 }
 
@@ -885,7 +888,7 @@ static inline void rte_pktmbuf_reset(struct rte_mbuf *m)
 	rte_pktmbuf_reset_headroom(m);
 
 	m->data_len = 0;
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 }
 
 /**
@@ -941,22 +944,22 @@ static inline int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool,
 	switch (count % 4) {
 	case 0:
 		while (idx != count) {
-			__rte_mbuf_raw_sanity_check(mbufs[idx]);
+			__rte_mbuf_raw_verify(mbufs[idx]);
 			rte_pktmbuf_reset(mbufs[idx]);
 			idx++;
 			/* fall-through */
 	case 3:
-			__rte_mbuf_raw_sanity_check(mbufs[idx]);
+			__rte_mbuf_raw_verify(mbufs[idx]);
 			rte_pktmbuf_reset(mbufs[idx]);
 			idx++;
 			/* fall-through */
 	case 2:
-			__rte_mbuf_raw_sanity_check(mbufs[idx]);
+			__rte_mbuf_raw_verify(mbufs[idx]);
 			rte_pktmbuf_reset(mbufs[idx]);
 			idx++;
 			/* fall-through */
 	case 1:
-			__rte_mbuf_raw_sanity_check(mbufs[idx]);
+			__rte_mbuf_raw_verify(mbufs[idx]);
 			rte_pktmbuf_reset(mbufs[idx]);
 			idx++;
 			/* fall-through */
@@ -1184,8 +1187,8 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
 	mi->pkt_len = mi->data_len;
 	mi->nb_segs = 1;
 
-	__rte_mbuf_sanity_check(mi, 1);
-	__rte_mbuf_sanity_check(m, 0);
+	__rte_mbuf_verify(mi, 1);
+	__rte_mbuf_verify(m, 0);
 }
 
 /**
@@ -1340,7 +1343,7 @@ static inline int __rte_pktmbuf_pinned_extbuf_decref(struct rte_mbuf *m)
 static __rte_always_inline struct rte_mbuf *
 rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
 {
-	__rte_mbuf_sanity_check(m, 0);
+	__rte_mbuf_verify(m, 0);
 
 	if (likely(rte_mbuf_refcnt_read(m) == 1)) {
 
@@ -1411,7 +1414,7 @@ static inline void rte_pktmbuf_free(struct rte_mbuf *m)
 	struct rte_mbuf *m_next;
 
 	if (m != NULL)
-		__rte_mbuf_sanity_check(m, 1);
+		__rte_mbuf_verify(m, 1);
 
 	while (m != NULL) {
 		m_next = m->next;
@@ -1492,7 +1495,7 @@ rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp,
  */
 static inline void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
 {
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	do {
 		rte_mbuf_refcnt_update(m, v);
@@ -1509,7 +1512,7 @@ static inline void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
  */
 static inline uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
 {
-	__rte_mbuf_sanity_check(m, 0);
+	__rte_mbuf_verify(m, 0);
 	return m->data_off;
 }
 
@@ -1523,7 +1526,7 @@ static inline uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
  */
 static inline uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
 {
-	__rte_mbuf_sanity_check(m, 0);
+	__rte_mbuf_verify(m, 0);
 	return (uint16_t)(m->buf_len - rte_pktmbuf_headroom(m) -
 			  m->data_len);
 }
@@ -1538,7 +1541,7 @@ static inline uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
  */
 static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
 {
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 	while (m->next != NULL)
 		m = m->next;
 	return m;
@@ -1582,7 +1585,7 @@ static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
 static inline char *rte_pktmbuf_prepend(struct rte_mbuf *m,
 					uint16_t len)
 {
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	if (unlikely(len > rte_pktmbuf_headroom(m)))
 		return NULL;
@@ -1617,7 +1620,7 @@ static inline char *rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
 	void *tail;
 	struct rte_mbuf *m_last;
 
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	m_last = rte_pktmbuf_lastseg(m);
 	if (unlikely(len > rte_pktmbuf_tailroom(m_last)))
@@ -1645,7 +1648,7 @@ static inline char *rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
  */
 static inline char *rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
 {
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	if (unlikely(len > m->data_len))
 		return NULL;
@@ -1677,7 +1680,7 @@ static inline int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
 {
 	struct rte_mbuf *m_last;
 
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	m_last = rte_pktmbuf_lastseg(m);
 	if (unlikely(len > m_last->data_len))
@@ -1699,7 +1702,7 @@ static inline int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
  */
 static inline int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
 {
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 	return m->nb_segs == 1;
 }
 
diff --git a/lib/mbuf/version.map b/lib/mbuf/version.map
index daa65e2bbdb2..c85370e430b2 100644
--- a/lib/mbuf/version.map
+++ b/lib/mbuf/version.map
@@ -31,6 +31,7 @@ DPDK_24 {
 	rte_mbuf_set_platform_mempool_ops;
 	rte_mbuf_set_user_mempool_ops;
 	rte_mbuf_user_mempool_ops;
+	rte_mbuf_verify;
 	rte_pktmbuf_clone;
 	rte_pktmbuf_copy;
 	rte_pktmbuf_dump;
-- 
2.43.0


^ permalink raw reply	[relevance 2%]

* RE: [PATCH v6 1/3] ethdev: rename action modify field data structure
  2024-02-05 11:23  0%     ` Thomas Monjalon
@ 2024-02-05 11:49  0%       ` Suanming Mou
  0 siblings, 0 replies; 200+ results
From: Suanming Mou @ 2024-02-05 11:49 UTC (permalink / raw)
  To: NBU-Contact-Thomas Monjalon (EXTERNAL)
  Cc: ferruh.yigit, Ori Kam, Aman Singh, Yuying Zhang,
	Dariusz Sosnowski, Slava Ovsiienko, Matan Azrad,
	Andrew Rybchenko, dev

Hi Thomas,

> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Monday, February 5, 2024 7:23 PM
> To: Suanming Mou <suanmingm@nvidia.com>
> Cc: ferruh.yigit@amd.com; Ori Kam <orika@nvidia.com>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>; Dariusz
> Sosnowski <dsosnowski@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Matan Azrad <matan@nvidia.com>; Andrew
> Rybchenko <andrew.rybchenko@oktetlabs.ru>; dev@dpdk.org
> Subject: Re: [PATCH v6 1/3] ethdev: rename action modify field data structure
> 
> 02/02/2024 01:42, Suanming Mou:
> > --- a/doc/guides/rel_notes/release_24_03.rst
> > +++ b/doc/guides/rel_notes/release_24_03.rst
> > @@ -124,6 +124,8 @@ ABI Changes
> >
> >  * No ABI change that would break compatibility with 23.11.
> >
> > +* ethdev: Rename the experimental ``struct
> > +rte_flow_action_modify_data`` to be ``struct rte_flow_field_data``
> 
> It should be in API change section.
> Please us past tense as recommened in comments in the file.
OK.

> 
> > --- a/lib/ethdev/rte_flow.h
> > +++ b/lib/ethdev/rte_flow.h
> > @@ -3894,6 +3894,7 @@ struct rte_flow_action_ethdev {
> >
> >  /**
> >   * Field IDs for MODIFY_FIELD action.
> > + * e.g. the packet field IDs used in RTE_FLOW_ACTION_TYPE_MODIFY_FIELD.
> 
> Better to give the full name in the first line, so no need to add a second line of
> comment.

So maybe " Field IDs for packet field, used by RTE_FLOW_ACTION_TYPE_MODIFY_FIELD."?
But when COMPARE item to be added. It will be " Field IDs for packet field, used by RTE_FLOW_ACTION_TYPE_MODIFY_FIELD and RTE_FLOW_ITEM_TYPE_COMPARE."  And I assume that will still need a second line since it is too long.

> 
> [...]
> > - * Field description for MODIFY_FIELD action.
> > + * Field description for packet field.
> > + * e.g. the packet fields used in RTE_FLOW_ACTION_TYPE_MODIFY_FIELD.
> 
> Same here, can be one simple line with full name.
> 
> 


^ permalink raw reply	[relevance 0%]

* Re: [PATCH v6 1/3] ethdev: rename action modify field data structure
  2024-02-02  0:42  7%   ` [PATCH v6 1/3] ethdev: rename action modify field data structure Suanming Mou
@ 2024-02-05 11:23  0%     ` Thomas Monjalon
  2024-02-05 11:49  0%       ` Suanming Mou
  0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2024-02-05 11:23 UTC (permalink / raw)
  To: Suanming Mou
  Cc: ferruh.yigit, Ori Kam, Aman Singh, Yuying Zhang,
	Dariusz Sosnowski, Viacheslav Ovsiienko, Matan Azrad,
	Andrew Rybchenko, dev

02/02/2024 01:42, Suanming Mou:
> --- a/doc/guides/rel_notes/release_24_03.rst
> +++ b/doc/guides/rel_notes/release_24_03.rst
> @@ -124,6 +124,8 @@ ABI Changes
>  
>  * No ABI change that would break compatibility with 23.11.
>  
> +* ethdev: Rename the experimental ``struct rte_flow_action_modify_data`` to be ``struct rte_flow_field_data``

It should be in API change section.
Please us past tense as recommened in comments in the file.

> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -3894,6 +3894,7 @@ struct rte_flow_action_ethdev {
>  
>  /**
>   * Field IDs for MODIFY_FIELD action.
> + * e.g. the packet field IDs used in RTE_FLOW_ACTION_TYPE_MODIFY_FIELD.

Better to give the full name in the first line,
so no need to add a second line of comment.

[...]
> - * Field description for MODIFY_FIELD action.
> + * Field description for packet field.
> + * e.g. the packet fields used in RTE_FLOW_ACTION_TYPE_MODIFY_FIELD.

Same here, can be one simple line with full name.




^ permalink raw reply	[relevance 0%]

* [PATCH v2 1/7] ethdev: support report register names and filter
  @ 2024-02-05 10:51  8%   ` Jie Hai
  2024-02-07 17:00  3%     ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Jie Hai @ 2024-02-05 10:51 UTC (permalink / raw)
  To: dev; +Cc: lihuisong, fengchengwen, liuyonglong, huangdengdui, ferruh.yigit

This patch adds "filter" and "names" fields to "rte_dev_reg_info"
structure. Names of registers in data fields can be reported and
the registers can be filtered by their names.

For compatibility, the original API rte_eth_dev_get_reg_info()
does not use the name and filter fields. The new API
rte_eth_dev_get_reg_info_ext() is added to support reporting
names and filtering by names. If the drivers does not report
the names, set them to "offset_XXX".

Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 doc/guides/rel_notes/release_24_03.rst |  8 ++++++
 lib/ethdev/rte_dev_info.h              | 11 ++++++++
 lib/ethdev/rte_ethdev.c                | 36 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 22 ++++++++++++++++
 4 files changed, 77 insertions(+)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 84d3144215c6..5d402341223a 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -75,6 +75,11 @@ New Features
   * Added support for Atomic Rules' TK242 packet-capture family of devices
     with PCI IDs: ``0x1024, 0x1025, 0x1026``.
 
+* **Added support for dumping regiters with names and filter.**
+
+  * Added new API functions ``rte_eth_dev_get_reg_info_ext()`` to and filter
+  * the registers by their names and get the information of registers(names,
+  * values and other attributes).
 
 Removed Items
 -------------
@@ -124,6 +129,9 @@ ABI Changes
 
 * No ABI change that would break compatibility with 23.11.
 
+* ethdev: Added ``filter`` and ``names`` fields to ``rte_dev_reg_info``
+  structure for reporting names of regiters and filtering them by names.
+
 
 Known Issues
 ------------
diff --git a/lib/ethdev/rte_dev_info.h b/lib/ethdev/rte_dev_info.h
index 67cf0ae52668..2f4541bd46c8 100644
--- a/lib/ethdev/rte_dev_info.h
+++ b/lib/ethdev/rte_dev_info.h
@@ -11,6 +11,11 @@ extern "C" {
 
 #include <stdint.h>
 
+#define RTE_ETH_REG_NAME_SIZE 128
+struct rte_eth_reg_name {
+	char name[RTE_ETH_REG_NAME_SIZE];
+};
+
 /*
  * Placeholder for accessing device registers
  */
@@ -20,6 +25,12 @@ struct rte_dev_reg_info {
 	uint32_t length; /**< Number of registers to fetch */
 	uint32_t width; /**< Size of device register */
 	uint32_t version; /**< Device version */
+	/**
+	 * Filter for target subset of registers.
+	 * This field could affects register selection for data/length/names.
+	 */
+	char *filter;
+	struct rte_eth_reg_name *names; /**< Registers name saver */
 };
 
 /*
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f1c658f49e80..3e0294e49092 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6388,8 +6388,39 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 
 int
 rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
+{
+	struct rte_dev_reg_info reg_info;
+	int ret;
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR,
+			"Cannot get ethdev port %u register info to NULL",
+			port_id);
+		return -EINVAL;
+	}
+
+	reg_info.length = info->length;
+	reg_info.data = info->data;
+	reg_info.names = NULL;
+	reg_info.filter = NULL;
+
+	ret = rte_eth_dev_get_reg_info_ext(port_id, &reg_info);
+	if (ret != 0)
+		return ret;
+
+	info->length = reg_info.length;
+	info->width = reg_info.width;
+	info->version = reg_info.version;
+	info->offset = reg_info.offset;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info)
 {
 	struct rte_eth_dev *dev;
+	uint32_t i;
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -6408,6 +6439,11 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 
 	rte_ethdev_trace_get_reg_info(port_id, info, ret);
 
+	/* Report the default names if drivers not report. */
+	if (info->names != NULL && strlen(info->names[0].name) == 0)
+		for (i = 0; i < info->length; i++)
+			sprintf(info->names[i].name, "offset_%x",
+				info->offset + i * info->width);
 	return ret;
 }
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 2687c23fa6fb..3abc2ad3f865 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5053,6 +5053,28 @@ __rte_experimental
 int rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 		struct rte_power_monitor_cond *pmc);
 
+/**
+ * Retrieve the filtered device registers (values and names) and
+ * register attributes (number of registers and register size)
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param info
+ *   Pointer to rte_dev_reg_info structure to fill in. If info->data is
+ *   NULL, the function fills in the width and length fields. If non-NULL,
+ *   the values of registers whose name contains the filter string are put
+ *   into the buffer pointed at by the data field. Do the same for the names
+ *   of registers if info->names is not NULL.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EIO) if device is removed.
+ *   - others depends on the specific operations implementation.
+ */
+int rte_eth_dev_get_reg_info_ext(uint16_t port_id, struct rte_dev_reg_info *info);
+
 /**
  * Retrieve device registers and register attributes (number of registers and
  * register size)
-- 
2.30.0


^ permalink raw reply	[relevance 8%]

* [PATCH v7 00/19] Replace uses of RTE_LOGTYPE_PMD
    2024-02-03  4:10  3% ` [PATCH v7 00/19] Replace use of PMD logtype Stephen Hemminger
@ 2024-02-03  4:11  3% ` Stephen Hemminger
  1 sibling, 0 replies; 200+ results
From: Stephen Hemminger @ 2024-02-03  4:11 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Many of the uses of PMD logtype have already been fixed.
But there are still some leftovers, mostly places where
drivers had a logtype but did not use them.

Note: this is not an ABI break, but could break out of
      tree drivers that never updated to use dynamic logtype.
      DPDK never guaranteed that that would not happen.

v7 - drop changes to newlines
     drop changes related to RTE_LOG_DP
     rebase now that other stuff has changed

Stephen Hemminger (19):
  common/sfc_efx: remove use of PMD logtype
  mempool/dpaa2: use driver logtype not PMD
  net/dpaa: use dedicated logtype not PMD
  net/dpaa2: used dedicated logtype not PMD
  net/mrvl: do not use PMD logtype
  net/mvpp2: use dedicated logtype
  net/nfb: use dynamic logtype
  net/vmxnet3: used dedicated logtype not PMD
  raw/cnxk: replace PMD logtype with dynamic type
  crypto/scheduler: replace use of logtype PMD
  crypto/armv8: do not use PMD logtype
  crypto/caam_jr: use dedicated logtype
  crypto/ccp: do not use PMD logtype
  crypto/dpaa_sec, crypto/dpaa2_sec: use dedicated logtype
  event/dpaa, event/dpaa2: use dedicated logtype
  event/dlb2: use dedicated logtype
  event/skeleton: replace logtype PMD with dynamic type
  examples/fips_validation: replace use of PMD logtype
  log: remove PMD log type

 drivers/common/cnxk/roc_platform.h            | 16 ++++---
 drivers/common/sfc_efx/sfc_efx.c              | 11 +----
 drivers/common/sfc_efx/sfc_efx_log.h          |  2 +-
 drivers/crypto/armv8/rte_armv8_pmd.c          |  4 +-
 drivers/crypto/caam_jr/caam_jr.c              |  5 +--
 drivers/crypto/ccp/rte_ccp_pmd.c              | 11 +++--
 drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c   |  6 +--
 drivers/crypto/dpaa_sec/dpaa_sec.c            | 30 ++++++-------
 drivers/crypto/scheduler/scheduler_pmd.c      |  4 +-
 drivers/event/dlb2/dlb2.c                     |  5 +--
 drivers/event/dpaa/dpaa_eventdev.c            |  2 +-
 drivers/event/dpaa2/dpaa2_eventdev.c          |  4 +-
 drivers/event/dpaa2/dpaa2_eventdev_selftest.c |  6 +--
 drivers/event/skeleton/skeleton_eventdev.c    |  4 +-
 drivers/event/skeleton/skeleton_eventdev.h    |  8 +++-
 drivers/mempool/dpaa2/dpaa2_hw_mempool.c      |  4 +-
 drivers/net/dpaa/dpaa_ethdev.c                |  6 +--
 drivers/net/dpaa2/dpaa2_ethdev.c              |  2 +-
 drivers/net/dpaa2/dpaa2_sparser.c             |  4 +-
 drivers/net/mvpp2/mrvl_ethdev.c               |  7 ++-
 drivers/net/nfb/nfb.h                         |  5 +++
 drivers/net/nfb/nfb_ethdev.c                  | 20 ++++-----
 drivers/net/nfb/nfb_rx.c                      | 10 ++---
 drivers/net/nfb/nfb_rx.h                      |  2 +-
 drivers/net/nfb/nfb_tx.c                      | 10 ++---
 drivers/net/nfb/nfb_tx.h                      |  2 +-
 drivers/net/vmxnet3/vmxnet3_ethdev.c          |  2 +-
 drivers/raw/cnxk_bphy/cnxk_bphy.c             |  3 +-
 drivers/raw/cnxk_bphy/cnxk_bphy_cgx.c         |  2 +-
 drivers/raw/cnxk_bphy/cnxk_bphy_cgx_test.c    | 31 +++++++------
 drivers/raw/cnxk_bphy/rte_pmd_bphy.h          |  6 +++
 drivers/raw/cnxk_gpio/cnxk_gpio.c             | 21 ++++-----
 drivers/raw/cnxk_gpio/cnxk_gpio.h             |  5 +++
 drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c    | 17 ++++---
 examples/fips_validation/fips_dev_self_test.c | 44 +++++++++----------
 lib/log/log.c                                 |  2 +-
 lib/log/rte_log.h                             |  2 +-
 37 files changed, 166 insertions(+), 159 deletions(-)

-- 
2.43.0


^ permalink raw reply	[relevance 3%]

* [PATCH v7 00/19] Replace use of PMD logtype
  @ 2024-02-03  4:10  3% ` Stephen Hemminger
  2024-02-12 14:45  0%   ` David Marchand
  2024-02-03  4:11  3% ` [PATCH v7 00/19] Replace uses of RTE_LOGTYPE_PMD Stephen Hemminger
  1 sibling, 1 reply; 200+ results
From: Stephen Hemminger @ 2024-02-03  4:10 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Many of the uses of PMD logtype have already been fixed.
But there are still some leftovers, mostly places where
drivers had a logtype but did not use them.

Note: this is not an ABI break, but could break out of
      tree drivers that never updated to use dynamic logtype.
      DPDK never guaranteed that that would not happen.

v7 - drop changes to newlines
     drop changes related to RTE_LOG_DP
     rebase now that other stuff has changed

Stephen Hemminger (19):
  common/sfc_efx: remove use of PMD logtype
  mempool/dpaa2: use driver logtype not PMD
  net/dpaa: use dedicated logtype not PMD
  net/dpaa2: used dedicated logtype not PMD
  net/mrvl: do not use PMD logtype
  net/mvpp2: use dedicated logtype
  net/nfb: use dynamic logtype
  net/vmxnet3: used dedicated logtype not PMD
  raw/cnxk: replace PMD logtype with dynamic type
  crypto/scheduler: replace use of logtype PMD
  crypto/armv8: do not use PMD logtype
  crypto/caam_jr: use dedicated logtype
  crypto/ccp: do not use PMD logtype
  crypto/dpaa_sec, crypto/dpaa2_sec: use dedicated logtype
  event/dpaa, event/dpaa2: use dedicated logtype
  event/dlb2: use dedicated logtype
  event/skeleton: replace logtype PMD with dynamic type
  examples/fips_validation: replace use of PMD logtype
  log: remove PMD log type

 drivers/common/cnxk/roc_platform.h            | 16 ++++---
 drivers/common/sfc_efx/sfc_efx.c              | 11 +----
 drivers/common/sfc_efx/sfc_efx_log.h          |  2 +-
 drivers/crypto/armv8/rte_armv8_pmd.c          |  4 +-
 drivers/crypto/caam_jr/caam_jr.c              |  5 +--
 drivers/crypto/ccp/rte_ccp_pmd.c              | 11 +++--
 drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c   |  6 +--
 drivers/crypto/dpaa_sec/dpaa_sec.c            | 30 ++++++-------
 drivers/crypto/scheduler/scheduler_pmd.c      |  4 +-
 drivers/event/dlb2/dlb2.c                     |  5 +--
 drivers/event/dpaa/dpaa_eventdev.c            |  2 +-
 drivers/event/dpaa2/dpaa2_eventdev.c          |  4 +-
 drivers/event/dpaa2/dpaa2_eventdev_selftest.c |  6 +--
 drivers/event/skeleton/skeleton_eventdev.c    |  4 +-
 drivers/event/skeleton/skeleton_eventdev.h    |  8 +++-
 drivers/mempool/dpaa2/dpaa2_hw_mempool.c      |  4 +-
 drivers/net/dpaa/dpaa_ethdev.c                |  6 +--
 drivers/net/dpaa2/dpaa2_ethdev.c              |  2 +-
 drivers/net/dpaa2/dpaa2_sparser.c             |  4 +-
 drivers/net/mvpp2/mrvl_ethdev.c               |  7 ++-
 drivers/net/nfb/nfb.h                         |  5 +++
 drivers/net/nfb/nfb_ethdev.c                  | 20 ++++-----
 drivers/net/nfb/nfb_rx.c                      | 10 ++---
 drivers/net/nfb/nfb_rx.h                      |  2 +-
 drivers/net/nfb/nfb_tx.c                      | 10 ++---
 drivers/net/nfb/nfb_tx.h                      |  2 +-
 drivers/net/vmxnet3/vmxnet3_ethdev.c          |  2 +-
 drivers/raw/cnxk_bphy/cnxk_bphy.c             |  3 +-
 drivers/raw/cnxk_bphy/cnxk_bphy_cgx.c         |  2 +-
 drivers/raw/cnxk_bphy/cnxk_bphy_cgx_test.c    | 31 +++++++------
 drivers/raw/cnxk_bphy/rte_pmd_bphy.h          |  6 +++
 drivers/raw/cnxk_gpio/cnxk_gpio.c             | 21 ++++-----
 drivers/raw/cnxk_gpio/cnxk_gpio.h             |  5 +++
 drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c    | 17 ++++---
 examples/fips_validation/fips_dev_self_test.c | 44 +++++++++----------
 lib/log/log.c                                 |  2 +-
 lib/log/rte_log.h                             |  2 +-
 37 files changed, 166 insertions(+), 159 deletions(-)

-- 
2.43.0


^ permalink raw reply	[relevance 3%]

* Re: [PATCH v2 11/11] eventdev: RFC clarify docs on event object fields
  2024-02-01 16:59  0%       ` Bruce Richardson
@ 2024-02-02  9:38  0%         ` Mattias Rönnblom
  0 siblings, 0 replies; 200+ results
From: Mattias Rönnblom @ 2024-02-02  9:38 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, jerinj, mattias.ronnblom, abdullah.sevincer, sachin.saxena,
	hemant.agrawal, pbhagavatula, pravin.pathak

On 2024-02-01 17:59, Bruce Richardson wrote:
> On Wed, Jan 24, 2024 at 12:34:50PM +0100, Mattias Rönnblom wrote:
>> On 2024-01-19 18:43, Bruce Richardson wrote:
>>> Clarify the meaning of the NEW, FORWARD and RELEASE event types.
>>> For the fields in "rte_event" struct, enhance the comments on each to
>>> clarify the field's use, and whether it is preserved between enqueue and
>>> dequeue, and it's role, if any, in scheduling.
>>>
>>> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
>>> ---
>>>
>>> As with the previous patch, please review this patch to ensure that the
>>> expected semantics of the various event types and event fields have not
>>> changed in an unexpected way.
>>> ---
>>>    lib/eventdev/rte_eventdev.h | 105 ++++++++++++++++++++++++++----------
>>>    1 file changed, 77 insertions(+), 28 deletions(-)
>>>
>>> diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h
>>> index cb13602ffb..4eff1c4958 100644
>>> --- a/lib/eventdev/rte_eventdev.h
>>> +++ b/lib/eventdev/rte_eventdev.h
>>> @@ -1416,21 +1416,25 @@ struct rte_event_vector {
>>>
>>>    /* Event enqueue operations */
>>>    #define RTE_EVENT_OP_NEW                0
>>> -/**< The event producers use this operation to inject a new event to the
>>> +/**< The @ref rte_event.op field should be set to this type to inject a new event to the
>>>     * event device.
>>>     */
>>
>> "type" -> "value"
>>
>> "to" -> "into"?
>>
>> You could also say "to mark the event as new".
>>
>> What is new? Maybe "new (as opposed to a forwarded) event." or "new (i.e.,
>> not previously dequeued).".
>>
> 
> Using this latter suggested wording in V3.
> 
>> "The application sets the @ref rte_event.op field of an enqueued event to
>> this value to mark the event as new (i.e., not previously dequeued)."
>>
>>>    #define RTE_EVENT_OP_FORWARD            1
>>> -/**< The CPU use this operation to forward the event to different event queue or
>>> - * change to new application specific flow or schedule type to enable
>>> - * pipelining.
>>> +/**< SW should set the @ref rte_event.op filed to this type to return a
>>> + * previously dequeued event to the event device for further processing.
>>
>> "filed" -> "field"
>>
>> "SW" -> "The application"
>>
>> "to be scheduled for further processing (or transmission)"
>>
>> The wording should otherwise be the same as NEW, whatever you choose there.
>>
> Ack.
> 
>>>     *
>>> - * This operation must only be enqueued to the same port that the
>>> + * This event *must* be enqueued to the same port that the
>>>     * event to be forwarded was dequeued from.
>>
>> OK, so you "should" mark a new event RTE_EVENT_OP_FORWARD but you "*must*"
>> enqueue it to the same port.
>>
>> I think you "must" do both.
>>
> Ack
> 
>>> + *
>>> + * The event's fields, including (but not limited to) flow_id, scheduling type,
>>> + * destination queue, and event payload e.g. mbuf pointer, may all be updated as
>>> + * desired by software, but the @ref rte_event.impl_opaque field must
>>
>> "software" -> "application"
>>
> Ack
>   
>>> + * be kept to the same value as was present when the event was dequeued.
>>>     */
>>>    #define RTE_EVENT_OP_RELEASE            2
>>>    /**< Release the flow context associated with the schedule type.
>>>     *
>>> - * If current flow's scheduler type method is *RTE_SCHED_TYPE_ATOMIC*
>>> + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_ATOMIC
>>>     * then this function hints the scheduler that the user has completed critical
>>>     * section processing in the current atomic context.
>>>     * The scheduler is now allowed to schedule events from the same flow from
>>> @@ -1442,21 +1446,19 @@ struct rte_event_vector {
>>>     * performance, but the user needs to design carefully the split into critical
>>>     * vs non-critical sections.
>>>     *
>>> - * If current flow's scheduler type method is *RTE_SCHED_TYPE_ORDERED*
>>> - * then this function hints the scheduler that the user has done all that need
>>> - * to maintain event order in the current ordered context.
>>> - * The scheduler is allowed to release the ordered context of this port and
>>> - * avoid reordering any following enqueues.
>>> - *
>>> - * Early ordered context release may increase parallelism and thus system
>>> - * performance.
>>> + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_ORDERED
>>
>> Isn't a missing "or @ref RTE_SCHED_TYPE_ATOMIC" just an oversight (in the
>> original API wording)?
>>
> 
> No, I don't think so, because ATOMIC is described above.
> 
>>> + * then this function informs the scheduler that the current event has
>>> + * completed processing and will not be returned to the scheduler, i.e.
>>> + * it has been dropped, and so the reordering context for that event
>>> + * should be considered filled.
>>>     *
>>> - * If current flow's scheduler type method is *RTE_SCHED_TYPE_PARALLEL*
>>> + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_PARALLEL
>>>     * or no scheduling context is held then this function may be an NOOP,
>>>     * depending on the implementation.
>>
>> Maybe you can also fix this "function" -> "operation". I suggest you delete
>> that sentence, because it makes no sense.
>>
>> What is says in a somewhat vague manner is that you tread into the realm of
>> undefined behavior if you release PARALLEL events.
>>
> 
> Agree. Just deleting.
> 
>>>     *
>>>     * This operation must only be enqueued to the same port that the
>>> - * event to be released was dequeued from.
>>> + * event to be released was dequeued from. The @ref rte_event.impl_opaque
>>> + * field in the release event must match that in the original dequeued event.
>>
>> I would say "same value" rather than "match".
>>
>> "The @ref rte_event.impl_opaque field in the release event have the same
>> value as in the original dequeued event."
>>
> Ack.
> 
>>>     */
>>>
>>>    /**
>>> @@ -1473,53 +1475,100 @@ struct rte_event {
>>>    			/**< Targeted flow identifier for the enqueue and
>>>    			 * dequeue operation.
>>>    			 * The value must be in the range of
>>> -			 * [0, nb_event_queue_flows - 1] which
>>> +			 * [0, @ref rte_event_dev_config.nb_event_queue_flows - 1] which
>>
>> The same comment as I had before about ranges for unsigned types.
>>
> Ack.
> 
>>>    			 * previously supplied to rte_event_dev_configure().
>>> +			 *
>>> +			 * For @ref RTE_SCHED_TYPE_ATOMIC, this field is used to identify a
>>> +			 * flow context for atomicity, such that events from each individual flow
>>> +			 * will only be scheduled to one port at a time.
>>
>> flow_id alone doesn't identify an atomic flow. It's queue_id + flow_id. I'm
>> not sure I think "flow context" adds much, unless it's defined somewhere.
>> Sounds like some assumed implementation detail.
>>
> Removing the word context, and adding that it identifies a flow "within a
> queue and priority level", to make it clear that it's just not the flow_id
> involved here, as you say.
> 
>>> +			 *
>>> +			 * This field is preserved between enqueue and dequeue when
>>> +			 * a device reports the @ref RTE_EVENT_DEV_CAP_CARRY_FLOW_ID
>>> +			 * capability. Otherwise the value is implementation dependent
>>> +			 * on dequeue >   			 */
>>>    			uint32_t sub_event_type:8;
>>>    			/**< Sub-event types based on the event source.
>>> +			 *
>>> +			 * This field is preserved between enqueue and dequeue.
>>> +			 * This field is for SW or event adapter use,
>>
>> "SW" -> "application"
>>
> Ack.
> 
>>> +			 * and is unused in scheduling decisions.
>>> +			 *
>>>    			 * @see RTE_EVENT_TYPE_CPU
>>>    			 */
>>>    			uint32_t event_type:4;
>>> -			/**< Event type to classify the event source.
>>> -			 * @see RTE_EVENT_TYPE_ETHDEV, (RTE_EVENT_TYPE_*)
>>> +			/**< Event type to classify the event source. (RTE_EVENT_TYPE_*)
>>> +			 *
>>> +			 * This field is preserved between enqueue and dequeue
>>> +			 * This field is for SW or event adapter use,
>>> +			 * and is unused in scheduling decisions.
>>
>> "unused" -> "is not considered"?
>>
> Ack.
> 
>>>    			 */
>>>    			uint8_t op:2;
>>> -			/**< The type of event enqueue operation - new/forward/
>>> -			 * etc.This field is not preserved across an instance
>>> +			/**< The type of event enqueue operation - new/forward/ etc.
>>> +			 *
>>> +			 * This field is *not* preserved across an instance
>>>    			 * and is undefined on dequeue.
>>
>> Maybe you should use "undefined" rather than "implementation dependent", or
>> change this instance of undefined to implementation dependent. Now two
>> different terms are used for the same thing.
>>
> 
> Using implementation dependent.
> Ideally, I think we should update all drivers to set this to "FORWARD" by
> default on dequeue, but for now it's "implementation dependent".
> 

That would make a lot of sense.

>>> -			 * @see RTE_EVENT_OP_NEW, (RTE_EVENT_OP_*)
>>> +			 *
>>> +			 * @see RTE_EVENT_OP_NEW
>>> +			 * @see RTE_EVENT_OP_FORWARD
>>> +			 * @see RTE_EVENT_OP_RELEASE
>>>    			 */
>>>    			uint8_t rsvd:4;
>>> -			/**< Reserved for future use */
>>> +			/**< Reserved for future use.
>>> +			 *
>>> +			 * Should be set to zero on enqueue. Zero on dequeue.
>>> +			 */
>>
>> Why say they should be zero on dequeue? Doesn't this defeat the purpose of
>> having reserved bits, for future use? With you suggested wording, you can't
>> use these bits without breaking the ABI.
> 
> Good point. Removing the dequeue value bit.
> 
>>
>>>    			uint8_t sched_type:2;
>>>    			/**< Scheduler synchronization type (RTE_SCHED_TYPE_*)
>>>    			 * associated with flow id on a given event queue
>>>    			 * for the enqueue and dequeue operation.
>>> +			 *
>>> +			 * This field is used to determine the scheduling type
>>> +			 * for events sent to queues where @ref RTE_EVENT_QUEUE_CFG_ALL_TYPES
>>> +			 * is supported.
>>
>> "supported" -> "configured"
>>
> Ack.
> 
>>> +			 * For queues where only a single scheduling type is available,
>>> +			 * this field must be set to match the configured scheduling type.
>>> +			 *
>>
>> Why is the API/event device asking this of the application?
>>
> Historical reasons. I agree that it shouldn't, this should just be marked
> as ignored on fixed-type queues, but the spec up till now says it must
> match and some drivers do check this. Once we update the drivers to stop
> checking then we can change the spec without affecting apps.
> 
>>> +			 * This field is preserved between enqueue and
>>> dequeue.  +			 * +			 * @see
>>> RTE_SCHED_TYPE_ORDERED +			 * @see
>>> RTE_SCHED_TYPE_ATOMIC +			 * @see
>>> RTE_SCHED_TYPE_PARALLEL */ uint8_t queue_id; /**< Targeted event queue
>>> identifier for the enqueue or * dequeue operation.  * The value must be
>>> in the range of -			 * [0, nb_event_queues - 1] which
>>> previously supplied to -			 *
>>> rte_event_dev_configure().  +			 * [0, @ref
>>> rte_event_dev_config.nb_event_queues - 1] which was +
>>> * previously supplied to rte_event_dev_configure().  +
>>> * +			 * This field is preserved between enqueue on
>>> dequeue.  */ uint8_t priority; /**< Event priority relative to other
>>> events in the * event queue. The requested priority should in the -
>>> * range of  [RTE_EVENT_DEV_PRIORITY_HIGHEST, -			 *
>>> RTE_EVENT_DEV_PRIORITY_LOWEST].  +			 * range of  [@ref
>>> RTE_EVENT_DEV_PRIORITY_HIGHEST, +			 * @ref
>>> RTE_EVENT_DEV_PRIORITY_LOWEST].  * The implementation shall normalize
>>> the requested * priority to supported priority value.  +
>>> * * Valid when the device has -			 *
>>> RTE_EVENT_DEV_CAP_EVENT_QOS capability.  +			 * @ref
>>> RTE_EVENT_DEV_CAP_EVENT_QOS capability.  +			 * Ignored
>>> otherwise.  +			 * +			 * This
>>> field is preserved between enqueue and dequeue.
>>
>> Is the normalized or unnormalized value that is preserved?
>>
> Very good point. It's the normalized & then denormalised version that is
> guaranteed to be preserved, I suspect. SW eventdevs probably preserve
> as-is, but HW eventdevs may lose precision. Rather than making this
> "implementation defined" or "not preserved" which would be annoying for
> apps, I think, I'm going to document this as "preserved, but with possible
> loss of precision".
> 

This makes me again think it may be worth noting that Eventdev -> API 
priority normalization is (event.priority * PMD_LEVELS) / 
EVENTDEV_LEVELS (rounded down) - assuming that's how it's supposed to be 
done - or something to that effect.

>>>    			 */
>>>    			uint8_t impl_opaque;
>>>    			/**< Implementation specific opaque value.
>>
>> Maybe you can also fix "implementation" here to be something more specific.
>> Implementation, of what?
>>
>> "Event device implementation" or just "event device".
>>
> "Opaque field for event device use"
> 
>>> +			 *
>>>    			 * An implementation may use this field to hold
>>>    			 * implementation specific value to share between
>>>    			 * dequeue and enqueue operation.
>>> +			 *
>>>    			 * The application should not modify this field.
>>> +			 * Its value is implementation dependent on dequeue,
>>> +			 * and must be returned unmodified on enqueue when
>>> +			 * op type is @ref RTE_EVENT_OP_FORWARD or @ref RTE_EVENT_OP_RELEASE
>>
>> Should it be mentioned that impl_opaque is ignored by the event device for
>> NEW events?
>>
> Added in V3.
> 
>>>    			 */
>>>    		};
>>>    	};
>>> --
>>> 2.40.1
>>>

^ permalink raw reply	[relevance 0%]

* [PATCH v6 1/3] ethdev: rename action modify field data structure
  2024-02-02  0:42  3% ` [PATCH v6 " Suanming Mou
@ 2024-02-02  0:42  7%   ` Suanming Mou
  2024-02-05 11:23  0%     ` Thomas Monjalon
  0 siblings, 1 reply; 200+ results
From: Suanming Mou @ 2024-02-02  0:42 UTC (permalink / raw)
  To: ferruh.yigit, Ori Kam, Aman Singh, Yuying Zhang,
	Dariusz Sosnowski, Viacheslav Ovsiienko, Matan Azrad,
	Thomas Monjalon, Andrew Rybchenko
  Cc: dev

Current rte_flow_action_modify_data struct describes the pkt
field perfectly and is used only in action.

It is planned to be used for item as well. This commit renames
it to "rte_flow_field_data" making it compatible to be used by item.

Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c            | 22 +++++++++++-----------
 doc/guides/prog_guide/rte_flow.rst     |  2 +-
 doc/guides/rel_notes/release_24_03.rst |  2 ++
 drivers/net/mlx5/mlx5_flow.c           |  4 ++--
 drivers/net/mlx5/mlx5_flow.h           |  6 +++---
 drivers/net/mlx5/mlx5_flow_dv.c        | 10 +++++-----
 lib/ethdev/rte_flow.h                  | 10 ++++++----
 7 files changed, 30 insertions(+), 26 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 4d26e81d26..35030b5c47 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -744,13 +744,13 @@ enum index {
 #define ITEM_RAW_SIZE \
 	(sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE)
 
-/** Maximum size for external pattern in struct rte_flow_action_modify_data. */
-#define ACTION_MODIFY_PATTERN_SIZE 32
+/** Maximum size for external pattern in struct rte_flow_field_data. */
+#define FLOW_FIELD_PATTERN_SIZE 32
 
 /** Storage size for struct rte_flow_action_modify_field including pattern. */
 #define ACTION_MODIFY_SIZE \
 	(sizeof(struct rte_flow_action_modify_field) + \
-	ACTION_MODIFY_PATTERN_SIZE)
+	FLOW_FIELD_PATTERN_SIZE)
 
 /** Maximum number of queue indices in struct rte_flow_action_rss. */
 #define ACTION_RSS_QUEUE_NUM 128
@@ -944,7 +944,7 @@ static const char *const modify_field_ops[] = {
 	"set", "add", "sub", NULL
 };
 
-static const char *const modify_field_ids[] = {
+static const char *const flow_field_ids[] = {
 	"start", "mac_dst", "mac_src",
 	"vlan_type", "vlan_id", "mac_type",
 	"ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst",
@@ -6995,7 +6995,7 @@ static const struct token token_list[] = {
 			     ARGS_ENTRY_ARB(0, 0),
 			     ARGS_ENTRY_ARB
 				(sizeof(struct rte_flow_action_modify_field),
-				 ACTION_MODIFY_PATTERN_SIZE)),
+				 FLOW_FIELD_PATTERN_SIZE)),
 		.call = parse_vc_conf,
 	},
 	[ACTION_MODIFY_FIELD_WIDTH] = {
@@ -9821,10 +9821,10 @@ parse_vc_modify_field_id(struct context *ctx, const struct token *token,
 	if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE &&
 		ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)
 		return -1;
-	for (i = 0; modify_field_ids[i]; ++i)
-		if (!strcmp_partial(modify_field_ids[i], str, len))
+	for (i = 0; flow_field_ids[i]; ++i)
+		if (!strcmp_partial(flow_field_ids[i], str, len))
 			break;
-	if (!modify_field_ids[i])
+	if (!flow_field_ids[i])
 		return -1;
 	if (!ctx->object)
 		return len;
@@ -12051,10 +12051,10 @@ comp_set_modify_field_id(struct context *ctx, const struct token *token,
 
 	RTE_SET_USED(token);
 	if (!buf)
-		return RTE_DIM(modify_field_ids);
-	if (ent >= RTE_DIM(modify_field_ids) - 1)
+		return RTE_DIM(flow_field_ids);
+	if (ent >= RTE_DIM(flow_field_ids) - 1)
 		return -1;
-	name = modify_field_ids[ent];
+	name = flow_field_ids[ent];
 	if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE ||
 	    (strcmp(name, "pointer") && strcmp(name, "value")))
 		return strlcpy(buf, name, size);
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 7af329bd93..9192d6ab01 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3185,7 +3185,7 @@ destination offset as ``48``, and provide immediate value ``0xXXXX85XX``.
    | ``width``     | number of bits to use   |
    +---------------+-------------------------+
 
-.. _table_rte_flow_action_modify_data:
+.. _table_rte_flow_field_data:
 
 .. table:: destination/source field definition
 
diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 84d3144215..5f3ceeccab 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -124,6 +124,8 @@ ABI Changes
 
 * No ABI change that would break compatibility with 23.11.
 
+* ethdev: Rename the experimental ``struct rte_flow_action_modify_data`` to be ``struct rte_flow_field_data``
+
 
 Known Issues
 ------------
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 85e8c77c81..5788a7fb57 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2493,7 +2493,7 @@ mlx5_validate_action_ct(struct rte_eth_dev *dev,
  * Validate the level value for modify field action.
  *
  * @param[in] data
- *   Pointer to the rte_flow_action_modify_data structure either src or dst.
+ *   Pointer to the rte_flow_field_data structure either src or dst.
  * @param[out] error
  *   Pointer to error structure.
  *
@@ -2501,7 +2501,7 @@ mlx5_validate_action_ct(struct rte_eth_dev *dev,
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-flow_validate_modify_field_level(const struct rte_flow_action_modify_data *data,
+flow_validate_modify_field_level(const struct rte_flow_field_data *data,
 				 struct rte_flow_error *error)
 {
 	if (data->level == 0)
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 6dde9de688..ecfb04ead2 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -1121,7 +1121,7 @@ flow_items_to_tunnel(const struct rte_flow_item items[])
  *   Tag array index.
  */
 static inline uint8_t
-flow_tag_index_get(const struct rte_flow_action_modify_data *data)
+flow_tag_index_get(const struct rte_flow_field_data *data)
 {
 	return data->tag_index ? data->tag_index : data->level;
 }
@@ -2523,7 +2523,7 @@ int mlx5_flow_validate_action_default_miss(uint64_t action_flags,
 				const struct rte_flow_attr *attr,
 				struct rte_flow_error *error);
 int flow_validate_modify_field_level
-			(const struct rte_flow_action_modify_data *data,
+			(const struct rte_flow_field_data *data,
 			 struct rte_flow_error *error);
 int mlx5_flow_item_acceptable(const struct rte_flow_item *item,
 			      const uint8_t *mask,
@@ -2828,7 +2828,7 @@ size_t flow_dv_get_item_hdr_len(const enum rte_flow_item_type item_type);
 int flow_dv_convert_encap_data(const struct rte_flow_item *items, uint8_t *buf,
 			   size_t *size, struct rte_flow_error *error);
 void mlx5_flow_field_id_to_modify_info
-		(const struct rte_flow_action_modify_data *data,
+		(const struct rte_flow_field_data *data,
 		 struct field_modify_info *info, uint32_t *mask,
 		 uint32_t width, struct rte_eth_dev *dev,
 		 const struct rte_flow_attr *attr, struct rte_flow_error *error);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 115d730317..52620be262 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1441,7 +1441,7 @@ flow_modify_info_mask_32_masked(uint32_t length, uint32_t off, uint32_t post_mas
 }
 
 static __rte_always_inline enum mlx5_modification_field
-mlx5_mpls_modi_field_get(const struct rte_flow_action_modify_data *data)
+mlx5_mpls_modi_field_get(const struct rte_flow_field_data *data)
 {
 	return MLX5_MODI_IN_MPLS_LABEL_0 + data->tag_index;
 }
@@ -1449,7 +1449,7 @@ mlx5_mpls_modi_field_get(const struct rte_flow_action_modify_data *data)
 static void
 mlx5_modify_flex_item(const struct rte_eth_dev *dev,
 		      const struct mlx5_flex_item *flex,
-		      const struct rte_flow_action_modify_data *data,
+		      const struct rte_flow_field_data *data,
 		      struct field_modify_info *info,
 		      uint32_t *mask, uint32_t width)
 {
@@ -1573,7 +1573,7 @@ mlx5_modify_flex_item(const struct rte_eth_dev *dev,
 
 void
 mlx5_flow_field_id_to_modify_info
-		(const struct rte_flow_action_modify_data *data,
+		(const struct rte_flow_field_data *data,
 		 struct field_modify_info *info, uint32_t *mask,
 		 uint32_t width, struct rte_eth_dev *dev,
 		 const struct rte_flow_attr *attr, struct rte_flow_error *error)
@@ -5284,8 +5284,8 @@ flow_dv_validate_action_modify_field(struct rte_eth_dev *dev,
 	struct mlx5_sh_config *config = &priv->sh->config;
 	struct mlx5_hca_attr *hca_attr = &priv->sh->cdev->config.hca_attr;
 	const struct rte_flow_action_modify_field *conf = action->conf;
-	const struct rte_flow_action_modify_data *src_data = &conf->src;
-	const struct rte_flow_action_modify_data *dst_data = &conf->dst;
+	const struct rte_flow_field_data *src_data = &conf->src;
+	const struct rte_flow_field_data *dst_data = &conf->dst;
 	uint32_t dst_width, src_width, width = conf->width;
 
 	ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 1dded812ec..5e66b2af1d 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3894,6 +3894,7 @@ struct rte_flow_action_ethdev {
 
 /**
  * Field IDs for MODIFY_FIELD action.
+ * e.g. the packet field IDs used in RTE_FLOW_ACTION_TYPE_MODIFY_FIELD.
  */
 enum rte_flow_field_id {
 	RTE_FLOW_FIELD_START = 0,	/**< Start of a packet. */
@@ -3947,9 +3948,10 @@ enum rte_flow_field_id {
  * @warning
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
- * Field description for MODIFY_FIELD action.
+ * Field description for packet field.
+ * e.g. the packet fields used in RTE_FLOW_ACTION_TYPE_MODIFY_FIELD.
  */
-struct rte_flow_action_modify_data {
+struct rte_flow_field_data {
 	enum rte_flow_field_id field; /**< Field or memory type ID. */
 	union {
 		struct {
@@ -4058,8 +4060,8 @@ enum rte_flow_modify_op {
  */
 struct rte_flow_action_modify_field {
 	enum rte_flow_modify_op operation; /**< Operation to perform. */
-	struct rte_flow_action_modify_data dst; /**< Destination field. */
-	struct rte_flow_action_modify_data src; /**< Source field. */
+	struct rte_flow_field_data dst; /**< Destination field. */
+	struct rte_flow_field_data src; /**< Source field. */
 	uint32_t width; /**< Number of bits to use from a source field. */
 };
 
-- 
2.34.1


^ permalink raw reply	[relevance 7%]

* [PATCH v6 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE
    2024-02-01  2:30  3% ` [PATCH v4 0/3] " Suanming Mou
  2024-02-01 12:29  3% ` [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Suanming Mou
@ 2024-02-02  0:42  3% ` Suanming Mou
  2024-02-02  0:42  7%   ` [PATCH v6 1/3] ethdev: rename action modify field data structure Suanming Mou
  2024-02-06  2:06  3% ` [PATCH v7 0/4] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Suanming Mou
  3 siblings, 1 reply; 200+ results
From: Suanming Mou @ 2024-02-02  0:42 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: dev, orika

The new item type is added for the case user wants to match traffic
based on packet field compare result with other fields or immediate
value.

e.g. take advantage the compare item user will be able to accumulate
a IPv4/TCP packet's TCP data_offset and IPv4 IHL field to a tag
register, then compare the tag register with IPv4 header total length
to understand the packet has payload or not.

The supported operations can be as below:
 - RTE_FLOW_ITEM_COMPARE_EQ (equal)
 - RTE_FLOW_ITEM_COMPARE_NE (not equal)
 - RTE_FLOW_ITEM_COMPARE_LT (less than)
 - RTE_FLOW_ITEM_COMPARE_LE (less than or equal)
 - RTE_FLOW_ITEM_COMPARE_GT (great than)
 - RTE_FLOW_ITEM_COMPARE_GE (great than or equal)

V6:
 - fix typo and style issue.
 - adjust flow_field description.

V5:
 - rebase on top of next-net
 - add sample detail for rte_flow_field.

V4:
 - rebase on top of the latest version.
 - move ACTION_MODIFY_PATTERN_SIZE and modify_field_ids rename
   to first patch.
 - add comparison flow create sample in testpmd_funcs.rst.

V3:
 - fix code style missing empty line in rte_flow.rst.
 - fix missing the ABI change release notes.

V2:
 - Since modify field data struct is experiment, rename modify
   field data directly instead of adding new flow field struct.


Suanming Mou (3):
  ethdev: rename action modify field data structure
  ethdev: add compare item
  net/mlx5: add compare item support

 app/test-pmd/cmdline_flow.c                 | 416 +++++++++++++++++++-
 doc/guides/nics/features/default.ini        |   1 +
 doc/guides/nics/features/mlx5.ini           |   1 +
 doc/guides/nics/mlx5.rst                    |   7 +
 doc/guides/prog_guide/rte_flow.rst          |   9 +-
 doc/guides/rel_notes/release_24_03.rst      |   9 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  24 ++
 drivers/net/mlx5/mlx5_flow.c                |   4 +-
 drivers/net/mlx5/mlx5_flow.h                |   9 +-
 drivers/net/mlx5/mlx5_flow_dv.c             |  10 +-
 drivers/net/mlx5/mlx5_flow_hw.c             |  73 ++++
 lib/ethdev/rte_flow.c                       |   1 +
 lib/ethdev/rte_flow.h                       | 332 +++++++++-------
 13 files changed, 727 insertions(+), 169 deletions(-)

-- 
2.34.1


^ permalink raw reply	[relevance 3%]

* RE: [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE
  2024-02-01 18:56  0%   ` [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Ferruh Yigit
@ 2024-02-02  0:32  0%     ` Suanming Mou
  0 siblings, 0 replies; 200+ results
From: Suanming Mou @ 2024-02-02  0:32 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Ori Kam



> -----Original Message-----
> From: Ferruh Yigit <ferruh.yigit@amd.com>
> Sent: Friday, February 2, 2024 2:56 AM
> To: Suanming Mou <suanmingm@nvidia.com>
> Cc: dev@dpdk.org; Ori Kam <orika@nvidia.com>
> Subject: Re: [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE
> 
> On 2/1/2024 12:29 PM, Suanming Mou wrote:
> > The new item type is added for the case user wants to match traffic
> > based on packet field compare result with other fields or immediate
> > value.
> >
> > e.g. take advantage the compare item user will be able to accumulate a
> > IPv4/TCP packet's TCP data_offset and IPv4 IHL field to a tag
> > register, then compare the tag register with IPv4 header total length
> > to understand the packet has payload or not.
> >
> > The supported operations can be as below:
> >  - RTE_FLOW_ITEM_COMPARE_EQ (equal)
> >  - RTE_FLOW_ITEM_COMPARE_NE (not equal)
> >  - RTE_FLOW_ITEM_COMPARE_LT (less than)
> >  - RTE_FLOW_ITEM_COMPARE_LE (less than or equal)
> >  - RTE_FLOW_ITEM_COMPARE_GT (great than)
> >  - RTE_FLOW_ITEM_COMPARE_GE (great than or equal)
> >
> > V5:
> >  - rebase on top of next-net
> >  - add sample detail for rte_flow_field.
> >
> > V4:
> >  - rebase on top of the latest version.
> >  - move ACTION_MODIFY_PATTERN_SIZE and modify_field_ids rename
> >    to first patch.
> >  - add comparison flow create sample in testpmd_funcs.rst.
> >
> > V3:
> >  - fix code style missing empty line in rte_flow.rst.
> >  - fix missing the ABI change release notes.
> >
> > V2:
> >  - Since modify field data struct is experiment, rename modify
> >    field data directly instead of adding new flow field struct.
> >
> >
> > Suanming Mou (3):
> >   ethdev: rename action modify field data structure
> >   ethdev: add compare item
> >   net/mlx5: add compare item support
> >
> 
> Mostly looks good, please find comments on a few minor issues on patches.

Sure, thanks.


^ permalink raw reply	[relevance 0%]

* Re: [PATCH v5 1/3] ethdev: rename action modify field data structure
  2024-02-01 12:29  7%   ` [PATCH v5 1/3] ethdev: rename action modify field data structure Suanming Mou
@ 2024-02-01 18:57  0%     ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2024-02-01 18:57 UTC (permalink / raw)
  To: Suanming Mou, Ori Kam, Aman Singh, Yuying Zhang,
	Dariusz Sosnowski, Viacheslav Ovsiienko, Matan Azrad,
	Thomas Monjalon, Andrew Rybchenko
  Cc: dev

On 2/1/2024 12:29 PM, Suanming Mou wrote:
> Current rte_flow_action_modify_data struct describes the pkt
> field perfectly and is used only in action.
> 
> It is planned to be used for item as well. This commit renames
> it to "rte_flow_field_data" making it compatible to be used by item.
> 
> Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
> Acked-by: Ori Kam <orika@nvidia.com>
> Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

<...>

> diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
> index 84d3144215..efeda6ea97 100644
> --- a/doc/guides/rel_notes/release_24_03.rst
> +++ b/doc/guides/rel_notes/release_24_03.rst
> @@ -124,6 +124,7 @@ ABI Changes
>  
>  * No ABI change that would break compatibility with 23.11.
>  
> +* ethdev: Rename the experimental ``struct rte_flow_action_modify_data`` to be ``struct rte_flow_field_data``
>  

Please put one more empty line after your change, to have two empty
lines before next section.

<...>

> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> index 1267c146e5..a143ecb194 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -3887,6 +3887,8 @@ struct rte_flow_action_ethdev {
>  
>  /**
>   * Field IDs for MODIFY_FIELD action.
> + * e.g. the packet field IDs used in RTE_FLOW_ACTION_TYPE_MODIFY_FIELD
> + * and RTE_FLOW_ITEM_TYPE_COMPARE.
>

In this patch there is no RTE_FLOW_ITEM_TYPE_COMPARE yet, can you please
update to have RTE_FLOW_ACTION_TYPE_MODIFY_FIELD in this patch and add
RTE_FLOW_ITEM_TYPE_COMPARE in next patch?


>   */
>  enum rte_flow_field_id {
>  	RTE_FLOW_FIELD_START = 0,	/**< Start of a packet. */
> @@ -3940,9 +3942,11 @@ enum rte_flow_field_id {
>   * @warning
>   * @b EXPERIMENTAL: this structure may change without prior notice
>   *
> - * Field description for MODIFY_FIELD action.
> + * Field description for packet field.
> + * e.g. the packet fields used in RTE_FLOW_ACTION_TYPE_MODIFY_FIELD
> + * and RTE_FLOW_ITEM_TYPE_COMPARE.
>

Same here, can you please mention from RTE_FLOW_ITEM_TYPE_COMPARE in
next patch.


^ permalink raw reply	[relevance 0%]

* Re: [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE
  2024-02-01 12:29  3% ` [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Suanming Mou
  2024-02-01 12:29  7%   ` [PATCH v5 1/3] ethdev: rename action modify field data structure Suanming Mou
@ 2024-02-01 18:56  0%   ` Ferruh Yigit
  2024-02-02  0:32  0%     ` Suanming Mou
  1 sibling, 1 reply; 200+ results
From: Ferruh Yigit @ 2024-02-01 18:56 UTC (permalink / raw)
  To: Suanming Mou; +Cc: dev, orika

On 2/1/2024 12:29 PM, Suanming Mou wrote:
> The new item type is added for the case user wants to match traffic
> based on packet field compare result with other fields or immediate
> value.
> 
> e.g. take advantage the compare item user will be able to accumulate
> a IPv4/TCP packet's TCP data_offset and IPv4 IHL field to a tag
> register, then compare the tag register with IPv4 header total length
> to understand the packet has payload or not.
> 
> The supported operations can be as below:
>  - RTE_FLOW_ITEM_COMPARE_EQ (equal)
>  - RTE_FLOW_ITEM_COMPARE_NE (not equal)
>  - RTE_FLOW_ITEM_COMPARE_LT (less than)
>  - RTE_FLOW_ITEM_COMPARE_LE (less than or equal)
>  - RTE_FLOW_ITEM_COMPARE_GT (great than)
>  - RTE_FLOW_ITEM_COMPARE_GE (great than or equal)
> 
> V5:
>  - rebase on top of next-net
>  - add sample detail for rte_flow_field.
> 
> V4:
>  - rebase on top of the latest version.
>  - move ACTION_MODIFY_PATTERN_SIZE and modify_field_ids rename
>    to first patch.
>  - add comparison flow create sample in testpmd_funcs.rst.
> 
> V3:
>  - fix code style missing empty line in rte_flow.rst.
>  - fix missing the ABI change release notes.
> 
> V2:
>  - Since modify field data struct is experiment, rename modify
>    field data directly instead of adding new flow field struct.
> 
> 
> Suanming Mou (3):
>   ethdev: rename action modify field data structure
>   ethdev: add compare item
>   net/mlx5: add compare item support
> 

Mostly looks good, please find comments on a few minor issues on patches.


^ permalink raw reply	[relevance 0%]

* Re: [PATCH v2 11/11] eventdev: RFC clarify docs on event object fields
  2024-01-24 11:34  3%     ` Mattias Rönnblom
@ 2024-02-01 16:59  0%       ` Bruce Richardson
  2024-02-02  9:38  0%         ` Mattias Rönnblom
  0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2024-02-01 16:59 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: dev, jerinj, mattias.ronnblom, abdullah.sevincer, sachin.saxena,
	hemant.agrawal, pbhagavatula, pravin.pathak

On Wed, Jan 24, 2024 at 12:34:50PM +0100, Mattias Rönnblom wrote:
> On 2024-01-19 18:43, Bruce Richardson wrote:
> > Clarify the meaning of the NEW, FORWARD and RELEASE event types.
> > For the fields in "rte_event" struct, enhance the comments on each to
> > clarify the field's use, and whether it is preserved between enqueue and
> > dequeue, and it's role, if any, in scheduling.
> > 
> > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > ---
> > 
> > As with the previous patch, please review this patch to ensure that the
> > expected semantics of the various event types and event fields have not
> > changed in an unexpected way.
> > ---
> >   lib/eventdev/rte_eventdev.h | 105 ++++++++++++++++++++++++++----------
> >   1 file changed, 77 insertions(+), 28 deletions(-)
> > 
> > diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h
> > index cb13602ffb..4eff1c4958 100644
> > --- a/lib/eventdev/rte_eventdev.h
> > +++ b/lib/eventdev/rte_eventdev.h
> > @@ -1416,21 +1416,25 @@ struct rte_event_vector {
> > 
> >   /* Event enqueue operations */
> >   #define RTE_EVENT_OP_NEW                0
> > -/**< The event producers use this operation to inject a new event to the
> > +/**< The @ref rte_event.op field should be set to this type to inject a new event to the
> >    * event device.
> >    */
> 
> "type" -> "value"
> 
> "to" -> "into"?
> 
> You could also say "to mark the event as new".
> 
> What is new? Maybe "new (as opposed to a forwarded) event." or "new (i.e.,
> not previously dequeued).".
> 

Using this latter suggested wording in V3.

> "The application sets the @ref rte_event.op field of an enqueued event to
> this value to mark the event as new (i.e., not previously dequeued)."
> 
> >   #define RTE_EVENT_OP_FORWARD            1
> > -/**< The CPU use this operation to forward the event to different event queue or
> > - * change to new application specific flow or schedule type to enable
> > - * pipelining.
> > +/**< SW should set the @ref rte_event.op filed to this type to return a
> > + * previously dequeued event to the event device for further processing.
> 
> "filed" -> "field"
> 
> "SW" -> "The application"
> 
> "to be scheduled for further processing (or transmission)"
> 
> The wording should otherwise be the same as NEW, whatever you choose there.
> 
Ack.

> >    *
> > - * This operation must only be enqueued to the same port that the
> > + * This event *must* be enqueued to the same port that the
> >    * event to be forwarded was dequeued from.
> 
> OK, so you "should" mark a new event RTE_EVENT_OP_FORWARD but you "*must*"
> enqueue it to the same port.
> 
> I think you "must" do both.
> 
Ack

> > + *
> > + * The event's fields, including (but not limited to) flow_id, scheduling type,
> > + * destination queue, and event payload e.g. mbuf pointer, may all be updated as
> > + * desired by software, but the @ref rte_event.impl_opaque field must
> 
> "software" -> "application"
>
Ack
 
> > + * be kept to the same value as was present when the event was dequeued.
> >    */
> >   #define RTE_EVENT_OP_RELEASE            2
> >   /**< Release the flow context associated with the schedule type.
> >    *
> > - * If current flow's scheduler type method is *RTE_SCHED_TYPE_ATOMIC*
> > + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_ATOMIC
> >    * then this function hints the scheduler that the user has completed critical
> >    * section processing in the current atomic context.
> >    * The scheduler is now allowed to schedule events from the same flow from
> > @@ -1442,21 +1446,19 @@ struct rte_event_vector {
> >    * performance, but the user needs to design carefully the split into critical
> >    * vs non-critical sections.
> >    *
> > - * If current flow's scheduler type method is *RTE_SCHED_TYPE_ORDERED*
> > - * then this function hints the scheduler that the user has done all that need
> > - * to maintain event order in the current ordered context.
> > - * The scheduler is allowed to release the ordered context of this port and
> > - * avoid reordering any following enqueues.
> > - *
> > - * Early ordered context release may increase parallelism and thus system
> > - * performance.
> > + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_ORDERED
> 
> Isn't a missing "or @ref RTE_SCHED_TYPE_ATOMIC" just an oversight (in the
> original API wording)?
> 

No, I don't think so, because ATOMIC is described above.

> > + * then this function informs the scheduler that the current event has
> > + * completed processing and will not be returned to the scheduler, i.e.
> > + * it has been dropped, and so the reordering context for that event
> > + * should be considered filled.
> >    *
> > - * If current flow's scheduler type method is *RTE_SCHED_TYPE_PARALLEL*
> > + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_PARALLEL
> >    * or no scheduling context is held then this function may be an NOOP,
> >    * depending on the implementation.
> 
> Maybe you can also fix this "function" -> "operation". I suggest you delete
> that sentence, because it makes no sense.
> 
> What is says in a somewhat vague manner is that you tread into the realm of
> undefined behavior if you release PARALLEL events.
> 

Agree. Just deleting.

> >    *
> >    * This operation must only be enqueued to the same port that the
> > - * event to be released was dequeued from.
> > + * event to be released was dequeued from. The @ref rte_event.impl_opaque
> > + * field in the release event must match that in the original dequeued event.
> 
> I would say "same value" rather than "match".
> 
> "The @ref rte_event.impl_opaque field in the release event have the same
> value as in the original dequeued event."
> 
Ack.

> >    */
> > 
> >   /**
> > @@ -1473,53 +1475,100 @@ struct rte_event {
> >   			/**< Targeted flow identifier for the enqueue and
> >   			 * dequeue operation.
> >   			 * The value must be in the range of
> > -			 * [0, nb_event_queue_flows - 1] which
> > +			 * [0, @ref rte_event_dev_config.nb_event_queue_flows - 1] which
> 
> The same comment as I had before about ranges for unsigned types.
> 
Ack.

> >   			 * previously supplied to rte_event_dev_configure().
> > +			 *
> > +			 * For @ref RTE_SCHED_TYPE_ATOMIC, this field is used to identify a
> > +			 * flow context for atomicity, such that events from each individual flow
> > +			 * will only be scheduled to one port at a time.
> 
> flow_id alone doesn't identify an atomic flow. It's queue_id + flow_id. I'm
> not sure I think "flow context" adds much, unless it's defined somewhere.
> Sounds like some assumed implementation detail.
> 
Removing the word context, and adding that it identifies a flow "within a
queue and priority level", to make it clear that it's just not the flow_id
involved here, as you say.

> > +			 *
> > +			 * This field is preserved between enqueue and dequeue when
> > +			 * a device reports the @ref RTE_EVENT_DEV_CAP_CARRY_FLOW_ID
> > +			 * capability. Otherwise the value is implementation dependent
> > +			 * on dequeue >   			 */
> >   			uint32_t sub_event_type:8;
> >   			/**< Sub-event types based on the event source.
> > +			 *
> > +			 * This field is preserved between enqueue and dequeue.
> > +			 * This field is for SW or event adapter use,
> 
> "SW" -> "application"
> 
Ack.

> > +			 * and is unused in scheduling decisions.
> > +			 *
> >   			 * @see RTE_EVENT_TYPE_CPU
> >   			 */
> >   			uint32_t event_type:4;
> > -			/**< Event type to classify the event source.
> > -			 * @see RTE_EVENT_TYPE_ETHDEV, (RTE_EVENT_TYPE_*)
> > +			/**< Event type to classify the event source. (RTE_EVENT_TYPE_*)
> > +			 *
> > +			 * This field is preserved between enqueue and dequeue
> > +			 * This field is for SW or event adapter use,
> > +			 * and is unused in scheduling decisions.
> 
> "unused" -> "is not considered"?
> 
Ack.

> >   			 */
> >   			uint8_t op:2;
> > -			/**< The type of event enqueue operation - new/forward/
> > -			 * etc.This field is not preserved across an instance
> > +			/**< The type of event enqueue operation - new/forward/ etc.
> > +			 *
> > +			 * This field is *not* preserved across an instance
> >   			 * and is undefined on dequeue.
> 
> Maybe you should use "undefined" rather than "implementation dependent", or
> change this instance of undefined to implementation dependent. Now two
> different terms are used for the same thing.
> 

Using implementation dependent.
Ideally, I think we should update all drivers to set this to "FORWARD" by
default on dequeue, but for now it's "implementation dependent".

> > -			 * @see RTE_EVENT_OP_NEW, (RTE_EVENT_OP_*)
> > +			 *
> > +			 * @see RTE_EVENT_OP_NEW
> > +			 * @see RTE_EVENT_OP_FORWARD
> > +			 * @see RTE_EVENT_OP_RELEASE
> >   			 */
> >   			uint8_t rsvd:4;
> > -			/**< Reserved for future use */
> > +			/**< Reserved for future use.
> > +			 *
> > +			 * Should be set to zero on enqueue. Zero on dequeue.
> > +			 */
> 
> Why say they should be zero on dequeue? Doesn't this defeat the purpose of
> having reserved bits, for future use? With you suggested wording, you can't
> use these bits without breaking the ABI.

Good point. Removing the dequeue value bit.

> 
> >   			uint8_t sched_type:2;
> >   			/**< Scheduler synchronization type (RTE_SCHED_TYPE_*)
> >   			 * associated with flow id on a given event queue
> >   			 * for the enqueue and dequeue operation.
> > +			 *
> > +			 * This field is used to determine the scheduling type
> > +			 * for events sent to queues where @ref RTE_EVENT_QUEUE_CFG_ALL_TYPES
> > +			 * is supported.
> 
> "supported" -> "configured"
> 
Ack.

> > +			 * For queues where only a single scheduling type is available,
> > +			 * this field must be set to match the configured scheduling type.
> > +			 *
> 
> Why is the API/event device asking this of the application?
> 
Historical reasons. I agree that it shouldn't, this should just be marked
as ignored on fixed-type queues, but the spec up till now says it must
match and some drivers do check this. Once we update the drivers to stop
checking then we can change the spec without affecting apps.

> > +			 * This field is preserved between enqueue and
> > dequeue.  +			 * +			 * @see
> > RTE_SCHED_TYPE_ORDERED +			 * @see
> > RTE_SCHED_TYPE_ATOMIC +			 * @see
> > RTE_SCHED_TYPE_PARALLEL */ uint8_t queue_id; /**< Targeted event queue
> > identifier for the enqueue or * dequeue operation.  * The value must be
> > in the range of -			 * [0, nb_event_queues - 1] which
> > previously supplied to -			 *
> > rte_event_dev_configure().  +			 * [0, @ref
> > rte_event_dev_config.nb_event_queues - 1] which was +
> > * previously supplied to rte_event_dev_configure().  +
> > * +			 * This field is preserved between enqueue on
> > dequeue.  */ uint8_t priority; /**< Event priority relative to other
> > events in the * event queue. The requested priority should in the -
> > * range of  [RTE_EVENT_DEV_PRIORITY_HIGHEST, -			 *
> > RTE_EVENT_DEV_PRIORITY_LOWEST].  +			 * range of  [@ref
> > RTE_EVENT_DEV_PRIORITY_HIGHEST, +			 * @ref
> > RTE_EVENT_DEV_PRIORITY_LOWEST].  * The implementation shall normalize
> > the requested * priority to supported priority value.  +
> > * * Valid when the device has -			 *
> > RTE_EVENT_DEV_CAP_EVENT_QOS capability.  +			 * @ref
> > RTE_EVENT_DEV_CAP_EVENT_QOS capability.  +			 * Ignored
> > otherwise.  +			 * +			 * This
> > field is preserved between enqueue and dequeue.
> 
> Is the normalized or unnormalized value that is preserved?
> 
Very good point. It's the normalized & then denormalised version that is
guaranteed to be preserved, I suspect. SW eventdevs probably preserve
as-is, but HW eventdevs may lose precision. Rather than making this
"implementation defined" or "not preserved" which would be annoying for
apps, I think, I'm going to document this as "preserved, but with possible
loss of precision".

> >   			 */
> >   			uint8_t impl_opaque;
> >   			/**< Implementation specific opaque value.
> 
> Maybe you can also fix "implementation" here to be something more specific.
> Implementation, of what?
> 
> "Event device implementation" or just "event device".
> 
"Opaque field for event device use"

> > +			 *
> >   			 * An implementation may use this field to hold
> >   			 * implementation specific value to share between
> >   			 * dequeue and enqueue operation.
> > +			 *
> >   			 * The application should not modify this field.
> > +			 * Its value is implementation dependent on dequeue,
> > +			 * and must be returned unmodified on enqueue when
> > +			 * op type is @ref RTE_EVENT_OP_FORWARD or @ref RTE_EVENT_OP_RELEASE
> 
> Should it be mentioned that impl_opaque is ignored by the event device for
> NEW events?
> 
Added in V3.

> >   			 */
> >   		};
> >   	};
> > --
> > 2.40.1
> > 

^ permalink raw reply	[relevance 0%]

* RE: [EXT] [PATCH 1/3] cryptodev: add ec points to sm2 op
  2024-02-01  8:07  3% ` [EXT] " Akhil Goyal
@ 2024-02-01 13:25  0%   ` Kusztal, ArkadiuszX
  0 siblings, 0 replies; 200+ results
From: Kusztal, ArkadiuszX @ 2024-02-01 13:25 UTC (permalink / raw)
  To: Akhil Goyal, dev; +Cc: Power, Ciara



> -----Original Message-----
> From: Akhil Goyal <gakhil@marvell.com>
> Sent: Thursday, February 1, 2024 9:08 AM
> To: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; dev@dpdk.org
> Cc: Power, Ciara <ciara.power@intel.com>
> Subject: RE: [EXT] [PATCH 1/3] cryptodev: add ec points to sm2 op
> 
> > ----------------------------------------------------------------------
> > In the case when PMD cannot support full process of the SM2, but
> > elliptic curve computation only, additional fields are needed to
> > handle such a case.
> >
> 
> Asym crypto APIs are no longer experimental.
> Hence adding new fields would lead to ABI break.

It seems that
`__rte_crypto_op_reset`
`rte_crypto_op_pool_create`
functions do not need versioning, and we could easily do it if needed.
But the field `flags` changes an offset, and this is actually problematic.
Which means that we cannot do this change before 24.11.

> 
> > Points C1, kP therefore were added to the SM2 crypto operation struct.
> >
> > Signed-off-by: Arkadiusz Kusztal <arkadiuszx.kusztal@intel.com>

^ permalink raw reply	[relevance 0%]

* [PATCH v5 1/3] ethdev: rename action modify field data structure
  2024-02-01 12:29  3% ` [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Suanming Mou
@ 2024-02-01 12:29  7%   ` Suanming Mou
  2024-02-01 18:57  0%     ` Ferruh Yigit
  2024-02-01 18:56  0%   ` [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Ferruh Yigit
  1 sibling, 1 reply; 200+ results
From: Suanming Mou @ 2024-02-01 12:29 UTC (permalink / raw)
  To: ferruh.yigit, Ori Kam, Aman Singh, Yuying Zhang,
	Dariusz Sosnowski, Viacheslav Ovsiienko, Matan Azrad,
	Thomas Monjalon, Andrew Rybchenko
  Cc: dev

Current rte_flow_action_modify_data struct describes the pkt
field perfectly and is used only in action.

It is planned to be used for item as well. This commit renames
it to "rte_flow_field_data" making it compatible to be used by item.

Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c            | 22 +++++++++++-----------
 doc/guides/prog_guide/rte_flow.rst     |  2 +-
 doc/guides/rel_notes/release_24_03.rst |  1 +
 drivers/net/mlx5/mlx5_flow.c           |  4 ++--
 drivers/net/mlx5/mlx5_flow.h           |  6 +++---
 drivers/net/mlx5/mlx5_flow_dv.c        | 10 +++++-----
 lib/ethdev/rte_flow.h                  | 12 ++++++++----
 7 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 359c187b3c..972c6ae490 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -742,13 +742,13 @@ enum index {
 #define ITEM_RAW_SIZE \
 	(sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE)
 
-/** Maximum size for external pattern in struct rte_flow_action_modify_data. */
-#define ACTION_MODIFY_PATTERN_SIZE 32
+/** Maximum size for external pattern in struct rte_flow_field_data. */
+#define FLOW_FIELD_PATTERN_SIZE 32
 
 /** Storage size for struct rte_flow_action_modify_field including pattern. */
 #define ACTION_MODIFY_SIZE \
 	(sizeof(struct rte_flow_action_modify_field) + \
-	ACTION_MODIFY_PATTERN_SIZE)
+	FLOW_FIELD_PATTERN_SIZE)
 
 /** Maximum number of queue indices in struct rte_flow_action_rss. */
 #define ACTION_RSS_QUEUE_NUM 128
@@ -942,7 +942,7 @@ static const char *const modify_field_ops[] = {
 	"set", "add", "sub", NULL
 };
 
-static const char *const modify_field_ids[] = {
+static const char *const flow_field_ids[] = {
 	"start", "mac_dst", "mac_src",
 	"vlan_type", "vlan_id", "mac_type",
 	"ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst",
@@ -6986,7 +6986,7 @@ static const struct token token_list[] = {
 			     ARGS_ENTRY_ARB(0, 0),
 			     ARGS_ENTRY_ARB
 				(sizeof(struct rte_flow_action_modify_field),
-				 ACTION_MODIFY_PATTERN_SIZE)),
+				 FLOW_FIELD_PATTERN_SIZE)),
 		.call = parse_vc_conf,
 	},
 	[ACTION_MODIFY_FIELD_WIDTH] = {
@@ -9798,10 +9798,10 @@ parse_vc_modify_field_id(struct context *ctx, const struct token *token,
 	if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE &&
 		ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)
 		return -1;
-	for (i = 0; modify_field_ids[i]; ++i)
-		if (!strcmp_partial(modify_field_ids[i], str, len))
+	for (i = 0; flow_field_ids[i]; ++i)
+		if (!strcmp_partial(flow_field_ids[i], str, len))
 			break;
-	if (!modify_field_ids[i])
+	if (!flow_field_ids[i])
 		return -1;
 	if (!ctx->object)
 		return len;
@@ -12028,10 +12028,10 @@ comp_set_modify_field_id(struct context *ctx, const struct token *token,
 
 	RTE_SET_USED(token);
 	if (!buf)
-		return RTE_DIM(modify_field_ids);
-	if (ent >= RTE_DIM(modify_field_ids) - 1)
+		return RTE_DIM(flow_field_ids);
+	if (ent >= RTE_DIM(flow_field_ids) - 1)
 		return -1;
-	name = modify_field_ids[ent];
+	name = flow_field_ids[ent];
 	if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE ||
 	    (strcmp(name, "pointer") && strcmp(name, "value")))
 		return strlcpy(buf, name, size);
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 900fdaefb6..f936a9ba19 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3185,7 +3185,7 @@ destination offset as ``48``, and provide immediate value ``0xXXXX85XX``.
    | ``width``     | number of bits to use   |
    +---------------+-------------------------+
 
-.. _table_rte_flow_action_modify_data:
+.. _table_rte_flow_field_data:
 
 .. table:: destination/source field definition
 
diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 84d3144215..efeda6ea97 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -124,6 +124,7 @@ ABI Changes
 
 * No ABI change that would break compatibility with 23.11.
 
+* ethdev: Rename the experimental ``struct rte_flow_action_modify_data`` to be ``struct rte_flow_field_data``
 
 Known Issues
 ------------
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 85e8c77c81..5788a7fb57 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2493,7 +2493,7 @@ mlx5_validate_action_ct(struct rte_eth_dev *dev,
  * Validate the level value for modify field action.
  *
  * @param[in] data
- *   Pointer to the rte_flow_action_modify_data structure either src or dst.
+ *   Pointer to the rte_flow_field_data structure either src or dst.
  * @param[out] error
  *   Pointer to error structure.
  *
@@ -2501,7 +2501,7 @@ mlx5_validate_action_ct(struct rte_eth_dev *dev,
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-flow_validate_modify_field_level(const struct rte_flow_action_modify_data *data,
+flow_validate_modify_field_level(const struct rte_flow_field_data *data,
 				 struct rte_flow_error *error)
 {
 	if (data->level == 0)
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 6dde9de688..ecfb04ead2 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -1121,7 +1121,7 @@ flow_items_to_tunnel(const struct rte_flow_item items[])
  *   Tag array index.
  */
 static inline uint8_t
-flow_tag_index_get(const struct rte_flow_action_modify_data *data)
+flow_tag_index_get(const struct rte_flow_field_data *data)
 {
 	return data->tag_index ? data->tag_index : data->level;
 }
@@ -2523,7 +2523,7 @@ int mlx5_flow_validate_action_default_miss(uint64_t action_flags,
 				const struct rte_flow_attr *attr,
 				struct rte_flow_error *error);
 int flow_validate_modify_field_level
-			(const struct rte_flow_action_modify_data *data,
+			(const struct rte_flow_field_data *data,
 			 struct rte_flow_error *error);
 int mlx5_flow_item_acceptable(const struct rte_flow_item *item,
 			      const uint8_t *mask,
@@ -2828,7 +2828,7 @@ size_t flow_dv_get_item_hdr_len(const enum rte_flow_item_type item_type);
 int flow_dv_convert_encap_data(const struct rte_flow_item *items, uint8_t *buf,
 			   size_t *size, struct rte_flow_error *error);
 void mlx5_flow_field_id_to_modify_info
-		(const struct rte_flow_action_modify_data *data,
+		(const struct rte_flow_field_data *data,
 		 struct field_modify_info *info, uint32_t *mask,
 		 uint32_t width, struct rte_eth_dev *dev,
 		 const struct rte_flow_attr *attr, struct rte_flow_error *error);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 115d730317..52620be262 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1441,7 +1441,7 @@ flow_modify_info_mask_32_masked(uint32_t length, uint32_t off, uint32_t post_mas
 }
 
 static __rte_always_inline enum mlx5_modification_field
-mlx5_mpls_modi_field_get(const struct rte_flow_action_modify_data *data)
+mlx5_mpls_modi_field_get(const struct rte_flow_field_data *data)
 {
 	return MLX5_MODI_IN_MPLS_LABEL_0 + data->tag_index;
 }
@@ -1449,7 +1449,7 @@ mlx5_mpls_modi_field_get(const struct rte_flow_action_modify_data *data)
 static void
 mlx5_modify_flex_item(const struct rte_eth_dev *dev,
 		      const struct mlx5_flex_item *flex,
-		      const struct rte_flow_action_modify_data *data,
+		      const struct rte_flow_field_data *data,
 		      struct field_modify_info *info,
 		      uint32_t *mask, uint32_t width)
 {
@@ -1573,7 +1573,7 @@ mlx5_modify_flex_item(const struct rte_eth_dev *dev,
 
 void
 mlx5_flow_field_id_to_modify_info
-		(const struct rte_flow_action_modify_data *data,
+		(const struct rte_flow_field_data *data,
 		 struct field_modify_info *info, uint32_t *mask,
 		 uint32_t width, struct rte_eth_dev *dev,
 		 const struct rte_flow_attr *attr, struct rte_flow_error *error)
@@ -5284,8 +5284,8 @@ flow_dv_validate_action_modify_field(struct rte_eth_dev *dev,
 	struct mlx5_sh_config *config = &priv->sh->config;
 	struct mlx5_hca_attr *hca_attr = &priv->sh->cdev->config.hca_attr;
 	const struct rte_flow_action_modify_field *conf = action->conf;
-	const struct rte_flow_action_modify_data *src_data = &conf->src;
-	const struct rte_flow_action_modify_data *dst_data = &conf->dst;
+	const struct rte_flow_field_data *src_data = &conf->src;
+	const struct rte_flow_field_data *dst_data = &conf->dst;
 	uint32_t dst_width, src_width, width = conf->width;
 
 	ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 1267c146e5..a143ecb194 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3887,6 +3887,8 @@ struct rte_flow_action_ethdev {
 
 /**
  * Field IDs for MODIFY_FIELD action.
+ * e.g. the packet field IDs used in RTE_FLOW_ACTION_TYPE_MODIFY_FIELD
+ * and RTE_FLOW_ITEM_TYPE_COMPARE.
  */
 enum rte_flow_field_id {
 	RTE_FLOW_FIELD_START = 0,	/**< Start of a packet. */
@@ -3940,9 +3942,11 @@ enum rte_flow_field_id {
  * @warning
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
- * Field description for MODIFY_FIELD action.
+ * Field description for packet field.
+ * e.g. the packet fields used in RTE_FLOW_ACTION_TYPE_MODIFY_FIELD
+ * and RTE_FLOW_ITEM_TYPE_COMPARE.
  */
-struct rte_flow_action_modify_data {
+struct rte_flow_field_data {
 	enum rte_flow_field_id field; /**< Field or memory type ID. */
 	union {
 		struct {
@@ -4051,8 +4055,8 @@ enum rte_flow_modify_op {
  */
 struct rte_flow_action_modify_field {
 	enum rte_flow_modify_op operation; /**< Operation to perform. */
-	struct rte_flow_action_modify_data dst; /**< Destination field. */
-	struct rte_flow_action_modify_data src; /**< Source field. */
+	struct rte_flow_field_data dst; /**< Destination field. */
+	struct rte_flow_field_data src; /**< Source field. */
 	uint32_t width; /**< Number of bits to use from a source field. */
 };
 
-- 
2.34.1


^ permalink raw reply	[relevance 7%]

* [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE
    2024-02-01  2:30  3% ` [PATCH v4 0/3] " Suanming Mou
@ 2024-02-01 12:29  3% ` Suanming Mou
  2024-02-01 12:29  7%   ` [PATCH v5 1/3] ethdev: rename action modify field data structure Suanming Mou
  2024-02-01 18:56  0%   ` [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Ferruh Yigit
  2024-02-02  0:42  3% ` [PATCH v6 " Suanming Mou
  2024-02-06  2:06  3% ` [PATCH v7 0/4] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Suanming Mou
  3 siblings, 2 replies; 200+ results
From: Suanming Mou @ 2024-02-01 12:29 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: dev, orika

The new item type is added for the case user wants to match traffic
based on packet field compare result with other fields or immediate
value.

e.g. take advantage the compare item user will be able to accumulate
a IPv4/TCP packet's TCP data_offset and IPv4 IHL field to a tag
register, then compare the tag register with IPv4 header total length
to understand the packet has payload or not.

The supported operations can be as below:
 - RTE_FLOW_ITEM_COMPARE_EQ (equal)
 - RTE_FLOW_ITEM_COMPARE_NE (not equal)
 - RTE_FLOW_ITEM_COMPARE_LT (less than)
 - RTE_FLOW_ITEM_COMPARE_LE (less than or equal)
 - RTE_FLOW_ITEM_COMPARE_GT (great than)
 - RTE_FLOW_ITEM_COMPARE_GE (great than or equal)

V5:
 - rebase on top of next-net
 - add sample detail for rte_flow_field.

V4:
 - rebase on top of the latest version.
 - move ACTION_MODIFY_PATTERN_SIZE and modify_field_ids rename
   to first patch.
 - add comparison flow create sample in testpmd_funcs.rst.

V3:
 - fix code style missing empty line in rte_flow.rst.
 - fix missing the ABI change release notes.

V2:
 - Since modify field data struct is experiment, rename modify
   field data directly instead of adding new flow field struct.


Suanming Mou (3):
  ethdev: rename action modify field data structure
  ethdev: add compare item
  net/mlx5: add compare item support

 app/test-pmd/cmdline_flow.c                 | 416 +++++++++++++++++++-
 doc/guides/nics/features/default.ini        |   1 +
 doc/guides/nics/features/mlx5.ini           |   1 +
 doc/guides/nics/mlx5.rst                    |   7 +
 doc/guides/prog_guide/rte_flow.rst          |   9 +-
 doc/guides/rel_notes/release_24_03.rst      |   8 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  24 ++
 drivers/net/mlx5/mlx5_flow.c                |   4 +-
 drivers/net/mlx5/mlx5_flow.h                |   9 +-
 drivers/net/mlx5/mlx5_flow_dv.c             |  10 +-
 drivers/net/mlx5/mlx5_flow_hw.c             |  73 ++++
 lib/ethdev/rte_flow.c                       |   1 +
 lib/ethdev/rte_flow.h                       | 332 +++++++++-------
 13 files changed, 726 insertions(+), 169 deletions(-)

-- 
2.34.1


^ permalink raw reply	[relevance 3%]

* Re: [PATCH] cfgfile: increase value length
  2024-02-01 10:32  3% ` David Marchand
@ 2024-02-01 12:01  0%   ` Varghese, Vipin
  0 siblings, 0 replies; 200+ results
From: Varghese, Vipin @ 2024-02-01 12:01 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, cristian.dumitrescu, Ferruh Yigit, Bruce Richardson


On 2/1/2024 4:02 PM, David Marchand wrote:
> Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.
>
>
> On Wed, Dec 6, 2023 at 12:31 PM Vipin Varghese <vipin.varghese@amd.com> wrote:
>> The default value for CFG_VALUE_LEN is set to 256 characters.
>> This limits the parsing for longer strings in configuration file.
>> Setting the default to 2048 characters increases the value array
>> size in `struct rte_cfgfile_entry`.
>>
>> Files using cfgfile library are
>> 1. drivers/net/mvpp2/
>> 2. app/test-dma-perf/
>> 3. app/test/
>> 4. examples/qos_sched/
>>
>> The structure `rte_cfgfile_entry` is not included in DPDK libraries.
>> Modifying from 256 to 2048 allows `app/test-dma-perf/main.c` helps to
>> parse longer string as shared in https://bugs.dpdk.org/show_bug.cgi?id=1333
>>
>> Signed-off-by: Vipin Varghese <vipin.varghese@amd.com>
>> Suggested-by: Ferruh Yigit <ferruh.yigit@amd.com>
>> ---
>>   lib/cfgfile/rte_cfgfile.h | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/lib/cfgfile/rte_cfgfile.h b/lib/cfgfile/rte_cfgfile.h
>> index 232c65c77b..401353c44e 100644
>> --- a/lib/cfgfile/rte_cfgfile.h
>> +++ b/lib/cfgfile/rte_cfgfile.h
>> @@ -24,7 +24,7 @@ extern "C" {
>>   #endif
>>
>>   #ifndef CFG_VALUE_LEN
>> -#define CFG_VALUE_LEN 256
>> +#define CFG_VALUE_LEN 2048
>>   #endif
>>
>>   /** Configuration file */
> Last time I looked at this code, I had the impression such a change
> would break the ABI.

Thanks David, Internally & 7 Dec 2023 based on the covnersation email 
from Bruce & Cristian; the new approach DPDK community should be taking 
is not to use comma seperated DMA instance.

Instead make DMA instances like `dma-1:, dma-2:, dma-3 ... etc`.


>
> I see that the discussion stopped at a suggestion to change some parsing logic.
> For now, I marked this patch as Changes requested.

I will make this deffer-ed or close the same.


>
> Thanks.
>
>
> --
> David Marchand
>

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] cfgfile: increase value length
    @ 2024-02-01 10:32  3% ` David Marchand
  2024-02-01 12:01  0%   ` Varghese, Vipin
  1 sibling, 1 reply; 200+ results
From: David Marchand @ 2024-02-01 10:32 UTC (permalink / raw)
  To: Vipin Varghese; +Cc: dev, cristian.dumitrescu, Ferruh Yigit, Bruce Richardson

On Wed, Dec 6, 2023 at 12:31 PM Vipin Varghese <vipin.varghese@amd.com> wrote:
>
> The default value for CFG_VALUE_LEN is set to 256 characters.
> This limits the parsing for longer strings in configuration file.
> Setting the default to 2048 characters increases the value array
> size in `struct rte_cfgfile_entry`.
>
> Files using cfgfile library are
> 1. drivers/net/mvpp2/
> 2. app/test-dma-perf/
> 3. app/test/
> 4. examples/qos_sched/
>
> The structure `rte_cfgfile_entry` is not included in DPDK libraries.
> Modifying from 256 to 2048 allows `app/test-dma-perf/main.c` helps to
> parse longer string as shared in https://bugs.dpdk.org/show_bug.cgi?id=1333
>
> Signed-off-by: Vipin Varghese <vipin.varghese@amd.com>
> Suggested-by: Ferruh Yigit <ferruh.yigit@amd.com>
> ---
>  lib/cfgfile/rte_cfgfile.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/lib/cfgfile/rte_cfgfile.h b/lib/cfgfile/rte_cfgfile.h
> index 232c65c77b..401353c44e 100644
> --- a/lib/cfgfile/rte_cfgfile.h
> +++ b/lib/cfgfile/rte_cfgfile.h
> @@ -24,7 +24,7 @@ extern "C" {
>  #endif
>
>  #ifndef CFG_VALUE_LEN
> -#define CFG_VALUE_LEN 256
> +#define CFG_VALUE_LEN 2048
>  #endif
>
>  /** Configuration file */

Last time I looked at this code, I had the impression such a change
would break the ABI.

I see that the discussion stopped at a suggestion to change some parsing logic.
For now, I marked this patch as Changes requested.

Thanks.


-- 
David Marchand


^ permalink raw reply	[relevance 3%]

* RE: [EXT] [PATCH 1/3] cryptodev: add ec points to sm2 op
  @ 2024-02-01  8:07  3% ` Akhil Goyal
  2024-02-01 13:25  0%   ` Kusztal, ArkadiuszX
  0 siblings, 1 reply; 200+ results
From: Akhil Goyal @ 2024-02-01  8:07 UTC (permalink / raw)
  To: Arkadiusz Kusztal, dev; +Cc: ciara.power

> ----------------------------------------------------------------------
> In the case when PMD cannot support full process of the SM2,
> but elliptic curve computation only, additional fields
> are needed to handle such a case.
> 

Asym crypto APIs are no longer experimental.
Hence adding new fields would lead to ABI break.

> Points C1, kP therefore were added to the SM2 crypto operation struct.
> 
> Signed-off-by: Arkadiusz Kusztal <arkadiuszx.kusztal@intel.com>

^ permalink raw reply	[relevance 3%]

* [PATCH v4 1/3] ethdev: rename action modify field data structure
  2024-02-01  2:30  3% ` [PATCH v4 0/3] " Suanming Mou
@ 2024-02-01  2:30  7%   ` Suanming Mou
  0 siblings, 0 replies; 200+ results
From: Suanming Mou @ 2024-02-01  2:30 UTC (permalink / raw)
  To: ferruh.yigit, Ori Kam, Aman Singh, Yuying Zhang, Matan Azrad,
	Viacheslav Ovsiienko, Thomas Monjalon, Andrew Rybchenko
  Cc: dev

Current rte_flow_action_modify_data struct describes the pkt
field perfectly and is used only in action.

It is planned to be used for item as well. This commit renames
it to "rte_flow_field_data" making it compatible to be used by item.

Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c            | 22 +++++++++++-----------
 doc/guides/prog_guide/rte_flow.rst     |  2 +-
 doc/guides/rel_notes/release_24_03.rst |  1 +
 drivers/net/mlx5/mlx5_flow.c           |  4 ++--
 drivers/net/mlx5/mlx5_flow.h           |  8 ++++----
 drivers/net/mlx5/mlx5_flow_dv.c        | 12 ++++++------
 drivers/net/mlx5/mlx5_flow_geneve.c    |  2 +-
 lib/ethdev/rte_flow.h                  |  8 ++++----
 8 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 4062879552..4741ec679d 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -745,13 +745,13 @@ enum index {
 #define ITEM_RAW_SIZE \
 	(sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE)
 
-/** Maximum size for external pattern in struct rte_flow_action_modify_data. */
-#define ACTION_MODIFY_PATTERN_SIZE 32
+/** Maximum size for external pattern in struct rte_flow_field_data. */
+#define FLOW_FIELD_PATTERN_SIZE 32
 
 /** Storage size for struct rte_flow_action_modify_field including pattern. */
 #define ACTION_MODIFY_SIZE \
 	(sizeof(struct rte_flow_action_modify_field) + \
-	ACTION_MODIFY_PATTERN_SIZE)
+	FLOW_FIELD_PATTERN_SIZE)
 
 /** Maximum number of queue indices in struct rte_flow_action_rss. */
 #define ACTION_RSS_QUEUE_NUM 128
@@ -945,7 +945,7 @@ static const char *const modify_field_ops[] = {
 	"set", "add", "sub", NULL
 };
 
-static const char *const modify_field_ids[] = {
+static const char *const flow_field_ids[] = {
 	"start", "mac_dst", "mac_src",
 	"vlan_type", "vlan_id", "mac_type",
 	"ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst",
@@ -7016,7 +7016,7 @@ static const struct token token_list[] = {
 			     ARGS_ENTRY_ARB(0, 0),
 			     ARGS_ENTRY_ARB
 				(sizeof(struct rte_flow_action_modify_field),
-				 ACTION_MODIFY_PATTERN_SIZE)),
+				 FLOW_FIELD_PATTERN_SIZE)),
 		.call = parse_vc_conf,
 	},
 	[ACTION_MODIFY_FIELD_WIDTH] = {
@@ -9828,10 +9828,10 @@ parse_vc_modify_field_id(struct context *ctx, const struct token *token,
 	if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE &&
 		ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)
 		return -1;
-	for (i = 0; modify_field_ids[i]; ++i)
-		if (!strcmp_partial(modify_field_ids[i], str, len))
+	for (i = 0; flow_field_ids[i]; ++i)
+		if (!strcmp_partial(flow_field_ids[i], str, len))
 			break;
-	if (!modify_field_ids[i])
+	if (!flow_field_ids[i])
 		return -1;
 	if (!ctx->object)
 		return len;
@@ -12058,10 +12058,10 @@ comp_set_modify_field_id(struct context *ctx, const struct token *token,
 
 	RTE_SET_USED(token);
 	if (!buf)
-		return RTE_DIM(modify_field_ids);
-	if (ent >= RTE_DIM(modify_field_ids) - 1)
+		return RTE_DIM(flow_field_ids);
+	if (ent >= RTE_DIM(flow_field_ids) - 1)
 		return -1;
-	name = modify_field_ids[ent];
+	name = flow_field_ids[ent];
 	if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE ||
 	    (strcmp(name, "pointer") && strcmp(name, "value")))
 		return strlcpy(buf, name, size);
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 900fdaefb6..f936a9ba19 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3185,7 +3185,7 @@ destination offset as ``48``, and provide immediate value ``0xXXXX85XX``.
    | ``width``     | number of bits to use   |
    +---------------+-------------------------+
 
-.. _table_rte_flow_action_modify_data:
+.. _table_rte_flow_field_data:
 
 .. table:: destination/source field definition
 
diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 2b91217943..b676683b42 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -140,6 +140,7 @@ ABI Changes
 
 * No ABI change that would break compatibility with 23.11.
 
+* ethdev: Rename the experimental ``struct rte_flow_action_modify_data`` to be ``struct rte_flow_field_data``
 
 Known Issues
 ------------
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 5159e8e773..40376c99ba 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2493,7 +2493,7 @@ mlx5_validate_action_ct(struct rte_eth_dev *dev,
  * Validate the level value for modify field action.
  *
  * @param[in] data
- *   Pointer to the rte_flow_action_modify_data structure either src or dst.
+ *   Pointer to the rte_flow_field_data structure either src or dst.
  * @param[out] error
  *   Pointer to error structure.
  *
@@ -2501,7 +2501,7 @@ mlx5_validate_action_ct(struct rte_eth_dev *dev,
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-flow_validate_modify_field_level(const struct rte_flow_action_modify_data *data,
+flow_validate_modify_field_level(const struct rte_flow_field_data *data,
 				 struct rte_flow_error *error)
 {
 	if (data->level == 0)
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index c9cc942d80..3f0699e986 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -1127,7 +1127,7 @@ flow_items_to_tunnel(const struct rte_flow_item items[])
  *   Tag array index.
  */
 static inline uint8_t
-flow_tag_index_get(const struct rte_flow_action_modify_data *data)
+flow_tag_index_get(const struct rte_flow_field_data *data)
 {
 	return data->tag_index ? data->tag_index : data->level;
 }
@@ -1839,7 +1839,7 @@ int mlx5_flow_geneve_tlv_option_validate(struct mlx5_priv *priv,
 					 const struct rte_flow_item *geneve_opt,
 					 struct rte_flow_error *error);
 int mlx5_geneve_opt_modi_field_get(struct mlx5_priv *priv,
-				   const struct rte_flow_action_modify_data *data);
+				   const struct rte_flow_field_data *data);
 
 struct mlx5_geneve_tlv_options_mng;
 int mlx5_geneve_tlv_option_register(struct mlx5_priv *priv,
@@ -2612,7 +2612,7 @@ int mlx5_flow_validate_action_default_miss(uint64_t action_flags,
 				const struct rte_flow_attr *attr,
 				struct rte_flow_error *error);
 int flow_validate_modify_field_level
-			(const struct rte_flow_action_modify_data *data,
+			(const struct rte_flow_field_data *data,
 			 struct rte_flow_error *error);
 int mlx5_flow_item_acceptable(const struct rte_flow_item *item,
 			      const uint8_t *mask,
@@ -2919,7 +2919,7 @@ size_t flow_dv_get_item_hdr_len(const enum rte_flow_item_type item_type);
 int flow_dv_convert_encap_data(const struct rte_flow_item *items, uint8_t *buf,
 			   size_t *size, struct rte_flow_error *error);
 void mlx5_flow_field_id_to_modify_info
-		(const struct rte_flow_action_modify_data *data,
+		(const struct rte_flow_field_data *data,
 		 struct field_modify_info *info, uint32_t *mask,
 		 uint32_t width, struct rte_eth_dev *dev,
 		 const struct rte_flow_attr *attr, struct rte_flow_error *error);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 6998be107f..a4ed7b1444 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1460,14 +1460,14 @@ flow_modify_info_mask_32_masked(uint32_t length, uint32_t off, uint32_t post_mas
 }
 
 static __rte_always_inline enum mlx5_modification_field
-mlx5_mpls_modi_field_get(const struct rte_flow_action_modify_data *data)
+mlx5_mpls_modi_field_get(const struct rte_flow_field_data *data)
 {
 	return MLX5_MODI_IN_MPLS_LABEL_0 + data->tag_index;
 }
 
 static __rte_always_inline int
 flow_geneve_opt_modi_field_get(struct mlx5_priv *priv,
-			       const struct rte_flow_action_modify_data *data)
+			       const struct rte_flow_field_data *data)
 {
 #ifdef HAVE_MLX5_HWS_SUPPORT
 	return mlx5_geneve_opt_modi_field_get(priv, data);
@@ -1483,7 +1483,7 @@ flow_geneve_opt_modi_field_get(struct mlx5_priv *priv,
 static void
 mlx5_modify_flex_item(const struct rte_eth_dev *dev,
 		      const struct mlx5_flex_item *flex,
-		      const struct rte_flow_action_modify_data *data,
+		      const struct rte_flow_field_data *data,
 		      struct field_modify_info *info,
 		      uint32_t *mask, uint32_t width)
 {
@@ -1613,7 +1613,7 @@ mlx5_dv_modify_ipv6_traffic_class_supported(struct mlx5_priv *priv)
 
 void
 mlx5_flow_field_id_to_modify_info
-		(const struct rte_flow_action_modify_data *data,
+		(const struct rte_flow_field_data *data,
 		 struct field_modify_info *info, uint32_t *mask,
 		 uint32_t width, struct rte_eth_dev *dev,
 		 const struct rte_flow_attr *attr, struct rte_flow_error *error)
@@ -5441,8 +5441,8 @@ flow_dv_validate_action_modify_field(struct rte_eth_dev *dev,
 	struct mlx5_sh_config *config = &priv->sh->config;
 	struct mlx5_hca_attr *hca_attr = &priv->sh->cdev->config.hca_attr;
 	const struct rte_flow_action_modify_field *conf = action->conf;
-	const struct rte_flow_action_modify_data *src_data = &conf->src;
-	const struct rte_flow_action_modify_data *dst_data = &conf->dst;
+	const struct rte_flow_field_data *src_data = &conf->src;
+	const struct rte_flow_field_data *dst_data = &conf->dst;
 	uint32_t dst_width, src_width, width = conf->width;
 
 	ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
diff --git a/drivers/net/mlx5/mlx5_flow_geneve.c b/drivers/net/mlx5/mlx5_flow_geneve.c
index d5847a60e9..d8086d333f 100644
--- a/drivers/net/mlx5/mlx5_flow_geneve.c
+++ b/drivers/net/mlx5/mlx5_flow_geneve.c
@@ -326,7 +326,7 @@ mlx5_get_geneve_option_modify_field_id(const void *dr_ctx, uint8_t type,
  */
 int
 mlx5_geneve_opt_modi_field_get(struct mlx5_priv *priv,
-			       const struct rte_flow_action_modify_data *data)
+			       const struct rte_flow_field_data *data)
 {
 	uint16_t class = data->class_id;
 	uint8_t type = data->type;
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 1267c146e5..d9965043e7 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3940,9 +3940,9 @@ enum rte_flow_field_id {
  * @warning
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
- * Field description for MODIFY_FIELD action.
+ * Field description for packet field.
  */
-struct rte_flow_action_modify_data {
+struct rte_flow_field_data {
 	enum rte_flow_field_id field; /**< Field or memory type ID. */
 	union {
 		struct {
@@ -4051,8 +4051,8 @@ enum rte_flow_modify_op {
  */
 struct rte_flow_action_modify_field {
 	enum rte_flow_modify_op operation; /**< Operation to perform. */
-	struct rte_flow_action_modify_data dst; /**< Destination field. */
-	struct rte_flow_action_modify_data src; /**< Source field. */
+	struct rte_flow_field_data dst; /**< Destination field. */
+	struct rte_flow_field_data src; /**< Source field. */
 	uint32_t width; /**< Number of bits to use from a source field. */
 };
 
-- 
2.34.1


^ permalink raw reply	[relevance 7%]

* [PATCH v4 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE
  @ 2024-02-01  2:30  3% ` Suanming Mou
  2024-02-01  2:30  7%   ` [PATCH v4 1/3] ethdev: rename action modify field data structure Suanming Mou
  2024-02-01 12:29  3% ` [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Suanming Mou
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 200+ results
From: Suanming Mou @ 2024-02-01  2:30 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: dev, orika

The new item type is added for the case user wants to match traffic
based on packet field compare result with other fields or immediate
value.

e.g. take advantage the compare item user will be able to accumulate
a IPv4/TCP packet's TCP data_offset and IPv4 IHL field to a tag
register, then compare the tag register with IPv4 header total length
to understand the packet has payload or not.

The supported operations can be as below:
 - RTE_FLOW_ITEM_COMPARE_EQ (equal)
 - RTE_FLOW_ITEM_COMPARE_NE (not equal)
 - RTE_FLOW_ITEM_COMPARE_LT (less than)
 - RTE_FLOW_ITEM_COMPARE_LE (less than or equal)
 - RTE_FLOW_ITEM_COMPARE_GT (great than)
 - RTE_FLOW_ITEM_COMPARE_GE (great than or equal)

V4:
 - rebase on top of the latest version.
 - move ACTION_MODIFY_PATTERN_SIZE and modify_field_ids rename
   to first patch.
 - add comparison flow create sample in testpmd_funcs.rst.

V3:
 - fix code style missing empty line in rte_flow.rst.
 - fix missing the ABI change release notes.

V2:
 - Since modify field data struct is experiment, rename modify
   field data directly instead of adding new flow field struct.

Suanming Mou (3):
  ethdev: rename action modify field data structure
  ethdev: add compare item
  net/mlx5: add compare item support

 app/test-pmd/cmdline_flow.c                 | 416 +++++++++++++++++++-
 doc/guides/nics/features/default.ini        |   1 +
 doc/guides/nics/features/mlx5.ini           |   1 +
 doc/guides/nics/mlx5.rst                    |   7 +
 doc/guides/prog_guide/rte_flow.rst          |   9 +-
 doc/guides/rel_notes/release_24_03.rst      |   8 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  24 ++
 drivers/net/mlx5/mlx5_flow.c                |   4 +-
 drivers/net/mlx5/mlx5_flow.h                |  11 +-
 drivers/net/mlx5/mlx5_flow_dv.c             |  12 +-
 drivers/net/mlx5/mlx5_flow_geneve.c         |   2 +-
 drivers/net/mlx5/mlx5_flow_hw.c             |  75 +++-
 lib/ethdev/rte_flow.c                       |   1 +
 lib/ethdev/rte_flow.h                       | 328 ++++++++-------
 14 files changed, 725 insertions(+), 174 deletions(-)

-- 
2.34.1


^ permalink raw reply	[relevance 3%]

* RE: [PATCH] mbuf: replace GCC marker extension with C11 anonymous unions
  2024-01-31 20:45  0%     ` Tyler Retzlaff
@ 2024-01-31 22:55  4%       ` Morten Brørup
  0 siblings, 0 replies; 200+ results
From: Morten Brørup @ 2024-01-31 22:55 UTC (permalink / raw)
  To: Tyler Retzlaff, Bruce Richardson
  Cc: dev, Andrew Boyer, Andrew Rybchenko, Chenbo Xia,
	Konstantin Ananyev, Maxime Coquelin

> From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com]
> Sent: Wednesday, 31 January 2024 21.46
> 
> On Wed, Jan 31, 2024 at 01:49:34PM +0000, Bruce Richardson wrote:
> > On Tue, Jan 30, 2024 at 03:26:13PM -0800, Tyler Retzlaff wrote:
> > > Replace the use of RTE_MARKER<x> with C11 anonymous unions to
> improve
> > > code portability between toolchains.
> > >
> > > Update use of rte_mbuf rearm_data field in net/ionic, net/sfc and
> > > net/virtio which were accessing field as a zero-length array.
> > >
> > > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> > > ---
> > >  drivers/net/ionic/ionic_lif.c               |   8 +-
> > >  drivers/net/ionic/ionic_rxtx_sg.c           |   4 +-
> > >  drivers/net/ionic/ionic_rxtx_simple.c       |   2 +-
> > >  drivers/net/sfc/sfc_ef100_rx.c              |   8 +-
> > >  drivers/net/sfc/sfc_ef10_rx.c               |  12 +--
> > >  drivers/net/virtio/virtio_rxtx_packed_avx.h |   8 +-
> > >  lib/mbuf/rte_mbuf_core.h                    | 135 +++++++++++++++-
> ------------
> > >  7 files changed, 94 insertions(+), 83 deletions(-)
> > >
> > <snip>
> > @@ -464,9 +464,10 @@ enum {
> > >   * The generic rte_mbuf, containing a packet mbuf.
> > >   */
> > >  struct rte_mbuf {
> > > -	RTE_MARKER cacheline0;
> > > -
> > > -	void *buf_addr;           /**< Virtual address of segment buffer.
> */
> > > +	union {
> > > +	    void *cacheline0;
> > > +	    void *buf_addr;           /**< Virtual address of segment
> buffer. */
> > > +	};
> >
> > This marker is never used, so we should just look to drop it. I think
> it
> > was originally added to have an equivalent to the cacheline1 marker.
> 
> it's actually got a use in one location.
> 
> rte_mbuf.h:
> 
> static inline void
> rte_mbuf_prefetch_part1(struct rte_mbuf *m)
> {	
>         rte_prefetch0(&m->cacheline0);
> }	
> 
> > However, that would be an ABI change, so I'm ok to have this as-is
> for now.

Typo: API change, not ABI change.

> 
> do you mean api change? just asking to make sure i understand what i'm
> doing.
> 
> as i understand how this extension (marker) works removing the
> cacheline0 marker would not alter the layout of the struct. that is the
> sizeof the struct, sizeof any field nor the offset of any field changes
> would change by the marker removal.

Correctly understood, Tyler.

The struct layout is unmodified, so it's not an ABI change.
However, it's an API change, because applications cannot access the field anymore.

Although DPDK itself doesn't use the field, other applications might use rte_prefetch0(&m->cacheline0) instead of rte_mbuf_prefetch_part1(m).
After checking in-house, I can mention at least one company doing that. ;-)

We should keep the cacheline0 field and not break the API. Not for my sake, but for other applications. :-)


^ permalink raw reply	[relevance 4%]

* RE: [PATCH] mbuf: replace GCC marker extension with C11 anonymous unions
  2024-01-31 21:09  3%     ` Tyler Retzlaff
@ 2024-01-31 22:39  3%       ` Morten Brørup
  0 siblings, 0 replies; 200+ results
From: Morten Brørup @ 2024-01-31 22:39 UTC (permalink / raw)
  To: Tyler Retzlaff
  Cc: dev, Andrew Boyer, Andrew Rybchenko, Bruce Richardson,
	Chenbo Xia, Konstantin Ananyev, Maxime Coquelin

> From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com]
> Sent: Wednesday, 31 January 2024 22.09
> 
> On Wed, Jan 31, 2024 at 10:18:37AM +0100, Morten Brørup wrote:
> > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com]
> > > Sent: Wednesday, 31 January 2024 00.26
> > >

[...]

> > >  	struct rte_mempool *pool; /**< Pool from which mbuf was
> > > allocated. */
> > >
> > >  	/* second cache line - fields only used in slow path or on TX */
> > > -	RTE_MARKER cacheline1 __rte_cache_min_aligned;
> > > +	union {
> > > +		void *cacheline1;
> >
> > The __rte_cache_min_aligned cannot be removed. It provides cache line
> alignment for 32 bit platforms, where pointers in the first cache line
> only use 4 byte.
> 
> oh no i forgot i needed to figure this out before submission. now that
> it's here though i could use some help / suggestions.
> 
> the existing __rte_cache_min_aligned (and indeed standard alignas)
> facilities are not of great utility when applied to anonymous unions,
> further complicating things is that it also has to work with C++.
> 
> i'll take this away and work on it some more but does anyone here have
> a
> suggestion on how to align this anonymous union data member to the
> desired alignment *without* the union being padded to min cache line
> size and as a consequence causing the rte_mbuf struct to be 3 instead
> of 2 cache lines? (that's essentially the problem i need help solving).

I would suggest to simply remove __rte_cache_min_aligned (and the implicit padding that comes with it), and instead conditionally (#ifdef RTE_ARCH_32) add an explicit uintptr_t padding field after each pointer field in the rte_mbuf struct's first cache line.

But that would break the 32-bit ABI, so instead insert the explicit padding in the rte_mbuf struct at the end of its first cache line (where the implicit padding from __rte_cache_min_aligned is currently added), something like this:

	struct rte_mempool *pool; /**< Pool from which mbuf was allocated. */

+#ifdef RTE_ARCH_32
+	/* Padding to ensure correct alignment of cacheline1. */
+	uintptr_t pad_buf_addr;
+#if !RTE_IOVA_IN_MBUF
+	uintptr_t pad_next;
+#endif
+#endif /* RTE_ARCH_32 */

	/* second cache line - fields only used in slow path or on TX */

To be on the safe side, add a static_assert to verify that offsetof(struct rte_mbuf, cacheline1) == RTE_CACHE_LINE_MIN_SIZE. This should be true for all architectures, i.e. both 64 bit and 32 bit.


^ permalink raw reply	[relevance 3%]

* Re: [PATCH] mbuf: replace GCC marker extension with C11 anonymous unions
  @ 2024-01-31 21:09  3%     ` Tyler Retzlaff
  2024-01-31 22:39  3%       ` Morten Brørup
  0 siblings, 1 reply; 200+ results
From: Tyler Retzlaff @ 2024-01-31 21:09 UTC (permalink / raw)
  To: Morten Brørup
  Cc: dev, Andrew Boyer, Andrew Rybchenko, Bruce Richardson,
	Chenbo Xia, Konstantin Ananyev, Maxime Coquelin

On Wed, Jan 31, 2024 at 10:18:37AM +0100, Morten Brørup wrote:
> > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com]
> > Sent: Wednesday, 31 January 2024 00.26
> > 
> > Replace the use of RTE_MARKER<x> with C11 anonymous unions to improve
> > code portability between toolchains.
> > 
> > Update use of rte_mbuf rearm_data field in net/ionic, net/sfc and
> > net/virtio which were accessing field as a zero-length array.
> > 
> > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> > ---
> 
> I have some comments, putting weight on code readability rather than avoiding API breakage.
> 
> We can consider my suggested API breaking changes for the next API breaking release, and keep your goal of minimal API breakage with the current changes.

thanks appreciate your help with this one.

> 
> > diff --git a/lib/mbuf/rte_mbuf_core.h b/lib/mbuf/rte_mbuf_core.h
> > index 5688683..d731ea0 100644
> > --- a/lib/mbuf/rte_mbuf_core.h
> > +++ b/lib/mbuf/rte_mbuf_core.h
> > @@ -464,9 +464,10 @@ enum {
> >   * The generic rte_mbuf, containing a packet mbuf.
> >   */
> >  struct rte_mbuf {
> > -	RTE_MARKER cacheline0;
> > -
> > -	void *buf_addr;           /**< Virtual address of segment buffer.
> > */
> > +	union {
> > +	    void *cacheline0;
> > +	    void *buf_addr;           /**< Virtual address of segment
> > buffer. */
> > +	};
> 
> I suppose this is the least ugly workaround for not being able to use the RTE_MARKER hack here.

it is but i'm absolutely open to alternatives that work with all
toolchains and both C and C++ if there are any.

> 
> >  #if RTE_IOVA_IN_MBUF
> >  	/**
> >  	 * Physical address of segment buffer.
> > @@ -487,69 +488,77 @@ struct rte_mbuf {
> >  #endif
> > 
> >  	/* next 8 bytes are initialised on RX descriptor rearm */
> > -	RTE_MARKER64 rearm_data;
> > -	uint16_t data_off;
> > -
> > -	/**
> > -	 * Reference counter. Its size should at least equal to the size
> > -	 * of port field (16 bits), to support zero-copy broadcast.
> > -	 * It should only be accessed using the following functions:
> > -	 * rte_mbuf_refcnt_update(), rte_mbuf_refcnt_read(), and
> > -	 * rte_mbuf_refcnt_set(). The functionality of these functions
> > (atomic,
> > -	 * or non-atomic) is controlled by the RTE_MBUF_REFCNT_ATOMIC
> > flag.
> > -	 */
> > -	RTE_ATOMIC(uint16_t) refcnt;
> > +	union {
> > +		uint64_t rearm_data;
> 
> I consider this union with uint64_t rearm_data an improvement for code readability. Using a marker here was weird.
> 
> > +		struct {
> > +			uint16_t data_off;
> > +
> > +			/**
> > +			 * Reference counter. Its size should at least equal
> > to the size
> > +			 * of port field (16 bits), to support zero-copy
> > broadcast.
> > +			 * It should only be accessed using the following
> > functions:
> > +			 * rte_mbuf_refcnt_update(), rte_mbuf_refcnt_read(),
> > and
> > +			 * rte_mbuf_refcnt_set(). The functionality of these
> > functions (atomic,
> > +			 * or non-atomic) is controlled by the
> > RTE_MBUF_REFCNT_ATOMIC flag.
> > +			 */
> > +			RTE_ATOMIC(uint16_t) refcnt;
> > 
> > -	/**
> > -	 * Number of segments. Only valid for the first segment of an
> > mbuf
> > -	 * chain.
> > -	 */
> > -	uint16_t nb_segs;
> > +			/**
> > +			 * Number of segments. Only valid for the first
> > segment of an mbuf
> > +			 * chain.
> > +			 */
> > +			uint16_t nb_segs;
> > 
> > -	/** Input port (16 bits to support more than 256 virtual ports).
> > -	 * The event eth Tx adapter uses this field to specify the output
> > port.
> > -	 */
> > -	uint16_t port;
> > +			/** Input port (16 bits to support more than 256
> > virtual ports).
> > +			 * The event eth Tx adapter uses this field to
> > specify the output port.
> > +			 */
> > +			uint16_t port;
> > 
> > -	uint64_t ol_flags;        /**< Offload features. */
> > +			uint64_t ol_flags;        /**< Offload features. */
> 
> Either:
> 1. If the comment about 8 bytes init on rearm is correct: ol_flags should remain outside the struct and union, i.e. at top level, else

> 2. It would be nice to increase the size of the rearm_data variable to 16 byte, so it covers the entire struct being rearmed. (And the incorrect comment about how many bytes are being rearmed should be fixed.)
> 

thanks for picking this up, i think i've actually just got a mistake
here. i don't think ol_flags should have been lifted into the union i'll
go back and do some double checking.

> > +		};
> > +	};
> > 
> >  	/* remaining bytes are set on RX when pulling packet from
> > descriptor */
> > -	RTE_MARKER rx_descriptor_fields1;
> > -
> > -	/*
> > -	 * The packet type, which is the combination of outer/inner L2,
> > L3, L4
> > -	 * and tunnel types. The packet_type is about data really present
> > in the
> > -	 * mbuf. Example: if vlan stripping is enabled, a received vlan
> > packet
> > -	 * would have RTE_PTYPE_L2_ETHER and not RTE_PTYPE_L2_VLAN
> > because the
> > -	 * vlan is stripped from the data.
> > -	 */
> >  	union {
> > -		uint32_t packet_type; /**< L2/L3/L4 and tunnel information.
> > */
> > -		__extension__
> > +		void *rx_descriptor_fields1;
> 
> Instead of using void* for rx_descriptor_fields1, it would be nice to make rx_descriptor_fields1 a type of the correct size. It might need to be an uint32_t array to avoid imposing additional alignment requirements.

as you've probably guessed i used the type from the original marker in
use. for api compat reasons i'll avoid changing type in this series.

> 
> > +
> > +		/*
> > +		 * The packet type, which is the combination of outer/inner
> > L2, L3, L4
> > +		 * and tunnel types. The packet_type is about data really
> > present in the
> > +		 * mbuf. Example: if vlan stripping is enabled, a received
> > vlan packet
> > +		 * would have RTE_PTYPE_L2_ETHER and not RTE_PTYPE_L2_VLAN
> > because the
> > +		 * vlan is stripped from the data.
> > +		 */
> >  		struct {
> > -			uint8_t l2_type:4;   /**< (Outer) L2 type. */
> > -			uint8_t l3_type:4;   /**< (Outer) L3 type. */
> > -			uint8_t l4_type:4;   /**< (Outer) L4 type. */
> > -			uint8_t tun_type:4;  /**< Tunnel type. */
> >  			union {
> > -				uint8_t inner_esp_next_proto;
> > -				/**< ESP next protocol type, valid if
> > -				 * RTE_PTYPE_TUNNEL_ESP tunnel type is set
> > -				 * on both Tx and Rx.
> > -				 */
> > +				uint32_t packet_type; /**< L2/L3/L4 and tunnel
> > information. */
> >  				__extension__
> >  				struct {
> > -					uint8_t inner_l2_type:4;
> > -					/**< Inner L2 type. */
> > -					uint8_t inner_l3_type:4;
> > -					/**< Inner L3 type. */
> > +					uint8_t l2_type:4;   /**< (Outer) L2
> > type. */
> > +					uint8_t l3_type:4;   /**< (Outer) L3
> > type. */
> > +					uint8_t l4_type:4;   /**< (Outer) L4
> > type. */
> > +					uint8_t tun_type:4;  /**< Tunnel type. */
> > +					union {
> > +						uint8_t inner_esp_next_proto;
> > +						/**< ESP next protocol type, valid
> > if
> > +						 * RTE_PTYPE_TUNNEL_ESP tunnel type
> > is set
> > +						 * on both Tx and Rx.
> > +						 */
> > +						__extension__
> > +						struct {
> > +							uint8_t inner_l2_type:4;
> > +							/**< Inner L2 type. */
> > +							uint8_t inner_l3_type:4;
> > +							/**< Inner L3 type. */
> > +						};
> > +					};
> > +					uint8_t inner_l4_type:4; /**< Inner L4
> > type. */
> >  				};
> >  			};
> > -			uint8_t inner_l4_type:4; /**< Inner L4 type. */
> > +			uint32_t pkt_len;         /**< Total pkt len: sum of
> > all segments. */
> >  		};
> >  	};
> > 
> > -	uint32_t pkt_len;         /**< Total pkt len: sum of all
> > segments. */
> >  	uint16_t data_len;        /**< Amount of data in segment buffer.
> > */
> >  	/** VLAN TCI (CPU order), valid if RTE_MBUF_F_RX_VLAN is set. */
> >  	uint16_t vlan_tci;
> > @@ -595,21 +604,23 @@ struct rte_mbuf {
> >  	struct rte_mempool *pool; /**< Pool from which mbuf was
> > allocated. */
> > 
> >  	/* second cache line - fields only used in slow path or on TX */
> > -	RTE_MARKER cacheline1 __rte_cache_min_aligned;
> > +	union {
> > +		void *cacheline1;
> 
> The __rte_cache_min_aligned cannot be removed. It provides cache line alignment for 32 bit platforms, where pointers in the first cache line only use 4 byte.

oh no i forgot i needed to figure this out before submission. now that
it's here though i could use some help / suggestions.

the existing __rte_cache_min_aligned (and indeed standard alignas)
facilities are not of great utility when applied to anonymous unions,
further complicating things is that it also has to work with C++.

i'll take this away and work on it some more but does anyone here have a
suggestion on how to align this anonymous union data member to the
desired alignment *without* the union being padded to min cache line
size and as a consequence causing the rte_mbuf struct to be 3 instead
of 2 cache lines? (that's essentially the problem i need help solving).

> 
> NB: The rte_mbuf structure could be optimized for 32 bit platforms by moving fields from the second cache line to the holes in the first, but that's another discussion.

likely could be optimized. a discussion for another time since we can't make
breaking abi changes.

> 
> > 
> >  #if RTE_IOVA_IN_MBUF
> > -	/**
> > -	 * Next segment of scattered packet. Must be NULL in the last
> > -	 * segment or in case of non-segmented packet.
> > -	 */
> > -	struct rte_mbuf *next;
> > +		/**
> > +		 * Next segment of scattered packet. Must be NULL in the
> > last
> > +		 * segment or in case of non-segmented packet.
> > +		 */
> > +		struct rte_mbuf *next;
> >  #else
> > -	/**
> > -	 * Reserved for dynamic fields
> > -	 * when the next pointer is in first cache line (i.e.
> > RTE_IOVA_IN_MBUF is 0).
> > -	 */
> > -	uint64_t dynfield2;
> > +		/**
> > +		 * Reserved for dynamic fields
> > +		 * when the next pointer is in first cache line (i.e.
> > RTE_IOVA_IN_MBUF is 0).
> > +		 */
> > +		uint64_t dynfield2;
> >  #endif
> > +	};
> > 
> >  	/* fields to support TX offloads */
> >  	union {
> > --
> > 1.8.3.1

^ permalink raw reply	[relevance 3%]

* Re: [PATCH] mbuf: replace GCC marker extension with C11 anonymous unions
  2024-01-31 13:49  3%   ` Bruce Richardson
@ 2024-01-31 20:45  0%     ` Tyler Retzlaff
  2024-01-31 22:55  4%       ` Morten Brørup
  0 siblings, 1 reply; 200+ results
From: Tyler Retzlaff @ 2024-01-31 20:45 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, Andrew Boyer, Andrew Rybchenko, Chenbo Xia,
	Konstantin Ananyev, Maxime Coquelin

On Wed, Jan 31, 2024 at 01:49:34PM +0000, Bruce Richardson wrote:
> On Tue, Jan 30, 2024 at 03:26:13PM -0800, Tyler Retzlaff wrote:
> > Replace the use of RTE_MARKER<x> with C11 anonymous unions to improve
> > code portability between toolchains.
> > 
> > Update use of rte_mbuf rearm_data field in net/ionic, net/sfc and
> > net/virtio which were accessing field as a zero-length array.
> > 
> > Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> > ---
> >  drivers/net/ionic/ionic_lif.c               |   8 +-
> >  drivers/net/ionic/ionic_rxtx_sg.c           |   4 +-
> >  drivers/net/ionic/ionic_rxtx_simple.c       |   2 +-
> >  drivers/net/sfc/sfc_ef100_rx.c              |   8 +-
> >  drivers/net/sfc/sfc_ef10_rx.c               |  12 +--
> >  drivers/net/virtio/virtio_rxtx_packed_avx.h |   8 +-
> >  lib/mbuf/rte_mbuf_core.h                    | 135 +++++++++++++++-------------
> >  7 files changed, 94 insertions(+), 83 deletions(-)
> > 
> <snip>
> @@ -464,9 +464,10 @@ enum {
> >   * The generic rte_mbuf, containing a packet mbuf.
> >   */
> >  struct rte_mbuf {
> > -	RTE_MARKER cacheline0;
> > -
> > -	void *buf_addr;           /**< Virtual address of segment buffer. */
> > +	union {
> > +	    void *cacheline0;
> > +	    void *buf_addr;           /**< Virtual address of segment buffer. */
> > +	};
> 
> This marker is never used, so we should just look to drop it. I think it
> was originally added to have an equivalent to the cacheline1 marker.

it's actually got a use in one location.

rte_mbuf.h:

static inline void
rte_mbuf_prefetch_part1(struct rte_mbuf *m)
{
        rte_prefetch0(&m->cacheline0);
}

> However, that would be an ABI change, so I'm ok to have this as-is for now.

do you mean api change? just asking to make sure i understand what i'm
doing.

as i understand how this extension (marker) works removing the
cacheline0 marker would not alter the layout of the struct. that is the
sizeof the struct, sizeof any field nor the offset of any field changes
would change by the marker removal.

> 
> /Bruce

^ permalink raw reply	[relevance 0%]

* [PATCH 2/2] ci: update versions of actions in GHA
  2024-01-31 17:44  4% [PATCH 1/2] ci: bump tested distributions in GHA David Marchand
@ 2024-01-31 17:44  6% ` David Marchand
  0 siblings, 0 replies; 200+ results
From: David Marchand @ 2024-01-31 17:44 UTC (permalink / raw)
  To: dev; +Cc: stable, Aaron Conole, Michael Santana

GitHub started deprecating GHA actions based on Node 16 [1].
For now, only warnings are raised, but we might as well switch to v4
versions of the common actions, now.

Link: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/

Cc: stable@dpdk.org

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 .github/workflows/build.yml | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 421207c241..776fbf6f30 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -72,7 +72,7 @@ jobs:
 
     steps:
     - name: Checkout sources
-      uses: actions/checkout@v3
+      uses: actions/checkout@v4
     - name: Generate cache keys
       id: get_ref_keys
       run: |
@@ -80,7 +80,7 @@ jobs:
         echo 'libabigail=libabigail-${{ env.LIBABIGAIL_VERSION }}-${{ matrix.config.os }}' >> $GITHUB_OUTPUT
         echo 'abi=abi-${{ matrix.config.os }}-${{ matrix.config.compiler }}-${{ matrix.config.cross }}-${{ env.REF_GIT_TAG }}' >> $GITHUB_OUTPUT
     - name: Retrieve ccache cache
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       with:
         path: ~/.ccache
         key: ${{ steps.get_ref_keys.outputs.ccache }}-${{ github.ref }}
@@ -88,13 +88,13 @@ jobs:
           ${{ steps.get_ref_keys.outputs.ccache }}-refs/heads/main
     - name: Retrieve libabigail cache
       id: libabigail-cache
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       if: env.ABI_CHECKS == 'true'
       with:
         path: libabigail
         key: ${{ steps.get_ref_keys.outputs.libabigail }}
     - name: Retrieve ABI reference cache
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       if: env.ABI_CHECKS == 'true'
       with:
         path: reference
@@ -143,7 +143,7 @@ jobs:
       run: .ci/linux-build.sh
     - name: Upload logs on failure
       if: failure()
-      uses: actions/upload-artifact@v3
+      uses: actions/upload-artifact@v4
       with:
         name: meson-logs-${{ join(matrix.config.*, '-') }}
         path: |
@@ -171,7 +171,7 @@ jobs:
         echo 'image=image-${{ matrix.config.image }}-'$(date -u +%Y-%m-%d) >> $GITHUB_OUTPUT
     - name: Retrieve image cache
       id: image_cache
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       with:
         path: ~/.image
         key: ${{ steps.get_keys.outputs.image }}
@@ -218,7 +218,7 @@ jobs:
 
     steps:
     - name: Checkout sources
-      uses: actions/checkout@v3
+      uses: actions/checkout@v4
     - name: Generate various keys
       id: get_keys
       run: |
@@ -226,7 +226,7 @@ jobs:
         echo 'logs=meson-logs-${{ join(matrix.config.*, '-') }}' | tr -d ':' >> $GITHUB_OUTPUT
     - name: Retrieve image cache
       id: image_cache
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       with:
         path: ~/.image
         key: ${{ needs.prepare-container-images.outputs.image }}
@@ -236,7 +236,7 @@ jobs:
         echo 'Image ${{ matrix.config.image }} is not cached.'
         false
     - name: Retrieve ccache cache
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       with:
         path: ~/.ccache
         key: ${{ steps.get_keys.outputs.ccache }}-${{ github.ref }}
@@ -276,7 +276,7 @@ jobs:
       run: docker kill dpdk
     - name: Upload logs on failure
       if: failure()
-      uses: actions/upload-artifact@v3
+      uses: actions/upload-artifact@v4
       with:
         name: ${{ steps.get_keys.outputs.logs }}
         path: |
-- 
2.43.0


^ permalink raw reply	[relevance 6%]

* [PATCH 1/2] ci: bump tested distributions in GHA
@ 2024-01-31 17:44  4% David Marchand
  2024-01-31 17:44  6% ` [PATCH 2/2] ci: update versions of actions " David Marchand
  0 siblings, 1 reply; 200+ results
From: David Marchand @ 2024-01-31 17:44 UTC (permalink / raw)
  To: dev; +Cc: Aaron Conole, Michael Santana

Fedora 37 has reached end of life in December 2023.
Ubuntu 20.04 is getting quite old.

Switch to more recent versions.

With this move, some packages provided by those distributions are now
recent enough to extend our build coverage.
Install additional dependencies like ipsec-mb, isal and other
libbpf/libxdp devel packages.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 .github/workflows/build.yml | 54 ++++++++++++++++++-------------------
 1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index af514e9545..421207c241 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -36,37 +36,37 @@ jobs:
       fail-fast: false
       matrix:
         config:
-          - os: ubuntu-20.04
+          - os: ubuntu-22.04
             compiler: gcc
             mini: mini
-          - os: ubuntu-20.04
+          - os: ubuntu-22.04
             compiler: gcc
             checks: stdatomic
-          - os: ubuntu-20.04
+          - os: ubuntu-22.04
             compiler: clang
             checks: stdatomic
-          - os: ubuntu-20.04
+          - os: ubuntu-22.04
             compiler: gcc
             checks: abi+debug+doc+examples+tests
-          - os: ubuntu-20.04
+          - os: ubuntu-22.04
             compiler: clang
             checks: asan+doc+tests
-          - os: ubuntu-20.04
+          - os: ubuntu-22.04
             compiler: gcc
             library: static
             cross: i386
-          - os: ubuntu-20.04
+          - os: ubuntu-22.04
             compiler: gcc
             library: static
             cross: mingw
-          - os: ubuntu-20.04
+          - os: ubuntu-22.04
             compiler: gcc
             library: shared
             cross: aarch64
-          - os: ubuntu-20.04
+          - os: ubuntu-22.04
             compiler: gcc
             cross: ppc64le
-          - os: ubuntu-20.04
+          - os: ubuntu-22.04
             compiler: gcc
             cross: riscv64
 
@@ -105,10 +105,10 @@ jobs:
     - name: Update APT cache
       run: sudo apt update || true
     - name: Install packages
-      run: sudo apt install -y ccache libarchive-dev libbsd-dev libfdt-dev
-        libibverbs-dev libjansson-dev libnuma-dev libpcap-dev libssl-dev
-        ninja-build pkg-config python3-pip python3-pyelftools python3-setuptools
-        python3-wheel zlib1g-dev
+      run: sudo apt install -y ccache libarchive-dev libbsd-dev libbpf-dev
+        libfdt-dev libibverbs-dev libipsec-mb-dev libisal-dev libjansson-dev
+        libnuma-dev libpcap-dev libssl-dev ninja-build pkg-config python3-pip
+        python3-pyelftools python3-setuptools python3-wheel zlib1g-dev
     - name: Install libabigail build dependencies if no cache is available
       if: env.ABI_CHECKS == 'true' && steps.libabigail-cache.outputs.cache-hit != 'true'
       run: sudo apt install -y autoconf automake libdw-dev libtool libxml2-dev
@@ -162,7 +162,7 @@ jobs:
       fail-fast: false
       matrix:
         config:
-          - image: fedora:37
+          - image: fedora:39
 
     steps:
     - name: Generate various keys
@@ -187,11 +187,11 @@ jobs:
       run: docker exec -i dpdk dnf update -y
     - name: Install packages
       if: steps.image_cache.outputs.cache-hit != 'true'
-      run: docker exec -i dpdk dnf install -y ccache jansson-devel
-        libarchive-devel libatomic libbsd-devel libbpf-devel libfdt-devel
-        libpcap-devel ninja-build numactl-devel openssl-devel python3-pip
-        python3-pyelftools python3-setuptools python3-wheel rdma-core-devel
-        zlib-devel
+      run: docker exec -i dpdk dnf install -y ccache intel-ipsec-mb-devel
+        isa-l-devel jansson-devel libarchive-devel libatomic libbsd-devel
+        libbpf-devel libfdt-devel libpcap-devel libxdp-devel ninja-build
+        numactl-devel openssl-devel python3-pip python3-pyelftools
+        python3-setuptools python3-wheel rdma-core-devel zlib-devel
     - name: Save image in cache
       if: steps.image_cache.outputs.cache-hit != 'true'
       run: |
@@ -211,9 +211,9 @@ jobs:
       fail-fast: false
       matrix:
         config:
-          - image: fedora:37
+          - image: fedora:39
             compiler: gcc
-          - image: fedora:37
+          - image: fedora:39
             compiler: clang
 
     steps:
@@ -262,11 +262,11 @@ jobs:
     - name: Update
       run: docker exec -i dpdk dnf update -y || true
     - name: Install packages
-      run: docker exec -i dpdk dnf install -y ccache jansson-devel
-        libarchive-devel libatomic libbsd-devel libxdp-devel libfdt-devel
-        libpcap-devel ninja-build numactl-devel openssl-devel python3-pip
-        python3-pyelftools python3-setuptools python3-wheel rdma-core-devel
-        zlib-devel
+      run: docker exec -i dpdk dnf install -y ccache intel-ipsec-mb-devel
+        isa-l-devel jansson-devel libarchive-devel libatomic libbsd-devel
+        libbpf-devel libfdt-devel libpcap-devel libxdp-devel ninja-build
+        numactl-devel openssl-devel python3-pip python3-pyelftools
+        python3-setuptools python3-wheel rdma-core-devel zlib-devel
         ${{ matrix.config.compiler }}
     - name: Run setup
       run: docker exec -i dpdk .ci/linux-setup.sh
-- 
2.43.0


^ permalink raw reply	[relevance 4%]

* Re: [PATCH] mbuf: replace GCC marker extension with C11 anonymous unions
    @ 2024-01-31 13:49  3%   ` Bruce Richardson
  2024-01-31 20:45  0%     ` Tyler Retzlaff
  2024-02-13  6:45  3%   ` [PATCH v2] RFC: " Tyler Retzlaff
  2 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2024-01-31 13:49 UTC (permalink / raw)
  To: Tyler Retzlaff
  Cc: dev, Andrew Boyer, Andrew Rybchenko, Chenbo Xia,
	Konstantin Ananyev, Maxime Coquelin

On Tue, Jan 30, 2024 at 03:26:13PM -0800, Tyler Retzlaff wrote:
> Replace the use of RTE_MARKER<x> with C11 anonymous unions to improve
> code portability between toolchains.
> 
> Update use of rte_mbuf rearm_data field in net/ionic, net/sfc and
> net/virtio which were accessing field as a zero-length array.
> 
> Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> ---
>  drivers/net/ionic/ionic_lif.c               |   8 +-
>  drivers/net/ionic/ionic_rxtx_sg.c           |   4 +-
>  drivers/net/ionic/ionic_rxtx_simple.c       |   2 +-
>  drivers/net/sfc/sfc_ef100_rx.c              |   8 +-
>  drivers/net/sfc/sfc_ef10_rx.c               |  12 +--
>  drivers/net/virtio/virtio_rxtx_packed_avx.h |   8 +-
>  lib/mbuf/rte_mbuf_core.h                    | 135 +++++++++++++++-------------
>  7 files changed, 94 insertions(+), 83 deletions(-)
> 
<snip>
@@ -464,9 +464,10 @@ enum {
>   * The generic rte_mbuf, containing a packet mbuf.
>   */
>  struct rte_mbuf {
> -	RTE_MARKER cacheline0;
> -
> -	void *buf_addr;           /**< Virtual address of segment buffer. */
> +	union {
> +	    void *cacheline0;
> +	    void *buf_addr;           /**< Virtual address of segment buffer. */
> +	};

This marker is never used, so we should just look to drop it. I think it
was originally added to have an equivalent to the cacheline1 marker.

However, that would be an ABI change, so I'm ok to have this as-is for now.

/Bruce


^ permalink raw reply	[relevance 3%]

* [PATCH v2] ethdev: fast path async flow API
  2024-01-30 18:17  1% [PATCH] ethdev: fast path async flow API Dariusz Sosnowski
@ 2024-01-31  9:35  1% ` Dariusz Sosnowski
  2024-02-06 17:36  1%   ` [PATCH v3] " Dariusz Sosnowski
  0 siblings, 1 reply; 200+ results
From: Dariusz Sosnowski @ 2024-01-31  9:35 UTC (permalink / raw)
  To: Viacheslav Ovsiienko, Ori Kam, Suanming Mou, Matan Azrad,
	Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
  Cc: dev

This patch reworks the async flow API functions called in data path,
to reduce the overhead during flow operations at the library level.
Main source of the overhead was indirection and checks done while
ethdev library was fetching rte_flow_ops from a given driver.

This patch introduces rte_flow_fp_ops struct which holds callbacks
to driver's implementation of fast path async flow API functions.
Each driver implementing these functions must populate flow_fp_ops
field inside rte_eth_dev structure with a reference to
its own implementation.
By default, ethdev library provides dummy callbacks with
implementations returning ENOSYS.
Such design provides a few assumptions:

- rte_flow_fp_ops struct for given port is always available.
- Each callback is either:
    - Default provided by library.
    - Set up by driver.

As a result, no checks for availability of the implementation
are needed at library level in data path.
Any library-level validation checks in async flow API are compiled
if and only if RTE_FLOW_DEBUG macro is defined.

These changes apply only to the following API functions:

- rte_flow_async_create()
- rte_flow_async_create_by_index()
- rte_flow_async_actions_update()
- rte_flow_async_destroy()
- rte_flow_push()
- rte_flow_pull()
- rte_flow_async_action_handle_create()
- rte_flow_async_action_handle_destroy()
- rte_flow_async_action_handle_update()
- rte_flow_async_action_handle_query()
- rte_flow_async_action_handle_query_update()
- rte_flow_async_action_list_handle_create()
- rte_flow_async_action_list_handle_destroy()
- rte_flow_async_action_list_handle_query_update()

This patch also adjusts the mlx5 PMD to the introduced flow API changes.

Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
v2:
- Fixed mlx5 PMD build issue with older versions of rdma-core.
---
 doc/guides/rel_notes/release_24_03.rst |  37 ++
 drivers/net/mlx5/mlx5_flow.c           | 608 +------------------------
 drivers/net/mlx5/mlx5_flow_hw.c        |  25 +
 lib/ethdev/ethdev_driver.c             |   4 +
 lib/ethdev/ethdev_driver.h             |   4 +
 lib/ethdev/rte_flow.c                  | 518 ++++++++++++++++-----
 lib/ethdev/rte_flow_driver.h           | 277 ++++++-----
 lib/ethdev/version.map                 |   2 +
 8 files changed, 635 insertions(+), 840 deletions(-)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 84d3144215..55e7d57096 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -106,6 +106,43 @@ API Changes
 
 * gso: ``rte_gso_segment`` now returns -ENOTSUP for unknown protocols.
 
+* ethdev: PMDs implementing asynchronous flow operations are required to provide relevant functions
+  implementation through ``rte_flow_fp_ops`` struct, instead of ``rte_flow_ops`` struct.
+  Pointer to device-dependent ``rte_flow_fp_ops`` should be provided to ``rte_eth_dev.flow_fp_ops``.
+  This change applies to the following API functions:
+
+   * ``rte_flow_async_create``
+   * ``rte_flow_async_create_by_index``
+   * ``rte_flow_async_actions_update``
+   * ``rte_flow_async_destroy``
+   * ``rte_flow_push``
+   * ``rte_flow_pull``
+   * ``rte_flow_async_action_handle_create``
+   * ``rte_flow_async_action_handle_destroy``
+   * ``rte_flow_async_action_handle_update``
+   * ``rte_flow_async_action_handle_query``
+   * ``rte_flow_async_action_handle_query_update``
+   * ``rte_flow_async_action_list_handle_create``
+   * ``rte_flow_async_action_list_handle_destroy``
+   * ``rte_flow_async_action_list_handle_query_update``
+
+* ethdev: Removed the following fields from ``rte_flow_ops`` struct:
+
+   * ``async_create``
+   * ``async_create_by_index``
+   * ``async_actions_update``
+   * ``async_destroy``
+   * ``push``
+   * ``pull``
+   * ``async_action_handle_create``
+   * ``async_action_handle_destroy``
+   * ``async_action_handle_update``
+   * ``async_action_handle_query``
+   * ``async_action_handle_query_update``
+   * ``async_action_list_handle_create``
+   * ``async_action_list_handle_destroy``
+   * ``async_action_list_handle_query_update``
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 85e8c77c81..0ff3b91596 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -1055,98 +1055,13 @@ mlx5_flow_group_set_miss_actions(struct rte_eth_dev *dev,
 				 const struct rte_flow_group_attr *attr,
 				 const struct rte_flow_action actions[],
 				 struct rte_flow_error *error);
-static struct rte_flow *
-mlx5_flow_async_flow_create(struct rte_eth_dev *dev,
-			    uint32_t queue,
-			    const struct rte_flow_op_attr *attr,
-			    struct rte_flow_template_table *table,
-			    const struct rte_flow_item items[],
-			    uint8_t pattern_template_index,
-			    const struct rte_flow_action actions[],
-			    uint8_t action_template_index,
-			    void *user_data,
-			    struct rte_flow_error *error);
-static struct rte_flow *
-mlx5_flow_async_flow_create_by_index(struct rte_eth_dev *dev,
-			    uint32_t queue,
-			    const struct rte_flow_op_attr *attr,
-			    struct rte_flow_template_table *table,
-			    uint32_t rule_index,
-			    const struct rte_flow_action actions[],
-			    uint8_t action_template_index,
-			    void *user_data,
-			    struct rte_flow_error *error);
-static int
-mlx5_flow_async_flow_update(struct rte_eth_dev *dev,
-			     uint32_t queue,
-			     const struct rte_flow_op_attr *attr,
-			     struct rte_flow *flow,
-			     const struct rte_flow_action actions[],
-			     uint8_t action_template_index,
-			     void *user_data,
-			     struct rte_flow_error *error);
-static int
-mlx5_flow_async_flow_destroy(struct rte_eth_dev *dev,
-			     uint32_t queue,
-			     const struct rte_flow_op_attr *attr,
-			     struct rte_flow *flow,
-			     void *user_data,
-			     struct rte_flow_error *error);
-static int
-mlx5_flow_pull(struct rte_eth_dev *dev,
-	       uint32_t queue,
-	       struct rte_flow_op_result res[],
-	       uint16_t n_res,
-	       struct rte_flow_error *error);
-static int
-mlx5_flow_push(struct rte_eth_dev *dev,
-	       uint32_t queue,
-	       struct rte_flow_error *error);
-
-static struct rte_flow_action_handle *
-mlx5_flow_async_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
-				 const struct rte_flow_op_attr *attr,
-				 const struct rte_flow_indir_action_conf *conf,
-				 const struct rte_flow_action *action,
-				 void *user_data,
-				 struct rte_flow_error *error);
-
-static int
-mlx5_flow_async_action_handle_update(struct rte_eth_dev *dev, uint32_t queue,
-				 const struct rte_flow_op_attr *attr,
-				 struct rte_flow_action_handle *handle,
-				 const void *update,
-				 void *user_data,
-				 struct rte_flow_error *error);
 
 static int
-mlx5_flow_async_action_handle_destroy(struct rte_eth_dev *dev, uint32_t queue,
-				  const struct rte_flow_op_attr *attr,
-				  struct rte_flow_action_handle *handle,
-				  void *user_data,
-				  struct rte_flow_error *error);
-
-static int
-mlx5_flow_async_action_handle_query(struct rte_eth_dev *dev, uint32_t queue,
-				 const struct rte_flow_op_attr *attr,
-				 const struct rte_flow_action_handle *handle,
-				 void *data,
-				 void *user_data,
-				 struct rte_flow_error *error);
-static int
 mlx5_action_handle_query_update(struct rte_eth_dev *dev,
 				struct rte_flow_action_handle *handle,
 				const void *update, void *query,
 				enum rte_flow_query_update_mode qu_mode,
 				struct rte_flow_error *error);
-static int
-mlx5_flow_async_action_handle_query_update
-	(struct rte_eth_dev *dev, uint32_t queue_id,
-	 const struct rte_flow_op_attr *op_attr,
-	 struct rte_flow_action_handle *action_handle,
-	 const void *update, void *query,
-	 enum rte_flow_query_update_mode qu_mode,
-	 void *user_data, struct rte_flow_error *error);
 
 static struct rte_flow_action_list_handle *
 mlx5_action_list_handle_create(struct rte_eth_dev *dev,
@@ -1159,20 +1074,6 @@ mlx5_action_list_handle_destroy(struct rte_eth_dev *dev,
 				struct rte_flow_action_list_handle *handle,
 				struct rte_flow_error *error);
 
-static struct rte_flow_action_list_handle *
-mlx5_flow_async_action_list_handle_create(struct rte_eth_dev *dev, uint32_t queue_id,
-					  const struct rte_flow_op_attr *attr,
-					  const struct
-					  rte_flow_indir_action_conf *conf,
-					  const struct rte_flow_action *actions,
-					  void *user_data,
-					  struct rte_flow_error *error);
-static int
-mlx5_flow_async_action_list_handle_destroy
-			(struct rte_eth_dev *dev, uint32_t queue_id,
-			 const struct rte_flow_op_attr *op_attr,
-			 struct rte_flow_action_list_handle *action_handle,
-			 void *user_data, struct rte_flow_error *error);
 static int
 mlx5_flow_action_list_handle_query_update(struct rte_eth_dev *dev,
 					  const
@@ -1180,17 +1081,7 @@ mlx5_flow_action_list_handle_query_update(struct rte_eth_dev *dev,
 					  const void **update, void **query,
 					  enum rte_flow_query_update_mode mode,
 					  struct rte_flow_error *error);
-static int
-mlx5_flow_async_action_list_handle_query_update(struct rte_eth_dev *dev,
-						uint32_t queue_id,
-						const struct rte_flow_op_attr *attr,
-						const struct
-						rte_flow_action_list_handle *handle,
-						const void **update,
-						void **query,
-						enum rte_flow_query_update_mode mode,
-						void *user_data,
-						struct rte_flow_error *error);
+
 static int
 mlx5_flow_calc_table_hash(struct rte_eth_dev *dev,
 			  const struct rte_flow_template_table *table,
@@ -1232,26 +1123,8 @@ static const struct rte_flow_ops mlx5_flow_ops = {
 	.template_table_create = mlx5_flow_table_create,
 	.template_table_destroy = mlx5_flow_table_destroy,
 	.group_set_miss_actions = mlx5_flow_group_set_miss_actions,
-	.async_create = mlx5_flow_async_flow_create,
-	.async_create_by_index = mlx5_flow_async_flow_create_by_index,
-	.async_destroy = mlx5_flow_async_flow_destroy,
-	.pull = mlx5_flow_pull,
-	.push = mlx5_flow_push,
-	.async_action_handle_create = mlx5_flow_async_action_handle_create,
-	.async_action_handle_update = mlx5_flow_async_action_handle_update,
-	.async_action_handle_query_update =
-		mlx5_flow_async_action_handle_query_update,
-	.async_action_handle_query = mlx5_flow_async_action_handle_query,
-	.async_action_handle_destroy = mlx5_flow_async_action_handle_destroy,
-	.async_actions_update = mlx5_flow_async_flow_update,
-	.async_action_list_handle_create =
-		mlx5_flow_async_action_list_handle_create,
-	.async_action_list_handle_destroy =
-		mlx5_flow_async_action_list_handle_destroy,
 	.action_list_handle_query_update =
 		mlx5_flow_action_list_handle_query_update,
-	.async_action_list_handle_query_update =
-		mlx5_flow_async_action_list_handle_query_update,
 	.flow_calc_table_hash = mlx5_flow_calc_table_hash,
 };
 
@@ -9427,424 +9300,6 @@ mlx5_flow_group_set_miss_actions(struct rte_eth_dev *dev,
 	return fops->group_set_miss_actions(dev, group_id, attr, actions, error);
 }
 
-/**
- * Enqueue flow creation.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue_id
- *   The queue to create the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] items
- *   Items with flow spec value.
- * @param[in] pattern_template_index
- *   The item pattern flow follows from the table.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    Flow pointer on success, NULL otherwise and rte_errno is set.
- */
-static struct rte_flow *
-mlx5_flow_async_flow_create(struct rte_eth_dev *dev,
-			    uint32_t queue_id,
-			    const struct rte_flow_op_attr *attr,
-			    struct rte_flow_template_table *table,
-			    const struct rte_flow_item items[],
-			    uint8_t pattern_template_index,
-			    const struct rte_flow_action actions[],
-			    uint8_t action_template_index,
-			    void *user_data,
-			    struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr fattr = {0};
-
-	if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW) {
-		rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q create with incorrect steering mode");
-		return NULL;
-	}
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->async_flow_create(dev, queue_id, attr, table,
-				       items, pattern_template_index,
-				       actions, action_template_index,
-				       user_data, error);
-}
-
-/**
- * Enqueue flow creation by index.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue_id
- *   The queue to create the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] rule_index
- *   The item pattern flow follows from the table.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    Flow pointer on success, NULL otherwise and rte_errno is set.
- */
-static struct rte_flow *
-mlx5_flow_async_flow_create_by_index(struct rte_eth_dev *dev,
-			    uint32_t queue_id,
-			    const struct rte_flow_op_attr *attr,
-			    struct rte_flow_template_table *table,
-			    uint32_t rule_index,
-			    const struct rte_flow_action actions[],
-			    uint8_t action_template_index,
-			    void *user_data,
-			    struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr fattr = {0};
-
-	if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW) {
-		rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q create with incorrect steering mode");
-		return NULL;
-	}
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->async_flow_create_by_index(dev, queue_id, attr, table,
-				       rule_index, actions, action_template_index,
-				       user_data, error);
-}
-
-/**
- * Enqueue flow update.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to destroy the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] flow
- *   Pointer to the flow to be destroyed.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_flow_update(struct rte_eth_dev *dev,
-			     uint32_t queue,
-			     const struct rte_flow_op_attr *attr,
-			     struct rte_flow *flow,
-			     const struct rte_flow_action actions[],
-			     uint8_t action_template_index,
-			     void *user_data,
-			     struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr fattr = {0};
-
-	if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW)
-		return rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q update with incorrect steering mode");
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->async_flow_update(dev, queue, attr, flow,
-					actions, action_template_index, user_data, error);
-}
-
-/**
- * Enqueue flow destruction.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to destroy the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] flow
- *   Pointer to the flow to be destroyed.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_flow_destroy(struct rte_eth_dev *dev,
-			     uint32_t queue,
-			     const struct rte_flow_op_attr *attr,
-			     struct rte_flow *flow,
-			     void *user_data,
-			     struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr fattr = {0};
-
-	if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW)
-		return rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q destroy with incorrect steering mode");
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->async_flow_destroy(dev, queue, attr, flow,
-					user_data, error);
-}
-
-/**
- * Pull the enqueued flows.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to pull the result.
- * @param[in/out] res
- *   Array to save the results.
- * @param[in] n_res
- *   Available result with the array.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    Result number on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_pull(struct rte_eth_dev *dev,
-	       uint32_t queue,
-	       struct rte_flow_op_result res[],
-	       uint16_t n_res,
-	       struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr attr = {0};
-
-	if (flow_get_drv_type(dev, &attr) != MLX5_FLOW_TYPE_HW)
-		return rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q pull with incorrect steering mode");
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->pull(dev, queue, res, n_res, error);
-}
-
-/**
- * Push the enqueued flows.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to push the flows.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_push(struct rte_eth_dev *dev,
-	       uint32_t queue,
-	       struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr attr = {0};
-
-	if (flow_get_drv_type(dev, &attr) != MLX5_FLOW_TYPE_HW)
-		return rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q push with incorrect steering mode");
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->push(dev, queue, error);
-}
-
-/**
- * Create shared action.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   Which queue to be used..
- * @param[in] attr
- *   Operation attribute.
- * @param[in] conf
- *   Indirect action configuration.
- * @param[in] action
- *   rte_flow action detail.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *   Action handle on success, NULL otherwise and rte_errno is set.
- */
-static struct rte_flow_action_handle *
-mlx5_flow_async_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
-				 const struct rte_flow_op_attr *attr,
-				 const struct rte_flow_indir_action_conf *conf,
-				 const struct rte_flow_action *action,
-				 void *user_data,
-				 struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	return fops->async_action_create(dev, queue, attr, conf, action,
-					 user_data, error);
-}
-
-/**
- * Update shared action.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   Which queue to be used..
- * @param[in] attr
- *   Operation attribute.
- * @param[in] handle
- *   Action handle to be updated.
- * @param[in] update
- *   Update value.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *   0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_action_handle_update(struct rte_eth_dev *dev, uint32_t queue,
-				     const struct rte_flow_op_attr *attr,
-				     struct rte_flow_action_handle *handle,
-				     const void *update,
-				     void *user_data,
-				     struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	return fops->async_action_update(dev, queue, attr, handle,
-					 update, user_data, error);
-}
-
-static int
-mlx5_flow_async_action_handle_query_update
-	(struct rte_eth_dev *dev, uint32_t queue_id,
-	 const struct rte_flow_op_attr *op_attr,
-	 struct rte_flow_action_handle *action_handle,
-	 const void *update, void *query,
-	 enum rte_flow_query_update_mode qu_mode,
-	 void *user_data, struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-		flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	if (!fops || !fops->async_action_query_update)
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-					  "async query_update not supported");
-	return fops->async_action_query_update
-			   (dev, queue_id, op_attr, action_handle,
-			    update, query, qu_mode, user_data, error);
-}
-
-/**
- * Query shared action.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   Which queue to be used..
- * @param[in] attr
- *   Operation attribute.
- * @param[in] handle
- *   Action handle to be updated.
- * @param[in] data
- *   Pointer query result data.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *   0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_action_handle_query(struct rte_eth_dev *dev, uint32_t queue,
-				    const struct rte_flow_op_attr *attr,
-				    const struct rte_flow_action_handle *handle,
-				    void *data,
-				    void *user_data,
-				    struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	return fops->async_action_query(dev, queue, attr, handle,
-					data, user_data, error);
-}
-
-/**
- * Destroy shared action.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   Which queue to be used..
- * @param[in] attr
- *   Operation attribute.
- * @param[in] handle
- *   Action handle to be destroyed.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *   0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_action_handle_destroy(struct rte_eth_dev *dev, uint32_t queue,
-				      const struct rte_flow_op_attr *attr,
-				      struct rte_flow_action_handle *handle,
-				      void *user_data,
-				      struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	return fops->async_action_destroy(dev, queue, attr, handle,
-					  user_data, error);
-}
-
 /**
  * Allocate a new memory for the counter values wrapped by all the needed
  * management.
@@ -11015,41 +10470,6 @@ mlx5_action_list_handle_destroy(struct rte_eth_dev *dev,
 	return fops->action_list_handle_destroy(dev, handle, error);
 }
 
-static struct rte_flow_action_list_handle *
-mlx5_flow_async_action_list_handle_create(struct rte_eth_dev *dev,
-					  uint32_t queue_id,
-					  const struct
-					  rte_flow_op_attr *op_attr,
-					  const struct
-					  rte_flow_indir_action_conf *conf,
-					  const struct rte_flow_action *actions,
-					  void *user_data,
-					  struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-
-	MLX5_DRV_FOPS_OR_ERR(dev, fops, async_action_list_handle_create, NULL);
-	return fops->async_action_list_handle_create(dev, queue_id, op_attr,
-						     conf, actions, user_data,
-						     error);
-}
-
-static int
-mlx5_flow_async_action_list_handle_destroy
-	(struct rte_eth_dev *dev, uint32_t queue_id,
-	 const struct rte_flow_op_attr *op_attr,
-	 struct rte_flow_action_list_handle *action_handle,
-	 void *user_data, struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-
-	MLX5_DRV_FOPS_OR_ERR(dev, fops,
-			     async_action_list_handle_destroy, ENOTSUP);
-	return fops->async_action_list_handle_destroy(dev, queue_id, op_attr,
-						      action_handle, user_data,
-						      error);
-}
-
 static int
 mlx5_flow_action_list_handle_query_update(struct rte_eth_dev *dev,
 					  const
@@ -11065,32 +10485,6 @@ mlx5_flow_action_list_handle_query_update(struct rte_eth_dev *dev,
 	return fops->action_list_handle_query_update(dev, handle, update, query,
 						     mode, error);
 }
-
-static int
-mlx5_flow_async_action_list_handle_query_update(struct rte_eth_dev *dev,
-						uint32_t queue_id,
-						const
-						struct rte_flow_op_attr *op_attr,
-						const struct
-						rte_flow_action_list_handle *handle,
-						const void **update,
-						void **query,
-						enum
-						rte_flow_query_update_mode mode,
-						void *user_data,
-						struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-
-	MLX5_DRV_FOPS_OR_ERR(dev, fops,
-			     async_action_list_handle_query_update, ENOTSUP);
-	return fops->async_action_list_handle_query_update(dev, queue_id, op_attr,
-							   handle, update,
-							   query, mode,
-							   user_data, error);
-}
-
-
 static int
 mlx5_flow_calc_table_hash(struct rte_eth_dev *dev,
 			  const struct rte_flow_template_table *table,
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index da873ae2e2..c65ebfbba2 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -3,6 +3,7 @@
  */
 
 #include <rte_flow.h>
+#include <rte_flow_driver.h>
 
 #include <mlx5_malloc.h>
 
@@ -14,6 +15,9 @@
 #if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H)
 #include "mlx5_hws_cnt.h"
 
+/** Fast path async flow API functions. */
+static struct rte_flow_fp_ops mlx5_flow_hw_fp_ops;
+
 /* The maximum actions support in the flow. */
 #define MLX5_HW_MAX_ACTS 16
 
@@ -9543,6 +9547,7 @@ flow_hw_configure(struct rte_eth_dev *dev,
 		mlx5_free(_queue_attr);
 	if (port_attr->flags & RTE_FLOW_PORT_FLAG_STRICT_QUEUE)
 		priv->hws_strict_queue = 1;
+	dev->flow_fp_ops = &mlx5_flow_hw_fp_ops;
 	return 0;
 err:
 	if (priv->hws_ctpool) {
@@ -9617,6 +9622,7 @@ flow_hw_resource_release(struct rte_eth_dev *dev)
 
 	if (!priv->dr_ctx)
 		return;
+	dev->flow_fp_ops = &rte_flow_fp_default_ops;
 	flow_hw_rxq_flag_set(dev, false);
 	flow_hw_flush_all_ctrl_flows(dev);
 	flow_hw_cleanup_tx_repr_tagging(dev);
@@ -12992,4 +12998,23 @@ mlx5_reformat_action_destroy(struct rte_eth_dev *dev,
 	mlx5_free(handle);
 	return 0;
 }
+
+static struct rte_flow_fp_ops mlx5_flow_hw_fp_ops = {
+	.async_create = flow_hw_async_flow_create,
+	.async_create_by_index = flow_hw_async_flow_create_by_index,
+	.async_actions_update = flow_hw_async_flow_update,
+	.async_destroy = flow_hw_async_flow_destroy,
+	.push = flow_hw_push,
+	.pull = flow_hw_pull,
+	.async_action_handle_create = flow_hw_action_handle_create,
+	.async_action_handle_destroy = flow_hw_action_handle_destroy,
+	.async_action_handle_update = flow_hw_action_handle_update,
+	.async_action_handle_query = flow_hw_action_handle_query,
+	.async_action_handle_query_update = flow_hw_async_action_handle_query_update,
+	.async_action_list_handle_create = flow_hw_async_action_list_handle_create,
+	.async_action_list_handle_destroy = flow_hw_async_action_list_handle_destroy,
+	.async_action_list_handle_query_update =
+		flow_hw_async_action_list_handle_query_update,
+};
+
 #endif
diff --git a/lib/ethdev/ethdev_driver.c b/lib/ethdev/ethdev_driver.c
index bd917a15fc..34909a3018 100644
--- a/lib/ethdev/ethdev_driver.c
+++ b/lib/ethdev/ethdev_driver.c
@@ -10,6 +10,7 @@
 
 #include "ethdev_driver.h"
 #include "ethdev_private.h"
+#include "rte_flow_driver.h"
 
 /**
  * A set of values to describe the possible states of a switch domain.
@@ -110,6 +111,7 @@ rte_eth_dev_allocate(const char *name)
 	}
 
 	eth_dev = eth_dev_get(port_id);
+	eth_dev->flow_fp_ops = &rte_flow_fp_default_ops;
 	strlcpy(eth_dev->data->name, name, sizeof(eth_dev->data->name));
 	eth_dev->data->port_id = port_id;
 	eth_dev->data->backer_port_id = RTE_MAX_ETHPORTS;
@@ -245,6 +247,8 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
 
 	eth_dev_fp_ops_reset(rte_eth_fp_ops + eth_dev->data->port_id);
 
+	eth_dev->flow_fp_ops = &rte_flow_fp_default_ops;
+
 	rte_spinlock_lock(rte_mcfg_ethdev_get_lock());
 
 	eth_dev->state = RTE_ETH_DEV_UNUSED;
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index f05f68a67c..2dfa8e238b 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -73,6 +73,10 @@ struct rte_eth_dev {
 	struct rte_eth_dev_data *data;
 	void *process_private; /**< Pointer to per-process device data */
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
+	/**
+	 * Fast path flow API functions exported by PMD.
+	 */
+	const struct rte_flow_fp_ops *flow_fp_ops;
 	struct rte_device *device; /**< Backing device */
 	struct rte_intr_handle *intr_handle; /**< Device interrupt handle */
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 3f58d792f9..7cd04c3637 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -2014,16 +2014,26 @@ rte_flow_async_create(uint16_t port_id,
 		      struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	struct rte_flow *flow;
 
-	flow = ops->async_create(dev, queue_id,
-				 op_attr, template_table,
-				 pattern, pattern_template_index,
-				 actions, actions_template_index,
-				 user_data, error);
-	if (flow == NULL)
-		flow_err(port_id, -rte_errno, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENODEV));
+		return NULL;
+	}
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_create) {
+		rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENOSYS));
+		return NULL;
+	}
+#endif
+
+	flow = dev->flow_fp_ops->async_create(dev, queue_id,
+					      op_attr, template_table,
+					      pattern, pattern_template_index,
+					      actions, actions_template_index,
+					      user_data, error);
 
 	rte_flow_trace_async_create(port_id, queue_id, op_attr, template_table,
 				    pattern, pattern_template_index, actions,
@@ -2044,16 +2054,24 @@ rte_flow_async_create_by_index(uint16_t port_id,
 			       struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
-	struct rte_flow *flow;
 
-	flow = ops->async_create_by_index(dev, queue_id,
-					  op_attr, template_table, rule_index,
-					  actions, actions_template_index,
-					  user_data, error);
-	if (flow == NULL)
-		flow_err(port_id, -rte_errno, error);
-	return flow;
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENODEV));
+		return NULL;
+	}
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_create_by_index) {
+		rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENOSYS));
+		return NULL;
+	}
+#endif
+
+	return dev->flow_fp_ops->async_create_by_index(dev, queue_id,
+						       op_attr, template_table, rule_index,
+						       actions, actions_template_index,
+						       user_data, error);
 }
 
 int
@@ -2065,14 +2083,20 @@ rte_flow_async_destroy(uint16_t port_id,
 		       struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
 
-	ret = flow_err(port_id,
-		       ops->async_destroy(dev, queue_id,
-					  op_attr, flow,
-					  user_data, error),
-		       error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_destroy)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_destroy(dev, queue_id,
+					      op_attr, flow,
+					      user_data, error);
 
 	rte_flow_trace_async_destroy(port_id, queue_id, op_attr, flow,
 				     user_data, ret);
@@ -2091,15 +2115,21 @@ rte_flow_async_actions_update(uint16_t port_id,
 			      struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
 
-	ret = flow_err(port_id,
-		       ops->async_actions_update(dev, queue_id, op_attr,
-						 flow, actions,
-						 actions_template_index,
-						 user_data, error),
-		       error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_actions_update)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_actions_update(dev, queue_id, op_attr,
+						     flow, actions,
+						     actions_template_index,
+						     user_data, error);
 
 	rte_flow_trace_async_actions_update(port_id, queue_id, op_attr, flow,
 					    actions, actions_template_index,
@@ -2114,12 +2144,18 @@ rte_flow_push(uint16_t port_id,
 	      struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
 
-	ret = flow_err(port_id,
-		       ops->push(dev, queue_id, error),
-		       error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->push)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->push(dev, queue_id, error);
 
 	rte_flow_trace_push(port_id, queue_id, ret);
 
@@ -2134,16 +2170,22 @@ rte_flow_pull(uint16_t port_id,
 	      struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
-	int rc;
 
-	ret = ops->pull(dev, queue_id, res, n_res, error);
-	rc = ret ? ret : flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->pull)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->pull(dev, queue_id, res, n_res, error);
 
-	rte_flow_trace_pull(port_id, queue_id, res, n_res, rc);
+	rte_flow_trace_pull(port_id, queue_id, res, n_res, ret);
 
-	return rc;
+	return ret;
 }
 
 struct rte_flow_action_handle *
@@ -2156,13 +2198,24 @@ rte_flow_async_action_handle_create(uint16_t port_id,
 		struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	struct rte_flow_action_handle *handle;
 
-	handle = ops->async_action_handle_create(dev, queue_id, op_attr,
-					     indir_action_conf, action, user_data, error);
-	if (handle == NULL)
-		flow_err(port_id, -rte_errno, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENODEV));
+		return NULL;
+	}
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_handle_create) {
+		rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENOSYS));
+		return NULL;
+	}
+#endif
+
+	handle = dev->flow_fp_ops->async_action_handle_create(dev, queue_id, op_attr,
+							      indir_action_conf, action,
+							      user_data, error);
 
 	rte_flow_trace_async_action_handle_create(port_id, queue_id, op_attr,
 						  indir_action_conf, action,
@@ -2180,12 +2233,19 @@ rte_flow_async_action_handle_destroy(uint16_t port_id,
 		struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
 
-	ret = ops->async_action_handle_destroy(dev, queue_id, op_attr,
-					   action_handle, user_data, error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_handle_destroy)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_handle_destroy(dev, queue_id, op_attr,
+							    action_handle, user_data, error);
 
 	rte_flow_trace_async_action_handle_destroy(port_id, queue_id, op_attr,
 						   action_handle, user_data, ret);
@@ -2203,12 +2263,19 @@ rte_flow_async_action_handle_update(uint16_t port_id,
 		struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
 
-	ret = ops->async_action_handle_update(dev, queue_id, op_attr,
-					  action_handle, update, user_data, error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_handle_update)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_handle_update(dev, queue_id, op_attr,
+							   action_handle, update, user_data, error);
 
 	rte_flow_trace_async_action_handle_update(port_id, queue_id, op_attr,
 						  action_handle, update,
@@ -2227,14 +2294,19 @@ rte_flow_async_action_handle_query(uint16_t port_id,
 		struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
 
-	if (unlikely(!ops))
-		return -rte_errno;
-	ret = ops->async_action_handle_query(dev, queue_id, op_attr,
-					  action_handle, data, user_data, error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_handle_query)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_handle_query(dev, queue_id, op_attr,
+							  action_handle, data, user_data, error);
 
 	rte_flow_trace_async_action_handle_query(port_id, queue_id, op_attr,
 						 action_handle, data, user_data,
@@ -2277,24 +2349,21 @@ rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id,
 					  void *user_data,
 					  struct rte_flow_error *error)
 {
-	int ret;
-	struct rte_eth_dev *dev;
-	const struct rte_flow_ops *ops;
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (!handle)
-		return -EINVAL;
-	if (!update && !query)
-		return -EINVAL;
-	dev = &rte_eth_devices[port_id];
-	ops = rte_flow_ops_get(port_id, error);
-	if (!ops || !ops->async_action_handle_query_update)
-		return -ENOTSUP;
-	ret = ops->async_action_handle_query_update(dev, queue_id, attr,
-						    handle, update,
-						    query, mode,
-						    user_data, error);
-	return flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_handle_query_update)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	return dev->flow_fp_ops->async_action_handle_query_update(dev, queue_id, attr,
+								  handle, update,
+								  query, mode,
+								  user_data, error);
 }
 
 struct rte_flow_action_list_handle *
@@ -2354,24 +2423,28 @@ rte_flow_async_action_list_handle_create(uint16_t port_id, uint32_t queue_id,
 					 void *user_data,
 					 struct rte_flow_error *error)
 {
-	int ret;
-	struct rte_eth_dev *dev;
-	const struct rte_flow_ops *ops;
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	struct rte_flow_action_list_handle *handle;
+	int ret;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
-	ops = rte_flow_ops_get(port_id, error);
-	if (!ops || !ops->async_action_list_handle_create) {
-		rte_flow_error_set(error, ENOTSUP,
-				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-				   "action_list handle not supported");
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENODEV));
 		return NULL;
 	}
-	dev = &rte_eth_devices[port_id];
-	handle = ops->async_action_list_handle_create(dev, queue_id, attr, conf,
-						      actions, user_data,
-						      error);
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_list_handle_create) {
+		rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENOSYS));
+		return NULL;
+	}
+#endif
+
+	handle = dev->flow_fp_ops->async_action_list_handle_create(dev, queue_id, attr, conf,
+								   actions, user_data,
+								   error);
 	ret = flow_err(port_id, -rte_errno, error);
+
 	rte_flow_trace_async_action_list_handle_create(port_id, queue_id, attr,
 						       conf, actions, user_data,
 						       ret);
@@ -2384,20 +2457,21 @@ rte_flow_async_action_list_handle_destroy(uint16_t port_id, uint32_t queue_id,
 				 struct rte_flow_action_list_handle *handle,
 				 void *user_data, struct rte_flow_error *error)
 {
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	int ret;
-	struct rte_eth_dev *dev;
-	const struct rte_flow_ops *ops;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	ops = rte_flow_ops_get(port_id, error);
-	if (!ops || !ops->async_action_list_handle_destroy)
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "async action_list handle not supported");
-	dev = &rte_eth_devices[port_id];
-	ret = ops->async_action_list_handle_destroy(dev, queue_id, op_attr,
-						    handle, user_data, error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_list_handle_destroy)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_list_handle_destroy(dev, queue_id, op_attr,
+								 handle, user_data, error);
+
 	rte_flow_trace_async_action_list_handle_destroy(port_id, queue_id,
 							op_attr, handle,
 							user_data, ret);
@@ -2438,22 +2512,23 @@ rte_flow_async_action_list_handle_query_update(uint16_t port_id, uint32_t queue_
 			 enum rte_flow_query_update_mode mode,
 			 void *user_data, struct rte_flow_error *error)
 {
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	int ret;
-	struct rte_eth_dev *dev;
-	const struct rte_flow_ops *ops;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	ops = rte_flow_ops_get(port_id, error);
-	if (!ops || !ops->async_action_list_handle_query_update)
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "action_list async query_update not supported");
-	dev = &rte_eth_devices[port_id];
-	ret = ops->async_action_list_handle_query_update(dev, queue_id, attr,
-							 handle, update, query,
-							 mode, user_data,
-							 error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_list_handle_query_update)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_list_handle_query_update(dev, queue_id, attr,
+								      handle, update, query,
+								      mode, user_data,
+								      error);
+
 	rte_flow_trace_async_action_list_handle_query_update(port_id, queue_id,
 							     attr, handle,
 							     update, query,
@@ -2482,3 +2557,216 @@ rte_flow_calc_table_hash(uint16_t port_id, const struct rte_flow_template_table
 					hash, error);
 	return flow_err(port_id, ret, error);
 }
+
+static struct rte_flow *
+rte_flow_dummy_async_create(struct rte_eth_dev *dev __rte_unused,
+			    uint32_t queue __rte_unused,
+			    const struct rte_flow_op_attr *attr __rte_unused,
+			    struct rte_flow_template_table *table __rte_unused,
+			    const struct rte_flow_item items[] __rte_unused,
+			    uint8_t pattern_template_index __rte_unused,
+			    const struct rte_flow_action actions[] __rte_unused,
+			    uint8_t action_template_index __rte_unused,
+			    void *user_data __rte_unused,
+			    struct rte_flow_error *error)
+{
+	rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			   rte_strerror(ENOSYS));
+	return NULL;
+}
+
+static struct rte_flow *
+rte_flow_dummy_async_create_by_index(struct rte_eth_dev *dev __rte_unused,
+				     uint32_t queue __rte_unused,
+				     const struct rte_flow_op_attr *attr __rte_unused,
+				     struct rte_flow_template_table *table __rte_unused,
+				     uint32_t rule_index __rte_unused,
+				     const struct rte_flow_action actions[] __rte_unused,
+				     uint8_t action_template_index __rte_unused,
+				     void *user_data __rte_unused,
+				     struct rte_flow_error *error)
+{
+	rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			   rte_strerror(ENOSYS));
+	return NULL;
+}
+
+static int
+rte_flow_dummy_async_actions_update(struct rte_eth_dev *dev __rte_unused,
+				    uint32_t queue_id __rte_unused,
+				    const struct rte_flow_op_attr *op_attr __rte_unused,
+				    struct rte_flow *flow __rte_unused,
+				    const struct rte_flow_action actions[] __rte_unused,
+				    uint8_t actions_template_index __rte_unused,
+				    void *user_data __rte_unused,
+				    struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_destroy(struct rte_eth_dev *dev __rte_unused,
+			     uint32_t queue_id __rte_unused,
+			     const struct rte_flow_op_attr *op_attr __rte_unused,
+			     struct rte_flow *flow __rte_unused,
+			     void *user_data __rte_unused,
+			     struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_push(struct rte_eth_dev *dev __rte_unused,
+		    uint32_t queue_id __rte_unused,
+		    struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_pull(struct rte_eth_dev *dev __rte_unused,
+		    uint32_t queue_id __rte_unused,
+		    struct rte_flow_op_result res[] __rte_unused,
+		    uint16_t n_res __rte_unused,
+		    struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static struct rte_flow_action_handle *
+rte_flow_dummy_async_action_handle_create(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	const struct rte_flow_indir_action_conf *indir_action_conf __rte_unused,
+	const struct rte_flow_action *action __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			   rte_strerror(ENOSYS));
+	return NULL;
+}
+
+static int
+rte_flow_dummy_async_action_handle_destroy(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	struct rte_flow_action_handle *action_handle __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_action_handle_update(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	struct rte_flow_action_handle *action_handle __rte_unused,
+	const void *update __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_action_handle_query(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	const struct rte_flow_action_handle *action_handle __rte_unused,
+	void *data __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_action_handle_query_update(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *attr __rte_unused,
+	struct rte_flow_action_handle *handle __rte_unused,
+	const void *update __rte_unused,
+	void *query __rte_unused,
+	enum rte_flow_query_update_mode mode __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static struct rte_flow_action_list_handle *
+rte_flow_dummy_async_action_list_handle_create(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *attr __rte_unused,
+	const struct rte_flow_indir_action_conf *conf __rte_unused,
+	const struct rte_flow_action *actions __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			   rte_strerror(ENOSYS));
+	return NULL;
+}
+
+static int
+rte_flow_dummy_async_action_list_handle_destroy(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	struct rte_flow_action_list_handle *handle __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_action_list_handle_query_update(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *attr __rte_unused,
+	const struct rte_flow_action_list_handle *handle __rte_unused,
+	const void **update __rte_unused,
+	void **query __rte_unused,
+	enum rte_flow_query_update_mode mode __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+struct rte_flow_fp_ops rte_flow_fp_default_ops = {
+	.async_create = rte_flow_dummy_async_create,
+	.async_create_by_index = rte_flow_dummy_async_create_by_index,
+	.async_actions_update = rte_flow_dummy_async_actions_update,
+	.async_destroy = rte_flow_dummy_async_destroy,
+	.push = rte_flow_dummy_push,
+	.pull = rte_flow_dummy_pull,
+	.async_action_handle_create = rte_flow_dummy_async_action_handle_create,
+	.async_action_handle_destroy = rte_flow_dummy_async_action_handle_destroy,
+	.async_action_handle_update = rte_flow_dummy_async_action_handle_update,
+	.async_action_handle_query = rte_flow_dummy_async_action_handle_query,
+	.async_action_handle_query_update = rte_flow_dummy_async_action_handle_query_update,
+	.async_action_list_handle_create = rte_flow_dummy_async_action_list_handle_create,
+	.async_action_list_handle_destroy = rte_flow_dummy_async_action_list_handle_destroy,
+	.async_action_list_handle_query_update =
+		rte_flow_dummy_async_action_list_handle_query_update,
+};
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index f35f659503..dd9d01045d 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -234,122 +234,12 @@ struct rte_flow_ops {
 		 const struct rte_flow_group_attr *attr,
 		 const struct rte_flow_action actions[],
 		 struct rte_flow_error *err);
-	/** See rte_flow_async_create() */
-	struct rte_flow *(*async_create)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_template_table *template_table,
-		 const struct rte_flow_item pattern[],
-		 uint8_t pattern_template_index,
-		 const struct rte_flow_action actions[],
-		 uint8_t actions_template_index,
-		 void *user_data,
-		 struct rte_flow_error *err);
-	/** See rte_flow_async_create_by_index() */
-	struct rte_flow *(*async_create_by_index)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_template_table *template_table,
-		 uint32_t rule_index,
-		 const struct rte_flow_action actions[],
-		 uint8_t actions_template_index,
-		 void *user_data,
-		 struct rte_flow_error *err);
-	/** See rte_flow_async_destroy() */
-	int (*async_destroy)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow *flow,
-		 void *user_data,
-		 struct rte_flow_error *err);
-	/** See rte_flow_push() */
-	int (*push)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 struct rte_flow_error *err);
-	/** See rte_flow_pull() */
-	int (*pull)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 struct rte_flow_op_result res[],
-		 uint16_t n_res,
-		 struct rte_flow_error *error);
-	/** See rte_flow_async_action_handle_create() */
-	struct rte_flow_action_handle *(*async_action_handle_create)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 const struct rte_flow_indir_action_conf *indir_action_conf,
-		 const struct rte_flow_action *action,
-		 void *user_data,
-		 struct rte_flow_error *err);
-	/** See rte_flow_async_action_handle_destroy() */
-	int (*async_action_handle_destroy)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_action_handle *action_handle,
-		 void *user_data,
-		 struct rte_flow_error *error);
-	/** See rte_flow_async_action_handle_update() */
-	int (*async_action_handle_update)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_action_handle *action_handle,
-		 const void *update,
-		 void *user_data,
-		 struct rte_flow_error *error);
-	/** See rte_flow_async_action_handle_query() */
-	int (*async_action_handle_query)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 const struct rte_flow_action_handle *action_handle,
-		 void *data,
-		 void *user_data,
-		 struct rte_flow_error *error);
-	/** See rte_flow_async_action_handle_query_update */
-	int (*async_action_handle_query_update)
-		(struct rte_eth_dev *dev, uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_action_handle *action_handle,
-		 const void *update, void *query,
-		 enum rte_flow_query_update_mode qu_mode,
-		 void *user_data, struct rte_flow_error *error);
 	/** See rte_flow_actions_update(). */
 	int (*actions_update)
 		(struct rte_eth_dev *dev,
 		 struct rte_flow *flow,
 		 const struct rte_flow_action actions[],
 		 struct rte_flow_error *error);
-	/** See rte_flow_async_actions_update() */
-	int (*async_actions_update)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow *flow,
-		 const struct rte_flow_action actions[],
-		 uint8_t actions_template_index,
-		 void *user_data,
-		 struct rte_flow_error *error);
-	/** @see rte_flow_async_action_list_handle_create() */
-	struct rte_flow_action_list_handle *
-	(*async_action_list_handle_create)
-		(struct rte_eth_dev *dev, uint32_t queue_id,
-		 const struct rte_flow_op_attr *attr,
-		 const struct rte_flow_indir_action_conf *conf,
-		 const struct rte_flow_action *actions,
-		 void *user_data, struct rte_flow_error *error);
-	/** @see rte_flow_async_action_list_handle_destroy() */
-	int (*async_action_list_handle_destroy)
-		(struct rte_eth_dev *dev, uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_action_list_handle *action_handle,
-		 void *user_data, struct rte_flow_error *error);
 	/** @see rte_flow_action_list_handle_query_update() */
 	int (*action_list_handle_query_update)
 		(struct rte_eth_dev *dev,
@@ -357,14 +247,6 @@ struct rte_flow_ops {
 		 const void **update, void **query,
 		 enum rte_flow_query_update_mode mode,
 		 struct rte_flow_error *error);
-	/** @see rte_flow_async_action_list_handle_query_update() */
-	int (*async_action_list_handle_query_update)
-		(struct rte_eth_dev *dev, uint32_t queue_id,
-		 const struct rte_flow_op_attr *attr,
-		 const struct rte_flow_action_list_handle *handle,
-		 const void **update, void **query,
-		 enum rte_flow_query_update_mode mode,
-		 void *user_data, struct rte_flow_error *error);
 	/** @see rte_flow_calc_table_hash() */
 	int (*flow_calc_table_hash)
 		(struct rte_eth_dev *dev, const struct rte_flow_template_table *table,
@@ -394,6 +276,165 @@ rte_flow_ops_get(uint16_t port_id, struct rte_flow_error *error);
 int
 rte_flow_restore_info_dynflag_register(void);
 
+/** @internal Enqueue rule creation operation. */
+typedef struct rte_flow *(*rte_flow_async_create_t)(struct rte_eth_dev *dev,
+						    uint32_t queue,
+						    const struct rte_flow_op_attr *attr,
+						    struct rte_flow_template_table *table,
+						    const struct rte_flow_item *items,
+						    uint8_t pattern_template_index,
+						    const struct rte_flow_action *actions,
+						    uint8_t action_template_index,
+						    void *user_data,
+						    struct rte_flow_error *error);
+
+/** @internal Enqueue rule creation by index operation. */
+typedef struct rte_flow *(*rte_flow_async_create_by_index_t)(struct rte_eth_dev *dev,
+							     uint32_t queue,
+							     const struct rte_flow_op_attr *attr,
+							     struct rte_flow_template_table *table,
+							     uint32_t rule_index,
+							     const struct rte_flow_action *actions,
+							     uint8_t action_template_index,
+							     void *user_data,
+							     struct rte_flow_error *error);
+
+/** @internal Enqueue rule update operation. */
+typedef int (*rte_flow_async_actions_update_t)(struct rte_eth_dev *dev,
+					       uint32_t queue_id,
+					       const struct rte_flow_op_attr *op_attr,
+					       struct rte_flow *flow,
+					       const struct rte_flow_action *actions,
+					       uint8_t actions_template_index,
+					       void *user_data,
+					       struct rte_flow_error *error);
+
+/** @internal Enqueue rule destruction operation. */
+typedef int (*rte_flow_async_destroy_t)(struct rte_eth_dev *dev,
+					uint32_t queue_id,
+					const struct rte_flow_op_attr *op_attr,
+					struct rte_flow *flow,
+					void *user_data,
+					struct rte_flow_error *error);
+
+/** @internal Push all internally stored rules to the HW. */
+typedef int (*rte_flow_push_t)(struct rte_eth_dev *dev,
+			       uint32_t queue_id,
+			       struct rte_flow_error *error);
+
+/** @internal Pull the flow rule operations results from the HW. */
+typedef int (*rte_flow_pull_t)(struct rte_eth_dev *dev,
+			       uint32_t queue_id,
+			       struct rte_flow_op_result *res,
+			       uint16_t n_res,
+			       struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action creation operation. */
+typedef struct rte_flow_action_handle *(*rte_flow_async_action_handle_create_t)(
+					struct rte_eth_dev *dev,
+					uint32_t queue_id,
+					const struct rte_flow_op_attr *op_attr,
+					const struct rte_flow_indir_action_conf *indir_action_conf,
+					const struct rte_flow_action *action,
+					void *user_data,
+					struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action destruction operation. */
+typedef int (*rte_flow_async_action_handle_destroy_t)(struct rte_eth_dev *dev,
+						      uint32_t queue_id,
+						      const struct rte_flow_op_attr *op_attr,
+						      struct rte_flow_action_handle *action_handle,
+						      void *user_data,
+						      struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action update operation. */
+typedef int (*rte_flow_async_action_handle_update_t)(struct rte_eth_dev *dev,
+						     uint32_t queue_id,
+						     const struct rte_flow_op_attr *op_attr,
+						     struct rte_flow_action_handle *action_handle,
+						     const void *update,
+						     void *user_data,
+						     struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action query operation. */
+typedef int (*rte_flow_async_action_handle_query_t)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 const struct rte_flow_op_attr *op_attr,
+		 const struct rte_flow_action_handle *action_handle,
+		 void *data,
+		 void *user_data,
+		 struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action query and/or update operation. */
+typedef int (*rte_flow_async_action_handle_query_update_t)(struct rte_eth_dev *dev,
+							   uint32_t queue_id,
+							   const struct rte_flow_op_attr *attr,
+							   struct rte_flow_action_handle *handle,
+							   const void *update, void *query,
+							   enum rte_flow_query_update_mode mode,
+							   void *user_data,
+							   struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action list creation operation. */
+typedef struct rte_flow_action_list_handle *(*rte_flow_async_action_list_handle_create_t)(
+	struct rte_eth_dev *dev,
+	uint32_t queue_id,
+	const struct rte_flow_op_attr *attr,
+	const struct rte_flow_indir_action_conf *conf,
+	const struct rte_flow_action *actions,
+	void *user_data,
+	struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action list destruction operation. */
+typedef int (*rte_flow_async_action_list_handle_destroy_t)(
+	struct rte_eth_dev *dev,
+	uint32_t queue_id,
+	const struct rte_flow_op_attr *op_attr,
+	struct rte_flow_action_list_handle *handle,
+	void *user_data,
+	struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action list query and/or update operation. */
+typedef int (*rte_flow_async_action_list_handle_query_update_t)(
+	struct rte_eth_dev *dev,
+	uint32_t queue_id,
+	const struct rte_flow_op_attr *attr,
+	const struct rte_flow_action_list_handle *handle,
+	const void **update,
+	void **query,
+	enum rte_flow_query_update_mode mode,
+	void *user_data,
+	struct rte_flow_error *error);
+
+/**
+ * @internal
+ *
+ * Fast path async flow functions are held in a flat array, one entry per ethdev.
+ */
+struct rte_flow_fp_ops {
+	rte_flow_async_create_t async_create;
+	rte_flow_async_create_by_index_t async_create_by_index;
+	rte_flow_async_actions_update_t async_actions_update;
+	rte_flow_async_destroy_t async_destroy;
+	rte_flow_push_t push;
+	rte_flow_pull_t pull;
+	rte_flow_async_action_handle_create_t async_action_handle_create;
+	rte_flow_async_action_handle_destroy_t async_action_handle_destroy;
+	rte_flow_async_action_handle_update_t async_action_handle_update;
+	rte_flow_async_action_handle_query_t async_action_handle_query;
+	rte_flow_async_action_handle_query_update_t async_action_handle_query_update;
+	rte_flow_async_action_list_handle_create_t async_action_list_handle_create;
+	rte_flow_async_action_list_handle_destroy_t async_action_list_handle_destroy;
+	rte_flow_async_action_list_handle_query_update_t async_action_list_handle_query_update;
+} __rte_cache_aligned;
+
+/**
+ * @internal
+ * Default implementation of fast path flow API functions.
+ */
+extern struct rte_flow_fp_ops rte_flow_fp_default_ops;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index a050baab0f..61e38a9f00 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -348,4 +348,6 @@ INTERNAL {
 	rte_eth_representor_id_get;
 	rte_eth_switch_domain_alloc;
 	rte_eth_switch_domain_free;
+
+	rte_flow_fp_default_ops;
 };
-- 
2.25.1


^ permalink raw reply	[relevance 1%]

* [PATCH] replace GCC marker extension with C11 anonymous unions
@ 2024-01-30 23:26  3% Tyler Retzlaff
                     ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Tyler Retzlaff @ 2024-01-30 23:26 UTC (permalink / raw)
  To: dev
  Cc: Andrew Boyer, Andrew Rybchenko, Bruce Richardson, Chenbo Xia,
	Konstantin Ananyev, Maxime Coquelin, Tyler Retzlaff

The zero sized RTE_MARKER<n> typedefs are a GCC extension unsupported by
MSVC.  Replace the use of the RTE_MARKER typedefs with anonymous unions.

both lib/mbuf and consuming drivers have been updated in the same commit
to avoid driver build break.

note:
since rte_mbuf is a public structure it might be argued that the removal
of the ability to access the fields as an array could be an api break.
there is no intended change in the application abi.

Tyler Retzlaff (1):
  mbuf: replace GCC marker extension with C11 anonymous unions

 drivers/net/ionic/ionic_lif.c               |   8 +-
 drivers/net/ionic/ionic_rxtx_sg.c           |   4 +-
 drivers/net/ionic/ionic_rxtx_simple.c       |   2 +-
 drivers/net/sfc/sfc_ef100_rx.c              |   8 +-
 drivers/net/sfc/sfc_ef10_rx.c               |  12 +--
 drivers/net/virtio/virtio_rxtx_packed_avx.h |   8 +-
 lib/mbuf/rte_mbuf_core.h                    | 135 +++++++++++++++-------------
 7 files changed, 94 insertions(+), 83 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[relevance 3%]

* [PATCH] ethdev: fast path async flow API
@ 2024-01-30 18:17  1% Dariusz Sosnowski
  2024-01-31  9:35  1% ` [PATCH v2] " Dariusz Sosnowski
  0 siblings, 1 reply; 200+ results
From: Dariusz Sosnowski @ 2024-01-30 18:17 UTC (permalink / raw)
  To: Viacheslav Ovsiienko, Ori Kam, Suanming Mou, Matan Azrad,
	Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
  Cc: dev

This patch reworks the async flow API functions called in data path,
to reduce the overhead during flow operations at the library level.
Main source of the overhead was indirection and checks done while
ethdev library was fetching rte_flow_ops from a given driver.

This patch introduces rte_flow_fp_ops struct which holds callbacks
to driver's implementation of fast path async flow API functions.
Each driver implementing these functions must populate flow_fp_ops
field inside rte_eth_dev structure with a reference to
its own implementation.
By default, ethdev library provides dummy callbacks with
implementations returning ENOSYS.
Such design provides a few assumptions:

- rte_flow_fp_ops struct for given port is always available.
- Each callback is either:
    - Default provided by library.
    - Set up by driver.

As a result, no checks for availability of the implementation
are needed at library level in data path.
Any library-level validation checks in async flow API are compiled
if and only if RTE_FLOW_DEBUG macro is defined.

These changes apply only to the following API functions:

- rte_flow_async_create()
- rte_flow_async_create_by_index()
- rte_flow_async_actions_update()
- rte_flow_async_destroy()
- rte_flow_push()
- rte_flow_pull()
- rte_flow_async_action_handle_create()
- rte_flow_async_action_handle_destroy()
- rte_flow_async_action_handle_update()
- rte_flow_async_action_handle_query()
- rte_flow_async_action_handle_query_update()
- rte_flow_async_action_list_handle_create()
- rte_flow_async_action_list_handle_destroy()
- rte_flow_async_action_list_handle_query_update()

This patch also adjusts the mlx5 PMD to the introduced flow API changes.

Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
 doc/guides/rel_notes/release_24_03.rst |  37 ++
 drivers/net/mlx5/mlx5_flow.c           | 608 +------------------------
 drivers/net/mlx5/mlx5_flow_hw.c        |  24 +
 lib/ethdev/ethdev_driver.c             |   4 +
 lib/ethdev/ethdev_driver.h             |   4 +
 lib/ethdev/rte_flow.c                  | 518 ++++++++++++++++-----
 lib/ethdev/rte_flow_driver.h           | 277 ++++++-----
 lib/ethdev/version.map                 |   2 +
 8 files changed, 634 insertions(+), 840 deletions(-)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 84d3144215..55e7d57096 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -106,6 +106,43 @@ API Changes
 
 * gso: ``rte_gso_segment`` now returns -ENOTSUP for unknown protocols.
 
+* ethdev: PMDs implementing asynchronous flow operations are required to provide relevant functions
+  implementation through ``rte_flow_fp_ops`` struct, instead of ``rte_flow_ops`` struct.
+  Pointer to device-dependent ``rte_flow_fp_ops`` should be provided to ``rte_eth_dev.flow_fp_ops``.
+  This change applies to the following API functions:
+
+   * ``rte_flow_async_create``
+   * ``rte_flow_async_create_by_index``
+   * ``rte_flow_async_actions_update``
+   * ``rte_flow_async_destroy``
+   * ``rte_flow_push``
+   * ``rte_flow_pull``
+   * ``rte_flow_async_action_handle_create``
+   * ``rte_flow_async_action_handle_destroy``
+   * ``rte_flow_async_action_handle_update``
+   * ``rte_flow_async_action_handle_query``
+   * ``rte_flow_async_action_handle_query_update``
+   * ``rte_flow_async_action_list_handle_create``
+   * ``rte_flow_async_action_list_handle_destroy``
+   * ``rte_flow_async_action_list_handle_query_update``
+
+* ethdev: Removed the following fields from ``rte_flow_ops`` struct:
+
+   * ``async_create``
+   * ``async_create_by_index``
+   * ``async_actions_update``
+   * ``async_destroy``
+   * ``push``
+   * ``pull``
+   * ``async_action_handle_create``
+   * ``async_action_handle_destroy``
+   * ``async_action_handle_update``
+   * ``async_action_handle_query``
+   * ``async_action_handle_query_update``
+   * ``async_action_list_handle_create``
+   * ``async_action_list_handle_destroy``
+   * ``async_action_list_handle_query_update``
+
 
 ABI Changes
 -----------
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 85e8c77c81..0ff3b91596 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -1055,98 +1055,13 @@ mlx5_flow_group_set_miss_actions(struct rte_eth_dev *dev,
 				 const struct rte_flow_group_attr *attr,
 				 const struct rte_flow_action actions[],
 				 struct rte_flow_error *error);
-static struct rte_flow *
-mlx5_flow_async_flow_create(struct rte_eth_dev *dev,
-			    uint32_t queue,
-			    const struct rte_flow_op_attr *attr,
-			    struct rte_flow_template_table *table,
-			    const struct rte_flow_item items[],
-			    uint8_t pattern_template_index,
-			    const struct rte_flow_action actions[],
-			    uint8_t action_template_index,
-			    void *user_data,
-			    struct rte_flow_error *error);
-static struct rte_flow *
-mlx5_flow_async_flow_create_by_index(struct rte_eth_dev *dev,
-			    uint32_t queue,
-			    const struct rte_flow_op_attr *attr,
-			    struct rte_flow_template_table *table,
-			    uint32_t rule_index,
-			    const struct rte_flow_action actions[],
-			    uint8_t action_template_index,
-			    void *user_data,
-			    struct rte_flow_error *error);
-static int
-mlx5_flow_async_flow_update(struct rte_eth_dev *dev,
-			     uint32_t queue,
-			     const struct rte_flow_op_attr *attr,
-			     struct rte_flow *flow,
-			     const struct rte_flow_action actions[],
-			     uint8_t action_template_index,
-			     void *user_data,
-			     struct rte_flow_error *error);
-static int
-mlx5_flow_async_flow_destroy(struct rte_eth_dev *dev,
-			     uint32_t queue,
-			     const struct rte_flow_op_attr *attr,
-			     struct rte_flow *flow,
-			     void *user_data,
-			     struct rte_flow_error *error);
-static int
-mlx5_flow_pull(struct rte_eth_dev *dev,
-	       uint32_t queue,
-	       struct rte_flow_op_result res[],
-	       uint16_t n_res,
-	       struct rte_flow_error *error);
-static int
-mlx5_flow_push(struct rte_eth_dev *dev,
-	       uint32_t queue,
-	       struct rte_flow_error *error);
-
-static struct rte_flow_action_handle *
-mlx5_flow_async_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
-				 const struct rte_flow_op_attr *attr,
-				 const struct rte_flow_indir_action_conf *conf,
-				 const struct rte_flow_action *action,
-				 void *user_data,
-				 struct rte_flow_error *error);
-
-static int
-mlx5_flow_async_action_handle_update(struct rte_eth_dev *dev, uint32_t queue,
-				 const struct rte_flow_op_attr *attr,
-				 struct rte_flow_action_handle *handle,
-				 const void *update,
-				 void *user_data,
-				 struct rte_flow_error *error);
 
 static int
-mlx5_flow_async_action_handle_destroy(struct rte_eth_dev *dev, uint32_t queue,
-				  const struct rte_flow_op_attr *attr,
-				  struct rte_flow_action_handle *handle,
-				  void *user_data,
-				  struct rte_flow_error *error);
-
-static int
-mlx5_flow_async_action_handle_query(struct rte_eth_dev *dev, uint32_t queue,
-				 const struct rte_flow_op_attr *attr,
-				 const struct rte_flow_action_handle *handle,
-				 void *data,
-				 void *user_data,
-				 struct rte_flow_error *error);
-static int
 mlx5_action_handle_query_update(struct rte_eth_dev *dev,
 				struct rte_flow_action_handle *handle,
 				const void *update, void *query,
 				enum rte_flow_query_update_mode qu_mode,
 				struct rte_flow_error *error);
-static int
-mlx5_flow_async_action_handle_query_update
-	(struct rte_eth_dev *dev, uint32_t queue_id,
-	 const struct rte_flow_op_attr *op_attr,
-	 struct rte_flow_action_handle *action_handle,
-	 const void *update, void *query,
-	 enum rte_flow_query_update_mode qu_mode,
-	 void *user_data, struct rte_flow_error *error);
 
 static struct rte_flow_action_list_handle *
 mlx5_action_list_handle_create(struct rte_eth_dev *dev,
@@ -1159,20 +1074,6 @@ mlx5_action_list_handle_destroy(struct rte_eth_dev *dev,
 				struct rte_flow_action_list_handle *handle,
 				struct rte_flow_error *error);
 
-static struct rte_flow_action_list_handle *
-mlx5_flow_async_action_list_handle_create(struct rte_eth_dev *dev, uint32_t queue_id,
-					  const struct rte_flow_op_attr *attr,
-					  const struct
-					  rte_flow_indir_action_conf *conf,
-					  const struct rte_flow_action *actions,
-					  void *user_data,
-					  struct rte_flow_error *error);
-static int
-mlx5_flow_async_action_list_handle_destroy
-			(struct rte_eth_dev *dev, uint32_t queue_id,
-			 const struct rte_flow_op_attr *op_attr,
-			 struct rte_flow_action_list_handle *action_handle,
-			 void *user_data, struct rte_flow_error *error);
 static int
 mlx5_flow_action_list_handle_query_update(struct rte_eth_dev *dev,
 					  const
@@ -1180,17 +1081,7 @@ mlx5_flow_action_list_handle_query_update(struct rte_eth_dev *dev,
 					  const void **update, void **query,
 					  enum rte_flow_query_update_mode mode,
 					  struct rte_flow_error *error);
-static int
-mlx5_flow_async_action_list_handle_query_update(struct rte_eth_dev *dev,
-						uint32_t queue_id,
-						const struct rte_flow_op_attr *attr,
-						const struct
-						rte_flow_action_list_handle *handle,
-						const void **update,
-						void **query,
-						enum rte_flow_query_update_mode mode,
-						void *user_data,
-						struct rte_flow_error *error);
+
 static int
 mlx5_flow_calc_table_hash(struct rte_eth_dev *dev,
 			  const struct rte_flow_template_table *table,
@@ -1232,26 +1123,8 @@ static const struct rte_flow_ops mlx5_flow_ops = {
 	.template_table_create = mlx5_flow_table_create,
 	.template_table_destroy = mlx5_flow_table_destroy,
 	.group_set_miss_actions = mlx5_flow_group_set_miss_actions,
-	.async_create = mlx5_flow_async_flow_create,
-	.async_create_by_index = mlx5_flow_async_flow_create_by_index,
-	.async_destroy = mlx5_flow_async_flow_destroy,
-	.pull = mlx5_flow_pull,
-	.push = mlx5_flow_push,
-	.async_action_handle_create = mlx5_flow_async_action_handle_create,
-	.async_action_handle_update = mlx5_flow_async_action_handle_update,
-	.async_action_handle_query_update =
-		mlx5_flow_async_action_handle_query_update,
-	.async_action_handle_query = mlx5_flow_async_action_handle_query,
-	.async_action_handle_destroy = mlx5_flow_async_action_handle_destroy,
-	.async_actions_update = mlx5_flow_async_flow_update,
-	.async_action_list_handle_create =
-		mlx5_flow_async_action_list_handle_create,
-	.async_action_list_handle_destroy =
-		mlx5_flow_async_action_list_handle_destroy,
 	.action_list_handle_query_update =
 		mlx5_flow_action_list_handle_query_update,
-	.async_action_list_handle_query_update =
-		mlx5_flow_async_action_list_handle_query_update,
 	.flow_calc_table_hash = mlx5_flow_calc_table_hash,
 };
 
@@ -9427,424 +9300,6 @@ mlx5_flow_group_set_miss_actions(struct rte_eth_dev *dev,
 	return fops->group_set_miss_actions(dev, group_id, attr, actions, error);
 }
 
-/**
- * Enqueue flow creation.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue_id
- *   The queue to create the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] items
- *   Items with flow spec value.
- * @param[in] pattern_template_index
- *   The item pattern flow follows from the table.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    Flow pointer on success, NULL otherwise and rte_errno is set.
- */
-static struct rte_flow *
-mlx5_flow_async_flow_create(struct rte_eth_dev *dev,
-			    uint32_t queue_id,
-			    const struct rte_flow_op_attr *attr,
-			    struct rte_flow_template_table *table,
-			    const struct rte_flow_item items[],
-			    uint8_t pattern_template_index,
-			    const struct rte_flow_action actions[],
-			    uint8_t action_template_index,
-			    void *user_data,
-			    struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr fattr = {0};
-
-	if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW) {
-		rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q create with incorrect steering mode");
-		return NULL;
-	}
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->async_flow_create(dev, queue_id, attr, table,
-				       items, pattern_template_index,
-				       actions, action_template_index,
-				       user_data, error);
-}
-
-/**
- * Enqueue flow creation by index.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue_id
- *   The queue to create the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] rule_index
- *   The item pattern flow follows from the table.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    Flow pointer on success, NULL otherwise and rte_errno is set.
- */
-static struct rte_flow *
-mlx5_flow_async_flow_create_by_index(struct rte_eth_dev *dev,
-			    uint32_t queue_id,
-			    const struct rte_flow_op_attr *attr,
-			    struct rte_flow_template_table *table,
-			    uint32_t rule_index,
-			    const struct rte_flow_action actions[],
-			    uint8_t action_template_index,
-			    void *user_data,
-			    struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr fattr = {0};
-
-	if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW) {
-		rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q create with incorrect steering mode");
-		return NULL;
-	}
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->async_flow_create_by_index(dev, queue_id, attr, table,
-				       rule_index, actions, action_template_index,
-				       user_data, error);
-}
-
-/**
- * Enqueue flow update.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to destroy the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] flow
- *   Pointer to the flow to be destroyed.
- * @param[in] actions
- *   Action with flow spec value.
- * @param[in] action_template_index
- *   The action pattern flow follows from the table.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_flow_update(struct rte_eth_dev *dev,
-			     uint32_t queue,
-			     const struct rte_flow_op_attr *attr,
-			     struct rte_flow *flow,
-			     const struct rte_flow_action actions[],
-			     uint8_t action_template_index,
-			     void *user_data,
-			     struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr fattr = {0};
-
-	if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW)
-		return rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q update with incorrect steering mode");
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->async_flow_update(dev, queue, attr, flow,
-					actions, action_template_index, user_data, error);
-}
-
-/**
- * Enqueue flow destruction.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to destroy the flow.
- * @param[in] attr
- *   Pointer to the flow operation attributes.
- * @param[in] flow
- *   Pointer to the flow to be destroyed.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_flow_destroy(struct rte_eth_dev *dev,
-			     uint32_t queue,
-			     const struct rte_flow_op_attr *attr,
-			     struct rte_flow *flow,
-			     void *user_data,
-			     struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr fattr = {0};
-
-	if (flow_get_drv_type(dev, &fattr) != MLX5_FLOW_TYPE_HW)
-		return rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q destroy with incorrect steering mode");
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->async_flow_destroy(dev, queue, attr, flow,
-					user_data, error);
-}
-
-/**
- * Pull the enqueued flows.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to pull the result.
- * @param[in/out] res
- *   Array to save the results.
- * @param[in] n_res
- *   Available result with the array.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    Result number on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_pull(struct rte_eth_dev *dev,
-	       uint32_t queue,
-	       struct rte_flow_op_result res[],
-	       uint16_t n_res,
-	       struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr attr = {0};
-
-	if (flow_get_drv_type(dev, &attr) != MLX5_FLOW_TYPE_HW)
-		return rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q pull with incorrect steering mode");
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->pull(dev, queue, res, n_res, error);
-}
-
-/**
- * Push the enqueued flows.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   The queue to push the flows.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *    0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_push(struct rte_eth_dev *dev,
-	       uint32_t queue,
-	       struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-	struct rte_flow_attr attr = {0};
-
-	if (flow_get_drv_type(dev, &attr) != MLX5_FLOW_TYPE_HW)
-		return rte_flow_error_set(error, ENOTSUP,
-				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				NULL,
-				"flow_q push with incorrect steering mode");
-	fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-	return fops->push(dev, queue, error);
-}
-
-/**
- * Create shared action.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   Which queue to be used..
- * @param[in] attr
- *   Operation attribute.
- * @param[in] conf
- *   Indirect action configuration.
- * @param[in] action
- *   rte_flow action detail.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *   Action handle on success, NULL otherwise and rte_errno is set.
- */
-static struct rte_flow_action_handle *
-mlx5_flow_async_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
-				 const struct rte_flow_op_attr *attr,
-				 const struct rte_flow_indir_action_conf *conf,
-				 const struct rte_flow_action *action,
-				 void *user_data,
-				 struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	return fops->async_action_create(dev, queue, attr, conf, action,
-					 user_data, error);
-}
-
-/**
- * Update shared action.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   Which queue to be used..
- * @param[in] attr
- *   Operation attribute.
- * @param[in] handle
- *   Action handle to be updated.
- * @param[in] update
- *   Update value.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *   0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_action_handle_update(struct rte_eth_dev *dev, uint32_t queue,
-				     const struct rte_flow_op_attr *attr,
-				     struct rte_flow_action_handle *handle,
-				     const void *update,
-				     void *user_data,
-				     struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	return fops->async_action_update(dev, queue, attr, handle,
-					 update, user_data, error);
-}
-
-static int
-mlx5_flow_async_action_handle_query_update
-	(struct rte_eth_dev *dev, uint32_t queue_id,
-	 const struct rte_flow_op_attr *op_attr,
-	 struct rte_flow_action_handle *action_handle,
-	 const void *update, void *query,
-	 enum rte_flow_query_update_mode qu_mode,
-	 void *user_data, struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-		flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	if (!fops || !fops->async_action_query_update)
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-					  "async query_update not supported");
-	return fops->async_action_query_update
-			   (dev, queue_id, op_attr, action_handle,
-			    update, query, qu_mode, user_data, error);
-}
-
-/**
- * Query shared action.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   Which queue to be used..
- * @param[in] attr
- *   Operation attribute.
- * @param[in] handle
- *   Action handle to be updated.
- * @param[in] data
- *   Pointer query result data.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *   0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_action_handle_query(struct rte_eth_dev *dev, uint32_t queue,
-				    const struct rte_flow_op_attr *attr,
-				    const struct rte_flow_action_handle *handle,
-				    void *data,
-				    void *user_data,
-				    struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	return fops->async_action_query(dev, queue, attr, handle,
-					data, user_data, error);
-}
-
-/**
- * Destroy shared action.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- * @param[in] queue
- *   Which queue to be used..
- * @param[in] attr
- *   Operation attribute.
- * @param[in] handle
- *   Action handle to be destroyed.
- * @param[in] user_data
- *   Pointer to the user_data.
- * @param[out] error
- *   Pointer to error structure.
- *
- * @return
- *   0 on success, negative value otherwise and rte_errno is set.
- */
-static int
-mlx5_flow_async_action_handle_destroy(struct rte_eth_dev *dev, uint32_t queue,
-				      const struct rte_flow_op_attr *attr,
-				      struct rte_flow_action_handle *handle,
-				      void *user_data,
-				      struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops =
-			flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
-
-	return fops->async_action_destroy(dev, queue, attr, handle,
-					  user_data, error);
-}
-
 /**
  * Allocate a new memory for the counter values wrapped by all the needed
  * management.
@@ -11015,41 +10470,6 @@ mlx5_action_list_handle_destroy(struct rte_eth_dev *dev,
 	return fops->action_list_handle_destroy(dev, handle, error);
 }
 
-static struct rte_flow_action_list_handle *
-mlx5_flow_async_action_list_handle_create(struct rte_eth_dev *dev,
-					  uint32_t queue_id,
-					  const struct
-					  rte_flow_op_attr *op_attr,
-					  const struct
-					  rte_flow_indir_action_conf *conf,
-					  const struct rte_flow_action *actions,
-					  void *user_data,
-					  struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-
-	MLX5_DRV_FOPS_OR_ERR(dev, fops, async_action_list_handle_create, NULL);
-	return fops->async_action_list_handle_create(dev, queue_id, op_attr,
-						     conf, actions, user_data,
-						     error);
-}
-
-static int
-mlx5_flow_async_action_list_handle_destroy
-	(struct rte_eth_dev *dev, uint32_t queue_id,
-	 const struct rte_flow_op_attr *op_attr,
-	 struct rte_flow_action_list_handle *action_handle,
-	 void *user_data, struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-
-	MLX5_DRV_FOPS_OR_ERR(dev, fops,
-			     async_action_list_handle_destroy, ENOTSUP);
-	return fops->async_action_list_handle_destroy(dev, queue_id, op_attr,
-						      action_handle, user_data,
-						      error);
-}
-
 static int
 mlx5_flow_action_list_handle_query_update(struct rte_eth_dev *dev,
 					  const
@@ -11065,32 +10485,6 @@ mlx5_flow_action_list_handle_query_update(struct rte_eth_dev *dev,
 	return fops->action_list_handle_query_update(dev, handle, update, query,
 						     mode, error);
 }
-
-static int
-mlx5_flow_async_action_list_handle_query_update(struct rte_eth_dev *dev,
-						uint32_t queue_id,
-						const
-						struct rte_flow_op_attr *op_attr,
-						const struct
-						rte_flow_action_list_handle *handle,
-						const void **update,
-						void **query,
-						enum
-						rte_flow_query_update_mode mode,
-						void *user_data,
-						struct rte_flow_error *error)
-{
-	const struct mlx5_flow_driver_ops *fops;
-
-	MLX5_DRV_FOPS_OR_ERR(dev, fops,
-			     async_action_list_handle_query_update, ENOTSUP);
-	return fops->async_action_list_handle_query_update(dev, queue_id, op_attr,
-							   handle, update,
-							   query, mode,
-							   user_data, error);
-}
-
-
 static int
 mlx5_flow_calc_table_hash(struct rte_eth_dev *dev,
 			  const struct rte_flow_template_table *table,
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index da873ae2e2..6f0659fa52 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -3,6 +3,7 @@
  */
 
 #include <rte_flow.h>
+#include <rte_flow_driver.h>
 
 #include <mlx5_malloc.h>
 
@@ -14,6 +15,9 @@
 #if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H)
 #include "mlx5_hws_cnt.h"
 
+/** Fast path async flow API functions. */
+static struct rte_flow_fp_ops mlx5_flow_hw_fp_ops;
+
 /* The maximum actions support in the flow. */
 #define MLX5_HW_MAX_ACTS 16
 
@@ -9543,6 +9547,7 @@ flow_hw_configure(struct rte_eth_dev *dev,
 		mlx5_free(_queue_attr);
 	if (port_attr->flags & RTE_FLOW_PORT_FLAG_STRICT_QUEUE)
 		priv->hws_strict_queue = 1;
+	dev->flow_fp_ops = &mlx5_flow_hw_fp_ops;
 	return 0;
 err:
 	if (priv->hws_ctpool) {
@@ -9617,6 +9622,7 @@ flow_hw_resource_release(struct rte_eth_dev *dev)
 
 	if (!priv->dr_ctx)
 		return;
+	dev->flow_fp_ops = &rte_flow_fp_default_ops;
 	flow_hw_rxq_flag_set(dev, false);
 	flow_hw_flush_all_ctrl_flows(dev);
 	flow_hw_cleanup_tx_repr_tagging(dev);
@@ -12993,3 +12999,21 @@ mlx5_reformat_action_destroy(struct rte_eth_dev *dev,
 	return 0;
 }
 #endif
+
+static struct rte_flow_fp_ops mlx5_flow_hw_fp_ops = {
+	.async_create = flow_hw_async_flow_create,
+	.async_create_by_index = flow_hw_async_flow_create_by_index,
+	.async_actions_update = flow_hw_async_flow_update,
+	.async_destroy = flow_hw_async_flow_destroy,
+	.push = flow_hw_push,
+	.pull = flow_hw_pull,
+	.async_action_handle_create = flow_hw_action_handle_create,
+	.async_action_handle_destroy = flow_hw_action_handle_destroy,
+	.async_action_handle_update = flow_hw_action_handle_update,
+	.async_action_handle_query = flow_hw_action_handle_query,
+	.async_action_handle_query_update = flow_hw_async_action_handle_query_update,
+	.async_action_list_handle_create = flow_hw_async_action_list_handle_create,
+	.async_action_list_handle_destroy = flow_hw_async_action_list_handle_destroy,
+	.async_action_list_handle_query_update =
+		flow_hw_async_action_list_handle_query_update,
+};
diff --git a/lib/ethdev/ethdev_driver.c b/lib/ethdev/ethdev_driver.c
index bd917a15fc..34909a3018 100644
--- a/lib/ethdev/ethdev_driver.c
+++ b/lib/ethdev/ethdev_driver.c
@@ -10,6 +10,7 @@
 
 #include "ethdev_driver.h"
 #include "ethdev_private.h"
+#include "rte_flow_driver.h"
 
 /**
  * A set of values to describe the possible states of a switch domain.
@@ -110,6 +111,7 @@ rte_eth_dev_allocate(const char *name)
 	}
 
 	eth_dev = eth_dev_get(port_id);
+	eth_dev->flow_fp_ops = &rte_flow_fp_default_ops;
 	strlcpy(eth_dev->data->name, name, sizeof(eth_dev->data->name));
 	eth_dev->data->port_id = port_id;
 	eth_dev->data->backer_port_id = RTE_MAX_ETHPORTS;
@@ -245,6 +247,8 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
 
 	eth_dev_fp_ops_reset(rte_eth_fp_ops + eth_dev->data->port_id);
 
+	eth_dev->flow_fp_ops = &rte_flow_fp_default_ops;
+
 	rte_spinlock_lock(rte_mcfg_ethdev_get_lock());
 
 	eth_dev->state = RTE_ETH_DEV_UNUSED;
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index f05f68a67c..2dfa8e238b 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -73,6 +73,10 @@ struct rte_eth_dev {
 	struct rte_eth_dev_data *data;
 	void *process_private; /**< Pointer to per-process device data */
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
+	/**
+	 * Fast path flow API functions exported by PMD.
+	 */
+	const struct rte_flow_fp_ops *flow_fp_ops;
 	struct rte_device *device; /**< Backing device */
 	struct rte_intr_handle *intr_handle; /**< Device interrupt handle */
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 3f58d792f9..7cd04c3637 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -2014,16 +2014,26 @@ rte_flow_async_create(uint16_t port_id,
 		      struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	struct rte_flow *flow;
 
-	flow = ops->async_create(dev, queue_id,
-				 op_attr, template_table,
-				 pattern, pattern_template_index,
-				 actions, actions_template_index,
-				 user_data, error);
-	if (flow == NULL)
-		flow_err(port_id, -rte_errno, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENODEV));
+		return NULL;
+	}
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_create) {
+		rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENOSYS));
+		return NULL;
+	}
+#endif
+
+	flow = dev->flow_fp_ops->async_create(dev, queue_id,
+					      op_attr, template_table,
+					      pattern, pattern_template_index,
+					      actions, actions_template_index,
+					      user_data, error);
 
 	rte_flow_trace_async_create(port_id, queue_id, op_attr, template_table,
 				    pattern, pattern_template_index, actions,
@@ -2044,16 +2054,24 @@ rte_flow_async_create_by_index(uint16_t port_id,
 			       struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
-	struct rte_flow *flow;
 
-	flow = ops->async_create_by_index(dev, queue_id,
-					  op_attr, template_table, rule_index,
-					  actions, actions_template_index,
-					  user_data, error);
-	if (flow == NULL)
-		flow_err(port_id, -rte_errno, error);
-	return flow;
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENODEV));
+		return NULL;
+	}
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_create_by_index) {
+		rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENOSYS));
+		return NULL;
+	}
+#endif
+
+	return dev->flow_fp_ops->async_create_by_index(dev, queue_id,
+						       op_attr, template_table, rule_index,
+						       actions, actions_template_index,
+						       user_data, error);
 }
 
 int
@@ -2065,14 +2083,20 @@ rte_flow_async_destroy(uint16_t port_id,
 		       struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
 
-	ret = flow_err(port_id,
-		       ops->async_destroy(dev, queue_id,
-					  op_attr, flow,
-					  user_data, error),
-		       error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_destroy)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_destroy(dev, queue_id,
+					      op_attr, flow,
+					      user_data, error);
 
 	rte_flow_trace_async_destroy(port_id, queue_id, op_attr, flow,
 				     user_data, ret);
@@ -2091,15 +2115,21 @@ rte_flow_async_actions_update(uint16_t port_id,
 			      struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
 
-	ret = flow_err(port_id,
-		       ops->async_actions_update(dev, queue_id, op_attr,
-						 flow, actions,
-						 actions_template_index,
-						 user_data, error),
-		       error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_actions_update)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_actions_update(dev, queue_id, op_attr,
+						     flow, actions,
+						     actions_template_index,
+						     user_data, error);
 
 	rte_flow_trace_async_actions_update(port_id, queue_id, op_attr, flow,
 					    actions, actions_template_index,
@@ -2114,12 +2144,18 @@ rte_flow_push(uint16_t port_id,
 	      struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
 
-	ret = flow_err(port_id,
-		       ops->push(dev, queue_id, error),
-		       error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->push)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->push(dev, queue_id, error);
 
 	rte_flow_trace_push(port_id, queue_id, ret);
 
@@ -2134,16 +2170,22 @@ rte_flow_pull(uint16_t port_id,
 	      struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
-	int rc;
 
-	ret = ops->pull(dev, queue_id, res, n_res, error);
-	rc = ret ? ret : flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->pull)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->pull(dev, queue_id, res, n_res, error);
 
-	rte_flow_trace_pull(port_id, queue_id, res, n_res, rc);
+	rte_flow_trace_pull(port_id, queue_id, res, n_res, ret);
 
-	return rc;
+	return ret;
 }
 
 struct rte_flow_action_handle *
@@ -2156,13 +2198,24 @@ rte_flow_async_action_handle_create(uint16_t port_id,
 		struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	struct rte_flow_action_handle *handle;
 
-	handle = ops->async_action_handle_create(dev, queue_id, op_attr,
-					     indir_action_conf, action, user_data, error);
-	if (handle == NULL)
-		flow_err(port_id, -rte_errno, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENODEV));
+		return NULL;
+	}
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_handle_create) {
+		rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENOSYS));
+		return NULL;
+	}
+#endif
+
+	handle = dev->flow_fp_ops->async_action_handle_create(dev, queue_id, op_attr,
+							      indir_action_conf, action,
+							      user_data, error);
 
 	rte_flow_trace_async_action_handle_create(port_id, queue_id, op_attr,
 						  indir_action_conf, action,
@@ -2180,12 +2233,19 @@ rte_flow_async_action_handle_destroy(uint16_t port_id,
 		struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
 
-	ret = ops->async_action_handle_destroy(dev, queue_id, op_attr,
-					   action_handle, user_data, error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_handle_destroy)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_handle_destroy(dev, queue_id, op_attr,
+							    action_handle, user_data, error);
 
 	rte_flow_trace_async_action_handle_destroy(port_id, queue_id, op_attr,
 						   action_handle, user_data, ret);
@@ -2203,12 +2263,19 @@ rte_flow_async_action_handle_update(uint16_t port_id,
 		struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
 
-	ret = ops->async_action_handle_update(dev, queue_id, op_attr,
-					  action_handle, update, user_data, error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_handle_update)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_handle_update(dev, queue_id, op_attr,
+							   action_handle, update, user_data, error);
 
 	rte_flow_trace_async_action_handle_update(port_id, queue_id, op_attr,
 						  action_handle, update,
@@ -2227,14 +2294,19 @@ rte_flow_async_action_handle_query(uint16_t port_id,
 		struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
 	int ret;
 
-	if (unlikely(!ops))
-		return -rte_errno;
-	ret = ops->async_action_handle_query(dev, queue_id, op_attr,
-					  action_handle, data, user_data, error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_handle_query)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_handle_query(dev, queue_id, op_attr,
+							  action_handle, data, user_data, error);
 
 	rte_flow_trace_async_action_handle_query(port_id, queue_id, op_attr,
 						 action_handle, data, user_data,
@@ -2277,24 +2349,21 @@ rte_flow_async_action_handle_query_update(uint16_t port_id, uint32_t queue_id,
 					  void *user_data,
 					  struct rte_flow_error *error)
 {
-	int ret;
-	struct rte_eth_dev *dev;
-	const struct rte_flow_ops *ops;
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (!handle)
-		return -EINVAL;
-	if (!update && !query)
-		return -EINVAL;
-	dev = &rte_eth_devices[port_id];
-	ops = rte_flow_ops_get(port_id, error);
-	if (!ops || !ops->async_action_handle_query_update)
-		return -ENOTSUP;
-	ret = ops->async_action_handle_query_update(dev, queue_id, attr,
-						    handle, update,
-						    query, mode,
-						    user_data, error);
-	return flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_handle_query_update)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	return dev->flow_fp_ops->async_action_handle_query_update(dev, queue_id, attr,
+								  handle, update,
+								  query, mode,
+								  user_data, error);
 }
 
 struct rte_flow_action_list_handle *
@@ -2354,24 +2423,28 @@ rte_flow_async_action_list_handle_create(uint16_t port_id, uint32_t queue_id,
 					 void *user_data,
 					 struct rte_flow_error *error)
 {
-	int ret;
-	struct rte_eth_dev *dev;
-	const struct rte_flow_ops *ops;
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	struct rte_flow_action_list_handle *handle;
+	int ret;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
-	ops = rte_flow_ops_get(port_id, error);
-	if (!ops || !ops->async_action_list_handle_create) {
-		rte_flow_error_set(error, ENOTSUP,
-				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-				   "action_list handle not supported");
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENODEV));
 		return NULL;
 	}
-	dev = &rte_eth_devices[port_id];
-	handle = ops->async_action_list_handle_create(dev, queue_id, attr, conf,
-						      actions, user_data,
-						      error);
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_list_handle_create) {
+		rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   rte_strerror(ENOSYS));
+		return NULL;
+	}
+#endif
+
+	handle = dev->flow_fp_ops->async_action_list_handle_create(dev, queue_id, attr, conf,
+								   actions, user_data,
+								   error);
 	ret = flow_err(port_id, -rte_errno, error);
+
 	rte_flow_trace_async_action_list_handle_create(port_id, queue_id, attr,
 						       conf, actions, user_data,
 						       ret);
@@ -2384,20 +2457,21 @@ rte_flow_async_action_list_handle_destroy(uint16_t port_id, uint32_t queue_id,
 				 struct rte_flow_action_list_handle *handle,
 				 void *user_data, struct rte_flow_error *error)
 {
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	int ret;
-	struct rte_eth_dev *dev;
-	const struct rte_flow_ops *ops;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	ops = rte_flow_ops_get(port_id, error);
-	if (!ops || !ops->async_action_list_handle_destroy)
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "async action_list handle not supported");
-	dev = &rte_eth_devices[port_id];
-	ret = ops->async_action_list_handle_destroy(dev, queue_id, op_attr,
-						    handle, user_data, error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_list_handle_destroy)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_list_handle_destroy(dev, queue_id, op_attr,
+								 handle, user_data, error);
+
 	rte_flow_trace_async_action_list_handle_destroy(port_id, queue_id,
 							op_attr, handle,
 							user_data, ret);
@@ -2438,22 +2512,23 @@ rte_flow_async_action_list_handle_query_update(uint16_t port_id, uint32_t queue_
 			 enum rte_flow_query_update_mode mode,
 			 void *user_data, struct rte_flow_error *error)
 {
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 	int ret;
-	struct rte_eth_dev *dev;
-	const struct rte_flow_ops *ops;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	ops = rte_flow_ops_get(port_id, error);
-	if (!ops || !ops->async_action_list_handle_query_update)
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "action_list async query_update not supported");
-	dev = &rte_eth_devices[port_id];
-	ret = ops->async_action_list_handle_query_update(dev, queue_id, attr,
-							 handle, update, query,
-							 mode, user_data,
-							 error);
-	ret = flow_err(port_id, ret, error);
+#ifdef RTE_FLOW_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return rte_flow_error_set(error, ENODEV, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENODEV));
+	if (!dev->flow_fp_ops || !dev->flow_fp_ops->async_action_list_handle_query_update)
+		return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  rte_strerror(ENOSYS));
+#endif
+
+	ret = dev->flow_fp_ops->async_action_list_handle_query_update(dev, queue_id, attr,
+								      handle, update, query,
+								      mode, user_data,
+								      error);
+
 	rte_flow_trace_async_action_list_handle_query_update(port_id, queue_id,
 							     attr, handle,
 							     update, query,
@@ -2482,3 +2557,216 @@ rte_flow_calc_table_hash(uint16_t port_id, const struct rte_flow_template_table
 					hash, error);
 	return flow_err(port_id, ret, error);
 }
+
+static struct rte_flow *
+rte_flow_dummy_async_create(struct rte_eth_dev *dev __rte_unused,
+			    uint32_t queue __rte_unused,
+			    const struct rte_flow_op_attr *attr __rte_unused,
+			    struct rte_flow_template_table *table __rte_unused,
+			    const struct rte_flow_item items[] __rte_unused,
+			    uint8_t pattern_template_index __rte_unused,
+			    const struct rte_flow_action actions[] __rte_unused,
+			    uint8_t action_template_index __rte_unused,
+			    void *user_data __rte_unused,
+			    struct rte_flow_error *error)
+{
+	rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			   rte_strerror(ENOSYS));
+	return NULL;
+}
+
+static struct rte_flow *
+rte_flow_dummy_async_create_by_index(struct rte_eth_dev *dev __rte_unused,
+				     uint32_t queue __rte_unused,
+				     const struct rte_flow_op_attr *attr __rte_unused,
+				     struct rte_flow_template_table *table __rte_unused,
+				     uint32_t rule_index __rte_unused,
+				     const struct rte_flow_action actions[] __rte_unused,
+				     uint8_t action_template_index __rte_unused,
+				     void *user_data __rte_unused,
+				     struct rte_flow_error *error)
+{
+	rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			   rte_strerror(ENOSYS));
+	return NULL;
+}
+
+static int
+rte_flow_dummy_async_actions_update(struct rte_eth_dev *dev __rte_unused,
+				    uint32_t queue_id __rte_unused,
+				    const struct rte_flow_op_attr *op_attr __rte_unused,
+				    struct rte_flow *flow __rte_unused,
+				    const struct rte_flow_action actions[] __rte_unused,
+				    uint8_t actions_template_index __rte_unused,
+				    void *user_data __rte_unused,
+				    struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_destroy(struct rte_eth_dev *dev __rte_unused,
+			     uint32_t queue_id __rte_unused,
+			     const struct rte_flow_op_attr *op_attr __rte_unused,
+			     struct rte_flow *flow __rte_unused,
+			     void *user_data __rte_unused,
+			     struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_push(struct rte_eth_dev *dev __rte_unused,
+		    uint32_t queue_id __rte_unused,
+		    struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_pull(struct rte_eth_dev *dev __rte_unused,
+		    uint32_t queue_id __rte_unused,
+		    struct rte_flow_op_result res[] __rte_unused,
+		    uint16_t n_res __rte_unused,
+		    struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static struct rte_flow_action_handle *
+rte_flow_dummy_async_action_handle_create(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	const struct rte_flow_indir_action_conf *indir_action_conf __rte_unused,
+	const struct rte_flow_action *action __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			   rte_strerror(ENOSYS));
+	return NULL;
+}
+
+static int
+rte_flow_dummy_async_action_handle_destroy(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	struct rte_flow_action_handle *action_handle __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_action_handle_update(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	struct rte_flow_action_handle *action_handle __rte_unused,
+	const void *update __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_action_handle_query(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	const struct rte_flow_action_handle *action_handle __rte_unused,
+	void *data __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_action_handle_query_update(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *attr __rte_unused,
+	struct rte_flow_action_handle *handle __rte_unused,
+	const void *update __rte_unused,
+	void *query __rte_unused,
+	enum rte_flow_query_update_mode mode __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static struct rte_flow_action_list_handle *
+rte_flow_dummy_async_action_list_handle_create(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *attr __rte_unused,
+	const struct rte_flow_indir_action_conf *conf __rte_unused,
+	const struct rte_flow_action *actions __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			   rte_strerror(ENOSYS));
+	return NULL;
+}
+
+static int
+rte_flow_dummy_async_action_list_handle_destroy(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *op_attr __rte_unused,
+	struct rte_flow_action_list_handle *handle __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+static int
+rte_flow_dummy_async_action_list_handle_query_update(
+	struct rte_eth_dev *dev __rte_unused,
+	uint32_t queue_id __rte_unused,
+	const struct rte_flow_op_attr *attr __rte_unused,
+	const struct rte_flow_action_list_handle *handle __rte_unused,
+	const void **update __rte_unused,
+	void **query __rte_unused,
+	enum rte_flow_query_update_mode mode __rte_unused,
+	void *user_data __rte_unused,
+	struct rte_flow_error *error)
+{
+	return rte_flow_error_set(error, ENOSYS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				  rte_strerror(ENOSYS));
+}
+
+struct rte_flow_fp_ops rte_flow_fp_default_ops = {
+	.async_create = rte_flow_dummy_async_create,
+	.async_create_by_index = rte_flow_dummy_async_create_by_index,
+	.async_actions_update = rte_flow_dummy_async_actions_update,
+	.async_destroy = rte_flow_dummy_async_destroy,
+	.push = rte_flow_dummy_push,
+	.pull = rte_flow_dummy_pull,
+	.async_action_handle_create = rte_flow_dummy_async_action_handle_create,
+	.async_action_handle_destroy = rte_flow_dummy_async_action_handle_destroy,
+	.async_action_handle_update = rte_flow_dummy_async_action_handle_update,
+	.async_action_handle_query = rte_flow_dummy_async_action_handle_query,
+	.async_action_handle_query_update = rte_flow_dummy_async_action_handle_query_update,
+	.async_action_list_handle_create = rte_flow_dummy_async_action_list_handle_create,
+	.async_action_list_handle_destroy = rte_flow_dummy_async_action_list_handle_destroy,
+	.async_action_list_handle_query_update =
+		rte_flow_dummy_async_action_list_handle_query_update,
+};
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index f35f659503..dd9d01045d 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -234,122 +234,12 @@ struct rte_flow_ops {
 		 const struct rte_flow_group_attr *attr,
 		 const struct rte_flow_action actions[],
 		 struct rte_flow_error *err);
-	/** See rte_flow_async_create() */
-	struct rte_flow *(*async_create)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_template_table *template_table,
-		 const struct rte_flow_item pattern[],
-		 uint8_t pattern_template_index,
-		 const struct rte_flow_action actions[],
-		 uint8_t actions_template_index,
-		 void *user_data,
-		 struct rte_flow_error *err);
-	/** See rte_flow_async_create_by_index() */
-	struct rte_flow *(*async_create_by_index)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_template_table *template_table,
-		 uint32_t rule_index,
-		 const struct rte_flow_action actions[],
-		 uint8_t actions_template_index,
-		 void *user_data,
-		 struct rte_flow_error *err);
-	/** See rte_flow_async_destroy() */
-	int (*async_destroy)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow *flow,
-		 void *user_data,
-		 struct rte_flow_error *err);
-	/** See rte_flow_push() */
-	int (*push)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 struct rte_flow_error *err);
-	/** See rte_flow_pull() */
-	int (*pull)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 struct rte_flow_op_result res[],
-		 uint16_t n_res,
-		 struct rte_flow_error *error);
-	/** See rte_flow_async_action_handle_create() */
-	struct rte_flow_action_handle *(*async_action_handle_create)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 const struct rte_flow_indir_action_conf *indir_action_conf,
-		 const struct rte_flow_action *action,
-		 void *user_data,
-		 struct rte_flow_error *err);
-	/** See rte_flow_async_action_handle_destroy() */
-	int (*async_action_handle_destroy)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_action_handle *action_handle,
-		 void *user_data,
-		 struct rte_flow_error *error);
-	/** See rte_flow_async_action_handle_update() */
-	int (*async_action_handle_update)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_action_handle *action_handle,
-		 const void *update,
-		 void *user_data,
-		 struct rte_flow_error *error);
-	/** See rte_flow_async_action_handle_query() */
-	int (*async_action_handle_query)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 const struct rte_flow_action_handle *action_handle,
-		 void *data,
-		 void *user_data,
-		 struct rte_flow_error *error);
-	/** See rte_flow_async_action_handle_query_update */
-	int (*async_action_handle_query_update)
-		(struct rte_eth_dev *dev, uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_action_handle *action_handle,
-		 const void *update, void *query,
-		 enum rte_flow_query_update_mode qu_mode,
-		 void *user_data, struct rte_flow_error *error);
 	/** See rte_flow_actions_update(). */
 	int (*actions_update)
 		(struct rte_eth_dev *dev,
 		 struct rte_flow *flow,
 		 const struct rte_flow_action actions[],
 		 struct rte_flow_error *error);
-	/** See rte_flow_async_actions_update() */
-	int (*async_actions_update)
-		(struct rte_eth_dev *dev,
-		 uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow *flow,
-		 const struct rte_flow_action actions[],
-		 uint8_t actions_template_index,
-		 void *user_data,
-		 struct rte_flow_error *error);
-	/** @see rte_flow_async_action_list_handle_create() */
-	struct rte_flow_action_list_handle *
-	(*async_action_list_handle_create)
-		(struct rte_eth_dev *dev, uint32_t queue_id,
-		 const struct rte_flow_op_attr *attr,
-		 const struct rte_flow_indir_action_conf *conf,
-		 const struct rte_flow_action *actions,
-		 void *user_data, struct rte_flow_error *error);
-	/** @see rte_flow_async_action_list_handle_destroy() */
-	int (*async_action_list_handle_destroy)
-		(struct rte_eth_dev *dev, uint32_t queue_id,
-		 const struct rte_flow_op_attr *op_attr,
-		 struct rte_flow_action_list_handle *action_handle,
-		 void *user_data, struct rte_flow_error *error);
 	/** @see rte_flow_action_list_handle_query_update() */
 	int (*action_list_handle_query_update)
 		(struct rte_eth_dev *dev,
@@ -357,14 +247,6 @@ struct rte_flow_ops {
 		 const void **update, void **query,
 		 enum rte_flow_query_update_mode mode,
 		 struct rte_flow_error *error);
-	/** @see rte_flow_async_action_list_handle_query_update() */
-	int (*async_action_list_handle_query_update)
-		(struct rte_eth_dev *dev, uint32_t queue_id,
-		 const struct rte_flow_op_attr *attr,
-		 const struct rte_flow_action_list_handle *handle,
-		 const void **update, void **query,
-		 enum rte_flow_query_update_mode mode,
-		 void *user_data, struct rte_flow_error *error);
 	/** @see rte_flow_calc_table_hash() */
 	int (*flow_calc_table_hash)
 		(struct rte_eth_dev *dev, const struct rte_flow_template_table *table,
@@ -394,6 +276,165 @@ rte_flow_ops_get(uint16_t port_id, struct rte_flow_error *error);
 int
 rte_flow_restore_info_dynflag_register(void);
 
+/** @internal Enqueue rule creation operation. */
+typedef struct rte_flow *(*rte_flow_async_create_t)(struct rte_eth_dev *dev,
+						    uint32_t queue,
+						    const struct rte_flow_op_attr *attr,
+						    struct rte_flow_template_table *table,
+						    const struct rte_flow_item *items,
+						    uint8_t pattern_template_index,
+						    const struct rte_flow_action *actions,
+						    uint8_t action_template_index,
+						    void *user_data,
+						    struct rte_flow_error *error);
+
+/** @internal Enqueue rule creation by index operation. */
+typedef struct rte_flow *(*rte_flow_async_create_by_index_t)(struct rte_eth_dev *dev,
+							     uint32_t queue,
+							     const struct rte_flow_op_attr *attr,
+							     struct rte_flow_template_table *table,
+							     uint32_t rule_index,
+							     const struct rte_flow_action *actions,
+							     uint8_t action_template_index,
+							     void *user_data,
+							     struct rte_flow_error *error);
+
+/** @internal Enqueue rule update operation. */
+typedef int (*rte_flow_async_actions_update_t)(struct rte_eth_dev *dev,
+					       uint32_t queue_id,
+					       const struct rte_flow_op_attr *op_attr,
+					       struct rte_flow *flow,
+					       const struct rte_flow_action *actions,
+					       uint8_t actions_template_index,
+					       void *user_data,
+					       struct rte_flow_error *error);
+
+/** @internal Enqueue rule destruction operation. */
+typedef int (*rte_flow_async_destroy_t)(struct rte_eth_dev *dev,
+					uint32_t queue_id,
+					const struct rte_flow_op_attr *op_attr,
+					struct rte_flow *flow,
+					void *user_data,
+					struct rte_flow_error *error);
+
+/** @internal Push all internally stored rules to the HW. */
+typedef int (*rte_flow_push_t)(struct rte_eth_dev *dev,
+			       uint32_t queue_id,
+			       struct rte_flow_error *error);
+
+/** @internal Pull the flow rule operations results from the HW. */
+typedef int (*rte_flow_pull_t)(struct rte_eth_dev *dev,
+			       uint32_t queue_id,
+			       struct rte_flow_op_result *res,
+			       uint16_t n_res,
+			       struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action creation operation. */
+typedef struct rte_flow_action_handle *(*rte_flow_async_action_handle_create_t)(
+					struct rte_eth_dev *dev,
+					uint32_t queue_id,
+					const struct rte_flow_op_attr *op_attr,
+					const struct rte_flow_indir_action_conf *indir_action_conf,
+					const struct rte_flow_action *action,
+					void *user_data,
+					struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action destruction operation. */
+typedef int (*rte_flow_async_action_handle_destroy_t)(struct rte_eth_dev *dev,
+						      uint32_t queue_id,
+						      const struct rte_flow_op_attr *op_attr,
+						      struct rte_flow_action_handle *action_handle,
+						      void *user_data,
+						      struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action update operation. */
+typedef int (*rte_flow_async_action_handle_update_t)(struct rte_eth_dev *dev,
+						     uint32_t queue_id,
+						     const struct rte_flow_op_attr *op_attr,
+						     struct rte_flow_action_handle *action_handle,
+						     const void *update,
+						     void *user_data,
+						     struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action query operation. */
+typedef int (*rte_flow_async_action_handle_query_t)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 const struct rte_flow_op_attr *op_attr,
+		 const struct rte_flow_action_handle *action_handle,
+		 void *data,
+		 void *user_data,
+		 struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action query and/or update operation. */
+typedef int (*rte_flow_async_action_handle_query_update_t)(struct rte_eth_dev *dev,
+							   uint32_t queue_id,
+							   const struct rte_flow_op_attr *attr,
+							   struct rte_flow_action_handle *handle,
+							   const void *update, void *query,
+							   enum rte_flow_query_update_mode mode,
+							   void *user_data,
+							   struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action list creation operation. */
+typedef struct rte_flow_action_list_handle *(*rte_flow_async_action_list_handle_create_t)(
+	struct rte_eth_dev *dev,
+	uint32_t queue_id,
+	const struct rte_flow_op_attr *attr,
+	const struct rte_flow_indir_action_conf *conf,
+	const struct rte_flow_action *actions,
+	void *user_data,
+	struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action list destruction operation. */
+typedef int (*rte_flow_async_action_list_handle_destroy_t)(
+	struct rte_eth_dev *dev,
+	uint32_t queue_id,
+	const struct rte_flow_op_attr *op_attr,
+	struct rte_flow_action_list_handle *handle,
+	void *user_data,
+	struct rte_flow_error *error);
+
+/** @internal Enqueue indirect action list query and/or update operation. */
+typedef int (*rte_flow_async_action_list_handle_query_update_t)(
+	struct rte_eth_dev *dev,
+	uint32_t queue_id,
+	const struct rte_flow_op_attr *attr,
+	const struct rte_flow_action_list_handle *handle,
+	const void **update,
+	void **query,
+	enum rte_flow_query_update_mode mode,
+	void *user_data,
+	struct rte_flow_error *error);
+
+/**
+ * @internal
+ *
+ * Fast path async flow functions are held in a flat array, one entry per ethdev.
+ */
+struct rte_flow_fp_ops {
+	rte_flow_async_create_t async_create;
+	rte_flow_async_create_by_index_t async_create_by_index;
+	rte_flow_async_actions_update_t async_actions_update;
+	rte_flow_async_destroy_t async_destroy;
+	rte_flow_push_t push;
+	rte_flow_pull_t pull;
+	rte_flow_async_action_handle_create_t async_action_handle_create;
+	rte_flow_async_action_handle_destroy_t async_action_handle_destroy;
+	rte_flow_async_action_handle_update_t async_action_handle_update;
+	rte_flow_async_action_handle_query_t async_action_handle_query;
+	rte_flow_async_action_handle_query_update_t async_action_handle_query_update;
+	rte_flow_async_action_list_handle_create_t async_action_list_handle_create;
+	rte_flow_async_action_list_handle_destroy_t async_action_list_handle_destroy;
+	rte_flow_async_action_list_handle_query_update_t async_action_list_handle_query_update;
+} __rte_cache_aligned;
+
+/**
+ * @internal
+ * Default implementation of fast path flow API functions.
+ */
+extern struct rte_flow_fp_ops rte_flow_fp_default_ops;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index a050baab0f..61e38a9f00 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -348,4 +348,6 @@ INTERNAL {
 	rte_eth_representor_id_get;
 	rte_eth_switch_domain_alloc;
 	rte_eth_switch_domain_free;
+
+	rte_flow_fp_default_ops;
 };
-- 
2.25.1


^ permalink raw reply	[relevance 1%]

* RE: [RFC] ethdev: fast path async flow API
  2024-01-30 12:17  0%               ` Ferruh Yigit
@ 2024-01-30 16:08  0%                 ` Dariusz Sosnowski
  0 siblings, 0 replies; 200+ results
From: Dariusz Sosnowski @ 2024-01-30 16:08 UTC (permalink / raw)
  To: Ferruh Yigit, Stephen Hemminger
  Cc: NBU-Contact-Thomas Monjalon (EXTERNAL), Andrew Rybchenko, Ori Kam, dev

> -----Original Message-----
> From: Ferruh Yigit <ferruh.yigit@amd.com>
> Sent: Tuesday, January 30, 2024 13:17
> To: Dariusz Sosnowski <dsosnowski@nvidia.com>; Stephen Hemminger
> <stephen@networkplumber.org>
> Cc: NBU-Contact-Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>;
> Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>; Ori Kam
> <orika@nvidia.com>; dev@dpdk.org
> Subject: Re: [RFC] ethdev: fast path async flow API 
> 
> On 1/30/2024 12:06 PM, Dariusz Sosnowski wrote:
> > Hi Ferruh,
> >
> >> -----Original Message-----
> >> From: Ferruh Yigit <ferruh.yigit@amd.com>
> >> Sent: Monday, January 29, 2024 18:36
> >> To: Dariusz Sosnowski <dsosnowski@nvidia.com>; Stephen Hemminger
> >> <stephen@networkplumber.org>
> >> Cc: NBU-Contact-Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>;
> >> Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>; Ori Kam
> >> <orika@nvidia.com>; dev@dpdk.org
> >> Subject: Re: [RFC] ethdev: fast path async flow API
> >>
> >> On 1/29/2024 1:38 PM, Dariusz Sosnowski wrote:
> >>> Hi all,
> >>>
> >>>> -----Original Message-----
> >>>> From: Dariusz Sosnowski <dsosnowski@nvidia.com>
> >>>> Sent: Tuesday, January 23, 2024 12:37
> >>>> To: Stephen Hemminger <stephen@networkplumber.org>
> >>>> Cc: NBU-Contact-Thomas Monjalon (EXTERNAL)
> <thomas@monjalon.net>;
> >>>> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> >>>> <andrew.rybchenko@oktetlabs.ru>; Ori Kam <orika@nvidia.com>;
> >>>> dev@dpdk.org
> >>>> Subject: RE: [RFC] ethdev: fast path async flow API
> >>>>
> >>>> Hi Stephen,
> >>>>
> >>>> Sorry for such a late response.
> >>>>
> >>>> From: Stephen Hemminger <stephen@networkplumber.org>
> >>>> Sent: Thursday, January 4, 2024 02:08
> >>>>> On Wed, 3 Jan 2024 19:14:49 +0000
> >>>>> Dariusz Sosnowski <dsosnowski@nvidia.com> wrote:
> >>>>>> In summary, in my opinion extending the async flow API with
> >>>>>> bulking
> >>>>> capabilities or exposing the queue directly to the application is
> >>>>> not
> >> desirable.
> >>>>>> This proposal aims to reduce the I-cache overhead in async flow
> >>>>>> API by
> >>>>> reusing the existing design pattern in DPDK - fast path functions
> >>>>> are inlined to the application code and they call cached PMD callbacks.
> >>>>>
> >>>>> Inline needs to more discouraged in DPDK, because it only works if
> >>>>> application ends up building with DPDK from source.
> >>>>> It doesn't work for the Linux distro packaging model and symbol
> >>>>> versioning, etc.
> >>>>
> >>>> I understand the problem. In that case, I have a proposal.
> >>>> I had a chat with Thomas regarding this RFC, and he noticed that
> >>>> there are 2 separate changes proposed here:
> >>>>
> >>>> 1. Per-port callbacks for async flow API.
> >>>>     - Moves specified callbacks to rte_flow_fp_ops struct and allow
> >>>> PMDs to register them dynamically.
> >>>>     - Removes indirection at API level - no need to call rte_flow_ops_get().
> >>>>     - Removes checking if callbacks are defined - either the
> >>>> default DPDK callback is used or the one provided by PMD.
> >>>> 2. Make async flow API functions inlineable.
> >>>>
> >>>> Change (1) won't break ABI (existing callbacks in rte_flow_ops can
> >>>> be marked as deprecated for now and phased out later) and in my
> >>>> opinion is less controversial compared to change (2).
> >>>>
> >>>> I'll rerun the benchmarks for both changes separately to compare
> >>>> their benefits in isolation.
> >>>> This would allow us to decide if change (2) is worth the drawbacks
> >>>> it introduces.
> >>>>
> >>>> What do you think?
> >>>
> >>> I split the RFC into 2 parts:
> >>>
> >>> 1. Introduce per-port callbacks:
> >>>     - Introduce rte_flow_fp_ops struct - holds callbacks for fast
> >>> path calls, for
> >> each port. PMD registers callbacks through rte_flow_fp_ops_register().
> >>>     - Relevant rte_flow_async_* functions just pass arguments to
> >>> fast path
> >> callbacks. Validation checks are done only if RTE_FLOW_DEBUG macro is
> >> defined.
> >>>     - Biggest difference is the removal of callback access through
> >> rte_flow_get_ops().
> >>> 2. Inline async flow API functions.
> >>>     - Relevant rte_flow_async_* functions definitions are moved to
> >>> rte_flow.h
> >> and made inlineable.
> >>>
> >>> Here are the results of the benchmark:
> >>>
> >>> |                       | Avg Insertion | Diff over baseline | Avg
> >>> | Deletion | Diff over baseline |
> >>> |-----------------------|---------------|--------------------|--------------|----------
> ---
> >> -------|
> >>> | baseline (v24.03-rc0) |     5855.4    |                    |    9026.8    |                    |
> >>> | applied (1)           |     6384.2    |    +528.8 (+9%)    |    10054.2   |  +1027.4
> >> (+11.4%)  |
> >>> | applied (2)           |     6434.6    |   +579.2 (+9.9%)   |    10011.4   |   +984.6
> >> (+10.9%)  |
> >>>
> >>> Results are in KFlows/sec.
> >>> The benchmark is continuously inserting and deleting 2M flow rules.
> >>> These rules match on IPv4 destination address and with a single
> >>> action
> >> DROP.
> >>> Flow rules are inserted and deleted using a single flow queue.
> >>>
> >>> Change (2) improves insertion rate performance by ~1% compared to
> >>> (1),
> >> but decreases deletion rate by ~0.5%.
> >>> Based on these results, I think we can say that making
> >>> rte_flow_async_*()
> >> calls inlineable may not be worth it compared to the issues it causes.
> >>>
> >>> What do you all think about the results?
> >>>
> >>
> >> Hi Dariusz,
> >>
> >> As discussed before, converting APIs to static inline functions or
> >> exposing 'rte_eth_dev' has cons but with only applying first part
> >> above seems get rid of them with reasonable performance gain, so I
> >> think we can continue with this approach and continue to reviews.
> >>
> >> Most of the 'rte_flow_async_*' are already missing the function
> >> validity check, so having a default (dummy?) rte_flow_fp_ops for them
> >> seems even an improvement there.
> >>
> >>
> >> Only previously 'struct rte_flow_ops' was coming from drivers, ethdev
> >> layer doesn't need to maintain anything.
> >> But with 'rte_flow_fp_ops' struct, ethdev needs to store another
> >> array with fixed ('RTE_MAX_ETHPORTS') size which will be another
> >> blocker in the future to convert this fixed arrays to dynamically allocated
> arrays.
> >>
> >> For this, does it still help we add an a new field to "struct
> >> rte_eth_dev", like "struct rte_flow_ops *flow_ops", similar to 'dev_ops'?
> >> The indirection still will be there, but eliminate 'rte_flow_get_ops()'
> >> call and checks comes with it.
> >> If makes sense, is there a chance to experiment this and get some
> >> performance numbers with it?
> > Which option do you have in mind specifically?
> >
> > 1. Keeping only fast path callbacks in "dev->flow_ops", so "struct
> rte_eth_dev" will hold only a pointer to "struct rte_flow_fp_ops" as defined in
> RFC.
> >     - Only async flow API will use "dev->flow_ops->callback".
> >     - Other APIs will go through "rte_flow_ops_get()"
> > 2. Keeping all flow callbacks in "dev->flow_ops", so "struct rte_flow_ops".
> >     - As a result, I think that "rte_flow_get_ops()" could be removed
> altogether assuming that all functions have default implementation,
> >       checking for port validity (ENODEV if port not valid) and returning
> ENOSYS.
> >
> > Regardless of the version, I can experiment with additional indirection.
> >
> >
> 
> Both can work, has some cons,
> 
> I think "rte_flow_ops_get()" is more clear approach and rte_flow APIs already
> using it, so no change is required, but using separate struct for fast path will
> create two different structs drivers needs to fill, and both uses slightly different
> way to populate which is not nice.
> 
> For this RFC I think we can go with option 1, and consider updating rest if
> there is more motivation for it.

Ok, sounds good to me.

I redid the benchmark with "dev->flow_ops->callback()" method.
There's no statistically significant difference between this and static array of rte_flow_fp_ops, so I think we can go with option 1.
I'll send the patch for review as soon as possible.

Best regards,
Dariusz Sosnowski

^ permalink raw reply	[relevance 0%]

* Re: [RFC] ethdev: fast path async flow API
  2024-01-30 12:06  0%             ` Dariusz Sosnowski
@ 2024-01-30 12:17  0%               ` Ferruh Yigit
  2024-01-30 16:08  0%                 ` Dariusz Sosnowski
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2024-01-30 12:17 UTC (permalink / raw)
  To: Dariusz Sosnowski, Stephen Hemminger
  Cc: NBU-Contact-Thomas Monjalon (EXTERNAL), Andrew Rybchenko, Ori Kam, dev

On 1/30/2024 12:06 PM, Dariusz Sosnowski wrote:
> Hi Ferruh,
> 
>> -----Original Message-----
>> From: Ferruh Yigit <ferruh.yigit@amd.com>
>> Sent: Monday, January 29, 2024 18:36
>> To: Dariusz Sosnowski <dsosnowski@nvidia.com>; Stephen Hemminger
>> <stephen@networkplumber.org>
>> Cc: NBU-Contact-Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>;
>> Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>; Ori Kam
>> <orika@nvidia.com>; dev@dpdk.org
>> Subject: Re: [RFC] ethdev: fast path async flow API
>>
>> On 1/29/2024 1:38 PM, Dariusz Sosnowski wrote:
>>> Hi all,
>>>
>>>> -----Original Message-----
>>>> From: Dariusz Sosnowski <dsosnowski@nvidia.com>
>>>> Sent: Tuesday, January 23, 2024 12:37
>>>> To: Stephen Hemminger <stephen@networkplumber.org>
>>>> Cc: NBU-Contact-Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>;
>>>> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
>>>> <andrew.rybchenko@oktetlabs.ru>; Ori Kam <orika@nvidia.com>;
>>>> dev@dpdk.org
>>>> Subject: RE: [RFC] ethdev: fast path async flow API
>>>>
>>>> Hi Stephen,
>>>>
>>>> Sorry for such a late response.
>>>>
>>>> From: Stephen Hemminger <stephen@networkplumber.org>
>>>> Sent: Thursday, January 4, 2024 02:08
>>>>> On Wed, 3 Jan 2024 19:14:49 +0000
>>>>> Dariusz Sosnowski <dsosnowski@nvidia.com> wrote:
>>>>>> In summary, in my opinion extending the async flow API with bulking
>>>>> capabilities or exposing the queue directly to the application is not
>> desirable.
>>>>>> This proposal aims to reduce the I-cache overhead in async flow API
>>>>>> by
>>>>> reusing the existing design pattern in DPDK - fast path functions
>>>>> are inlined to the application code and they call cached PMD callbacks.
>>>>>
>>>>> Inline needs to more discouraged in DPDK, because it only works if
>>>>> application ends up building with DPDK from source.
>>>>> It doesn't work for the Linux distro packaging model and symbol
>>>>> versioning, etc.
>>>>
>>>> I understand the problem. In that case, I have a proposal.
>>>> I had a chat with Thomas regarding this RFC, and he noticed that
>>>> there are 2 separate changes proposed here:
>>>>
>>>> 1. Per-port callbacks for async flow API.
>>>>     - Moves specified callbacks to rte_flow_fp_ops struct and allow
>>>> PMDs to register them dynamically.
>>>>     - Removes indirection at API level - no need to call rte_flow_ops_get().
>>>>     - Removes checking if callbacks are defined - either the default
>>>> DPDK callback is used or the one provided by PMD.
>>>> 2. Make async flow API functions inlineable.
>>>>
>>>> Change (1) won't break ABI (existing callbacks in rte_flow_ops can be
>>>> marked as deprecated for now and phased out later) and in my opinion
>>>> is less controversial compared to change (2).
>>>>
>>>> I'll rerun the benchmarks for both changes separately to compare
>>>> their benefits in isolation.
>>>> This would allow us to decide if change (2) is worth the drawbacks it
>>>> introduces.
>>>>
>>>> What do you think?
>>>
>>> I split the RFC into 2 parts:
>>>
>>> 1. Introduce per-port callbacks:
>>>     - Introduce rte_flow_fp_ops struct - holds callbacks for fast path calls, for
>> each port. PMD registers callbacks through rte_flow_fp_ops_register().
>>>     - Relevant rte_flow_async_* functions just pass arguments to fast path
>> callbacks. Validation checks are done only if RTE_FLOW_DEBUG macro is
>> defined.
>>>     - Biggest difference is the removal of callback access through
>> rte_flow_get_ops().
>>> 2. Inline async flow API functions.
>>>     - Relevant rte_flow_async_* functions definitions are moved to rte_flow.h
>> and made inlineable.
>>>
>>> Here are the results of the benchmark:
>>>
>>> |                       | Avg Insertion | Diff over baseline | Avg
>>> | Deletion | Diff over baseline |
>>> |-----------------------|---------------|--------------------|--------------|-------------
>> -------|
>>> | baseline (v24.03-rc0) |     5855.4    |                    |    9026.8    |                    |
>>> | applied (1)           |     6384.2    |    +528.8 (+9%)    |    10054.2   |  +1027.4
>> (+11.4%)  |
>>> | applied (2)           |     6434.6    |   +579.2 (+9.9%)   |    10011.4   |   +984.6
>> (+10.9%)  |
>>>
>>> Results are in KFlows/sec.
>>> The benchmark is continuously inserting and deleting 2M flow rules.
>>> These rules match on IPv4 destination address and with a single action
>> DROP.
>>> Flow rules are inserted and deleted using a single flow queue.
>>>
>>> Change (2) improves insertion rate performance by ~1% compared to (1),
>> but decreases deletion rate by ~0.5%.
>>> Based on these results, I think we can say that making rte_flow_async_*()
>> calls inlineable may not be worth it compared to the issues it causes.
>>>
>>> What do you all think about the results?
>>>
>>
>> Hi Dariusz,
>>
>> As discussed before, converting APIs to static inline functions or exposing
>> 'rte_eth_dev' has cons but with only applying first part above seems get rid of
>> them with reasonable performance gain, so I think we can continue with this
>> approach and continue to reviews.
>>
>> Most of the 'rte_flow_async_*' are already missing the function validity check,
>> so having a default (dummy?) rte_flow_fp_ops for them seems even an
>> improvement there.
>>
>>
>> Only previously 'struct rte_flow_ops' was coming from drivers, ethdev layer
>> doesn't need to maintain anything.
>> But with 'rte_flow_fp_ops' struct, ethdev needs to store another array with
>> fixed ('RTE_MAX_ETHPORTS') size which will be another blocker in the future
>> to convert this fixed arrays to dynamically allocated arrays.
>>
>> For this, does it still help we add an a new field to "struct rte_eth_dev", like
>> "struct rte_flow_ops *flow_ops", similar to 'dev_ops'?
>> The indirection still will be there, but eliminate 'rte_flow_get_ops()'
>> call and checks comes with it.
>> If makes sense, is there a chance to experiment this and get some performance
>> numbers with it?
> Which option do you have in mind specifically?
> 
> 1. Keeping only fast path callbacks in "dev->flow_ops", so "struct rte_eth_dev" will hold only a pointer to "struct rte_flow_fp_ops" as defined in RFC.
>     - Only async flow API will use "dev->flow_ops->callback".
>     - Other APIs will go through "rte_flow_ops_get()"
> 2. Keeping all flow callbacks in "dev->flow_ops", so "struct rte_flow_ops".
>     - As a result, I think that "rte_flow_get_ops()" could be removed altogether assuming that all functions have default implementation,
>       checking for port validity (ENODEV if port not valid) and returning ENOSYS.
> 
> Regardless of the version, I can experiment with additional indirection.
> 
> 

Both can work, has some cons,

I think "rte_flow_ops_get()" is more clear approach and rte_flow APIs
already using it, so no change is required, but using separate struct
for fast path will create two different structs drivers needs to fill,
and both uses slightly different way to populate which is not nice.

For this RFC I think we can go with option 1, and consider updating rest
if there is more motivation for it.




^ permalink raw reply	[relevance 0%]

* RE: [RFC] ethdev: fast path async flow API
  2024-01-29 17:36  0%           ` Ferruh Yigit
@ 2024-01-30 12:06  0%             ` Dariusz Sosnowski
  2024-01-30 12:17  0%               ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Dariusz Sosnowski @ 2024-01-30 12:06 UTC (permalink / raw)
  To: Ferruh Yigit, Stephen Hemminger
  Cc: NBU-Contact-Thomas Monjalon (EXTERNAL), Andrew Rybchenko, Ori Kam, dev

Hi Ferruh,

> -----Original Message-----
> From: Ferruh Yigit <ferruh.yigit@amd.com>
> Sent: Monday, January 29, 2024 18:36
> To: Dariusz Sosnowski <dsosnowski@nvidia.com>; Stephen Hemminger
> <stephen@networkplumber.org>
> Cc: NBU-Contact-Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>;
> Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>; Ori Kam
> <orika@nvidia.com>; dev@dpdk.org
> Subject: Re: [RFC] ethdev: fast path async flow API
> 
> On 1/29/2024 1:38 PM, Dariusz Sosnowski wrote:
> > Hi all,
> >
> >> -----Original Message-----
> >> From: Dariusz Sosnowski <dsosnowski@nvidia.com>
> >> Sent: Tuesday, January 23, 2024 12:37
> >> To: Stephen Hemminger <stephen@networkplumber.org>
> >> Cc: NBU-Contact-Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>;
> >> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> >> <andrew.rybchenko@oktetlabs.ru>; Ori Kam <orika@nvidia.com>;
> >> dev@dpdk.org
> >> Subject: RE: [RFC] ethdev: fast path async flow API
> >>
> >> Hi Stephen,
> >>
> >> Sorry for such a late response.
> >>
> >> From: Stephen Hemminger <stephen@networkplumber.org>
> >> Sent: Thursday, January 4, 2024 02:08
> >>> On Wed, 3 Jan 2024 19:14:49 +0000
> >>> Dariusz Sosnowski <dsosnowski@nvidia.com> wrote:
> >>>> In summary, in my opinion extending the async flow API with bulking
> >>> capabilities or exposing the queue directly to the application is not
> desirable.
> >>>> This proposal aims to reduce the I-cache overhead in async flow API
> >>>> by
> >>> reusing the existing design pattern in DPDK - fast path functions
> >>> are inlined to the application code and they call cached PMD callbacks.
> >>>
> >>> Inline needs to more discouraged in DPDK, because it only works if
> >>> application ends up building with DPDK from source.
> >>> It doesn't work for the Linux distro packaging model and symbol
> >>> versioning, etc.
> >>
> >> I understand the problem. In that case, I have a proposal.
> >> I had a chat with Thomas regarding this RFC, and he noticed that
> >> there are 2 separate changes proposed here:
> >>
> >> 1. Per-port callbacks for async flow API.
> >>     - Moves specified callbacks to rte_flow_fp_ops struct and allow
> >> PMDs to register them dynamically.
> >>     - Removes indirection at API level - no need to call rte_flow_ops_get().
> >>     - Removes checking if callbacks are defined - either the default
> >> DPDK callback is used or the one provided by PMD.
> >> 2. Make async flow API functions inlineable.
> >>
> >> Change (1) won't break ABI (existing callbacks in rte_flow_ops can be
> >> marked as deprecated for now and phased out later) and in my opinion
> >> is less controversial compared to change (2).
> >>
> >> I'll rerun the benchmarks for both changes separately to compare
> >> their benefits in isolation.
> >> This would allow us to decide if change (2) is worth the drawbacks it
> >> introduces.
> >>
> >> What do you think?
> >
> > I split the RFC into 2 parts:
> >
> > 1. Introduce per-port callbacks:
> >     - Introduce rte_flow_fp_ops struct - holds callbacks for fast path calls, for
> each port. PMD registers callbacks through rte_flow_fp_ops_register().
> >     - Relevant rte_flow_async_* functions just pass arguments to fast path
> callbacks. Validation checks are done only if RTE_FLOW_DEBUG macro is
> defined.
> >     - Biggest difference is the removal of callback access through
> rte_flow_get_ops().
> > 2. Inline async flow API functions.
> >     - Relevant rte_flow_async_* functions definitions are moved to rte_flow.h
> and made inlineable.
> >
> > Here are the results of the benchmark:
> >
> > |                       | Avg Insertion | Diff over baseline | Avg
> > | Deletion | Diff over baseline |
> > |-----------------------|---------------|--------------------|--------------|-------------
> -------|
> > | baseline (v24.03-rc0) |     5855.4    |                    |    9026.8    |                    |
> > | applied (1)           |     6384.2    |    +528.8 (+9%)    |    10054.2   |  +1027.4
> (+11.4%)  |
> > | applied (2)           |     6434.6    |   +579.2 (+9.9%)   |    10011.4   |   +984.6
> (+10.9%)  |
> >
> > Results are in KFlows/sec.
> > The benchmark is continuously inserting and deleting 2M flow rules.
> > These rules match on IPv4 destination address and with a single action
> DROP.
> > Flow rules are inserted and deleted using a single flow queue.
> >
> > Change (2) improves insertion rate performance by ~1% compared to (1),
> but decreases deletion rate by ~0.5%.
> > Based on these results, I think we can say that making rte_flow_async_*()
> calls inlineable may not be worth it compared to the issues it causes.
> >
> > What do you all think about the results?
> >
> 
> Hi Dariusz,
> 
> As discussed before, converting APIs to static inline functions or exposing
> 'rte_eth_dev' has cons but with only applying first part above seems get rid of
> them with reasonable performance gain, so I think we can continue with this
> approach and continue to reviews.
> 
> Most of the 'rte_flow_async_*' are already missing the function validity check,
> so having a default (dummy?) rte_flow_fp_ops for them seems even an
> improvement there.
> 
> 
> Only previously 'struct rte_flow_ops' was coming from drivers, ethdev layer
> doesn't need to maintain anything.
> But with 'rte_flow_fp_ops' struct, ethdev needs to store another array with
> fixed ('RTE_MAX_ETHPORTS') size which will be another blocker in the future
> to convert this fixed arrays to dynamically allocated arrays.
> 
> For this, does it still help we add an a new field to "struct rte_eth_dev", like
> "struct rte_flow_ops *flow_ops", similar to 'dev_ops'?
> The indirection still will be there, but eliminate 'rte_flow_get_ops()'
> call and checks comes with it.
> If makes sense, is there a chance to experiment this and get some performance
> numbers with it?
Which option do you have in mind specifically?

1. Keeping only fast path callbacks in "dev->flow_ops", so "struct rte_eth_dev" will hold only a pointer to "struct rte_flow_fp_ops" as defined in RFC.
    - Only async flow API will use "dev->flow_ops->callback".
    - Other APIs will go through "rte_flow_ops_get()"
2. Keeping all flow callbacks in "dev->flow_ops", so "struct rte_flow_ops".
    - As a result, I think that "rte_flow_get_ops()" could be removed altogether assuming that all functions have default implementation,
      checking for port validity (ENODEV if port not valid) and returning ENOSYS.

Regardless of the version, I can experiment with additional indirection.

Best regards,
Dariusz Sosnowski

^ permalink raw reply	[relevance 0%]

* [RFC 2/2] tap: rework BPF handling
  @ 2024-01-30  3:46  1% ` Stephen Hemminger
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2024-01-30  3:46 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

There were multiple issues in the RSS queue support in the TAP
driver. This required extensive rework of the BPF support.

Key points:
    - works with current kernels requiring BTF support[1]
    - use libbpf for interactions with kernel
      (no longer need the python extraction code)
    - no longer needs to process packets twice;
      the BPF reclassifier step is not needed
    - does error checking on RSS flow parameters
    - supports setting RSS key per flow (never done in original code)
    - supports L3 only hash (original code was broken)
    - supports IPv4 options and IPv6 extension header
    - BPF program is only loaded once and not modified,
      tc classid is used to find configuration
    - remove unused code and fields
    - code rewritten and commented for clarity

[1] This is based of the BPF map work in earlier patch
    from Madhuker Mythri <madhuker.mythri@oracle.com>

Expect multiple checkpatch errors because it contains non RTE
code (the BPF program) and autogenerated code from bpftool.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 .gitignore                            |     3 -
 drivers/net/tap/bpf/.gitignore        |     2 +
 drivers/net/tap/bpf/Makefile          |    21 +-
 drivers/net/tap/bpf/README            |    12 +
 drivers/net/tap/bpf/bpf_api.h         |   276 -
 drivers/net/tap/bpf/bpf_elf.h         |    53 -
 drivers/net/tap/bpf/bpf_extract.py    |    85 -
 drivers/net/tap/bpf/tap_bpf_program.c |   255 -
 drivers/net/tap/bpf/tap_rss.c         |   269 +
 drivers/net/tap/meson.build           |    26 +-
 drivers/net/tap/rte_eth_tap.c         |     2 +
 drivers/net/tap/rte_eth_tap.h         |     9 +-
 drivers/net/tap/tap_bpf_api.c         |   196 -
 drivers/net/tap/tap_bpf_insns.h       |  1742 ----
 drivers/net/tap/tap_flow.c            |   443 +-
 drivers/net/tap/tap_flow.h            |    11 +-
 drivers/net/tap/tap_rss.h             |    14 +-
 drivers/net/tap/tap_rss.skel.h        | 11625 ++++++++++++++++++++++++
 drivers/net/tap/tap_rss.stub.h        |    45 +
 19 files changed, 12138 insertions(+), 2951 deletions(-)
 create mode 100644 drivers/net/tap/bpf/.gitignore
 create mode 100644 drivers/net/tap/bpf/README
 delete mode 100644 drivers/net/tap/bpf/bpf_api.h
 delete mode 100644 drivers/net/tap/bpf/bpf_elf.h
 delete mode 100644 drivers/net/tap/bpf/bpf_extract.py
 delete mode 100644 drivers/net/tap/bpf/tap_bpf_program.c
 create mode 100644 drivers/net/tap/bpf/tap_rss.c
 delete mode 100644 drivers/net/tap/tap_bpf_api.c
 delete mode 100644 drivers/net/tap/tap_bpf_insns.h
 create mode 100644 drivers/net/tap/tap_rss.skel.h
 create mode 100644 drivers/net/tap/tap_rss.stub.h

diff --git a/.gitignore b/.gitignore
index 3f444dcace2e..01a47a760660 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,9 +36,6 @@ TAGS
 # ignore python bytecode files
 *.pyc
 
-# ignore BPF programs
-drivers/net/tap/bpf/tap_bpf_program.o
-
 # DTS results
 dts/output
 
diff --git a/drivers/net/tap/bpf/.gitignore b/drivers/net/tap/bpf/.gitignore
new file mode 100644
index 000000000000..8ae453adf290
--- /dev/null
+++ b/drivers/net/tap/bpf/.gitignore
@@ -0,0 +1,2 @@
+# ignore the BPF object file
+tap_rss.o
diff --git a/drivers/net/tap/bpf/Makefile b/drivers/net/tap/bpf/Makefile
index 9efeeb1bc704..c963a088e58e 100644
--- a/drivers/net/tap/bpf/Makefile
+++ b/drivers/net/tap/bpf/Makefile
@@ -2,18 +2,21 @@
 # This file is not built as part of normal DPDK build.
 # It is used to generate the eBPF code for TAP RSS.
 
-CLANG=clang
-CLANG_OPTS=-O2
-TARGET=../tap_bpf_insns.h
+CLANG = clang
+BPFTOOL = /usr/sbin/bpftool
+CLANG_OPTS = -O2 -Wall -Wextra
+TARGET = ../tap_rss.skel.h
+
+CLANG_BPF_SYS_INCLUDES ?= $(shell $(CLANG) -v -E - </dev/null 2>&1 \
+	| sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }')
 
 all: $(TARGET)
 
 clean:
-	rm tap_bpf_program.o $(TARGET)
+	rm tap_rss.o $(TARGET)
 
-tap_bpf_program.o: tap_bpf_program.c
-	$(CLANG) $(CLANG_OPTS) -emit-llvm -c $< -o - | \
-	llc -march=bpf -filetype=obj -o $@
+$(TARGET): tap_rss.o
+	$(BPFTOOL) gen skeleton $< > $@
 
-$(TARGET): tap_bpf_program.o
-	python3 bpf_extract.py -stap_bpf_program.c -o $@ $<
+tap_rss.o: tap_rss.c
+	$(CLANG) $(CLANG_OPTS) $(CLANG_BPF_SYS_INCLUDES) -target bpf -c $< -g -o $@
diff --git a/drivers/net/tap/bpf/README b/drivers/net/tap/bpf/README
new file mode 100644
index 000000000000..960a10da73b8
--- /dev/null
+++ b/drivers/net/tap/bpf/README
@@ -0,0 +1,12 @@
+This is the BPF program used to implement the RSS across queues
+flow action. It works like the skbedit tc filter but instead of mapping
+to only one queues, it maps to multiple queues based on RSS hash.
+
+This version is built the BPF Compile Once — Run Everywhere (CO-RE)
+framework and uses libbpf and bpftool.
+
+Limitations
+- requires libbpf version XX or later
+- rebuilding the BPF requires clang and bpftool
+- only Toeplitz hash with standard 40 byte key is supported
+- the number of queues per RSS action is limited to 16
diff --git a/drivers/net/tap/bpf/bpf_api.h b/drivers/net/tap/bpf/bpf_api.h
deleted file mode 100644
index 2638a8a4ac9a..000000000000
--- a/drivers/net/tap/bpf/bpf_api.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-
-#ifndef __BPF_API__
-#define __BPF_API__
-
-/* Note:
- *
- * This file can be included into eBPF kernel programs. It contains
- * a couple of useful helper functions, map/section ABI (bpf_elf.h),
- * misc macros and some eBPF specific LLVM built-ins.
- */
-
-#include <stdint.h>
-
-#include <linux/pkt_cls.h>
-#include <linux/bpf.h>
-#include <linux/filter.h>
-
-#include <asm/byteorder.h>
-
-#include "bpf_elf.h"
-
-/** libbpf pin type. */
-enum libbpf_pin_type {
-	LIBBPF_PIN_NONE,
-	/* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */
-	LIBBPF_PIN_BY_NAME,
-};
-
-/** Type helper macros. */
-
-#define __uint(name, val) int (*name)[val]
-#define __type(name, val) typeof(val) *name
-#define __array(name, val) typeof(val) *name[]
-
-/** Misc macros. */
-
-#ifndef __stringify
-# define __stringify(X)		#X
-#endif
-
-#ifndef __maybe_unused
-# define __maybe_unused		__attribute__((__unused__))
-#endif
-
-#ifndef offsetof
-# define offsetof(TYPE, MEMBER)	__builtin_offsetof(TYPE, MEMBER)
-#endif
-
-#ifndef likely
-# define likely(X)		__builtin_expect(!!(X), 1)
-#endif
-
-#ifndef unlikely
-# define unlikely(X)		__builtin_expect(!!(X), 0)
-#endif
-
-#ifndef htons
-# define htons(X)		__constant_htons((X))
-#endif
-
-#ifndef ntohs
-# define ntohs(X)		__constant_ntohs((X))
-#endif
-
-#ifndef htonl
-# define htonl(X)		__constant_htonl((X))
-#endif
-
-#ifndef ntohl
-# define ntohl(X)		__constant_ntohl((X))
-#endif
-
-#ifndef __inline__
-# define __inline__		__attribute__((always_inline))
-#endif
-
-/** Section helper macros. */
-
-#ifndef __section
-# define __section(NAME)						\
-	__attribute__((section(NAME), used))
-#endif
-
-#ifndef __section_tail
-# define __section_tail(ID, KEY)					\
-	__section(__stringify(ID) "/" __stringify(KEY))
-#endif
-
-#ifndef __section_xdp_entry
-# define __section_xdp_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_cls_entry
-# define __section_cls_entry						\
-	__section(ELF_SECTION_CLASSIFIER)
-#endif
-
-#ifndef __section_act_entry
-# define __section_act_entry						\
-	__section(ELF_SECTION_ACTION)
-#endif
-
-#ifndef __section_lwt_entry
-# define __section_lwt_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_license
-# define __section_license						\
-	__section(ELF_SECTION_LICENSE)
-#endif
-
-#ifndef __section_maps
-# define __section_maps							\
-	__section(ELF_SECTION_MAPS)
-#endif
-
-/** Declaration helper macros. */
-
-#ifndef BPF_LICENSE
-# define BPF_LICENSE(NAME)						\
-	char ____license[] __section_license = NAME
-#endif
-
-/** Classifier helper */
-
-#ifndef BPF_H_DEFAULT
-# define BPF_H_DEFAULT	-1
-#endif
-
-/** BPF helper functions for tc. Individual flags are in linux/bpf.h */
-
-#ifndef __BPF_FUNC
-# define __BPF_FUNC(NAME, ...)						\
-	(* NAME)(__VA_ARGS__) __maybe_unused
-#endif
-
-#ifndef BPF_FUNC
-# define BPF_FUNC(NAME, ...)						\
-	__BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME
-#endif
-
-/* Map access/manipulation */
-static void *BPF_FUNC(map_lookup_elem, void *map, const void *key);
-static int BPF_FUNC(map_update_elem, void *map, const void *key,
-		    const void *value, uint32_t flags);
-static int BPF_FUNC(map_delete_elem, void *map, const void *key);
-
-/* Time access */
-static uint64_t BPF_FUNC(ktime_get_ns);
-
-/* Debugging */
-
-/* FIXME: __attribute__ ((format(printf, 1, 3))) not possible unless
- * llvm bug https://llvm.org/bugs/show_bug.cgi?id=26243 gets resolved.
- * It would require ____fmt to be made const, which generates a reloc
- * entry (non-map).
- */
-static void BPF_FUNC(trace_printk, const char *fmt, int fmt_size, ...);
-
-#ifndef printt
-# define printt(fmt, ...)						\
-	({								\
-		char ____fmt[] = fmt;					\
-		trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__);	\
-	})
-#endif
-
-/* Random numbers */
-static uint32_t BPF_FUNC(get_prandom_u32);
-
-/* Tail calls */
-static void BPF_FUNC(tail_call, struct __sk_buff *skb, void *map,
-		     uint32_t index);
-
-/* System helpers */
-static uint32_t BPF_FUNC(get_smp_processor_id);
-static uint32_t BPF_FUNC(get_numa_node_id);
-
-/* Packet misc meta data */
-static uint32_t BPF_FUNC(get_cgroup_classid, struct __sk_buff *skb);
-static int BPF_FUNC(skb_under_cgroup, void *map, uint32_t index);
-
-static uint32_t BPF_FUNC(get_route_realm, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(get_hash_recalc, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(set_hash_invalid, struct __sk_buff *skb);
-
-/* Packet redirection */
-static int BPF_FUNC(redirect, int ifindex, uint32_t flags);
-static int BPF_FUNC(clone_redirect, struct __sk_buff *skb, int ifindex,
-		    uint32_t flags);
-
-/* Packet manipulation */
-static int BPF_FUNC(skb_load_bytes, struct __sk_buff *skb, uint32_t off,
-		    void *to, uint32_t len);
-static int BPF_FUNC(skb_store_bytes, struct __sk_buff *skb, uint32_t off,
-		    const void *from, uint32_t len, uint32_t flags);
-
-static int BPF_FUNC(l3_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(l4_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(csum_diff, const void *from, uint32_t from_size,
-		    const void *to, uint32_t to_size, uint32_t seed);
-static int BPF_FUNC(csum_update, struct __sk_buff *skb, uint32_t wsum);
-
-static int BPF_FUNC(skb_change_type, struct __sk_buff *skb, uint32_t type);
-static int BPF_FUNC(skb_change_proto, struct __sk_buff *skb, uint32_t proto,
-		    uint32_t flags);
-static int BPF_FUNC(skb_change_tail, struct __sk_buff *skb, uint32_t nlen,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_pull_data, struct __sk_buff *skb, uint32_t len);
-
-/* Event notification */
-static int __BPF_FUNC(skb_event_output, struct __sk_buff *skb, void *map,
-		      uint64_t index, const void *data, uint32_t size) =
-		      (void *) BPF_FUNC_perf_event_output;
-
-/* Packet vlan encap/decap */
-static int BPF_FUNC(skb_vlan_push, struct __sk_buff *skb, uint16_t proto,
-		    uint16_t vlan_tci);
-static int BPF_FUNC(skb_vlan_pop, struct __sk_buff *skb);
-
-/* Packet tunnel encap/decap */
-static int BPF_FUNC(skb_get_tunnel_key, struct __sk_buff *skb,
-		    struct bpf_tunnel_key *to, uint32_t size, uint32_t flags);
-static int BPF_FUNC(skb_set_tunnel_key, struct __sk_buff *skb,
-		    const struct bpf_tunnel_key *from, uint32_t size,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_get_tunnel_opt, struct __sk_buff *skb,
-		    void *to, uint32_t size);
-static int BPF_FUNC(skb_set_tunnel_opt, struct __sk_buff *skb,
-		    const void *from, uint32_t size);
-
-/** LLVM built-ins, mem*() routines work for constant size */
-
-#ifndef lock_xadd
-# define lock_xadd(ptr, val)	((void) __sync_fetch_and_add(ptr, val))
-#endif
-
-#ifndef memset
-# define memset(s, c, n)	__builtin_memset((s), (c), (n))
-#endif
-
-#ifndef memcpy
-# define memcpy(d, s, n)	__builtin_memcpy((d), (s), (n))
-#endif
-
-#ifndef memmove
-# define memmove(d, s, n)	__builtin_memmove((d), (s), (n))
-#endif
-
-/* FIXME: __builtin_memcmp() is not yet fully usable unless llvm bug
- * https://llvm.org/bugs/show_bug.cgi?id=26218 gets resolved. Also
- * this one would generate a reloc entry (non-map), otherwise.
- */
-#if 0
-#ifndef memcmp
-# define memcmp(a, b, n)	__builtin_memcmp((a), (b), (n))
-#endif
-#endif
-
-unsigned long long load_byte(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.byte");
-
-unsigned long long load_half(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.half");
-
-unsigned long long load_word(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.word");
-
-#endif /* __BPF_API__ */
diff --git a/drivers/net/tap/bpf/bpf_elf.h b/drivers/net/tap/bpf/bpf_elf.h
deleted file mode 100644
index ea8a11c95c0f..000000000000
--- a/drivers/net/tap/bpf/bpf_elf.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-#ifndef __BPF_ELF__
-#define __BPF_ELF__
-
-#include <asm/types.h>
-
-/* Note:
- *
- * Below ELF section names and bpf_elf_map structure definition
- * are not (!) kernel ABI. It's rather a "contract" between the
- * application and the BPF loader in tc. For compatibility, the
- * section names should stay as-is. Introduction of aliases, if
- * needed, are a possibility, though.
- */
-
-/* ELF section names, etc */
-#define ELF_SECTION_LICENSE	"license"
-#define ELF_SECTION_MAPS	"maps"
-#define ELF_SECTION_PROG	"prog"
-#define ELF_SECTION_CLASSIFIER	"classifier"
-#define ELF_SECTION_ACTION	"action"
-
-#define ELF_MAX_MAPS		64
-#define ELF_MAX_LICENSE_LEN	128
-
-/* Object pinning settings */
-#define PIN_NONE		0
-#define PIN_OBJECT_NS		1
-#define PIN_GLOBAL_NS		2
-
-/* ELF map definition */
-struct bpf_elf_map {
-	__u32 type;
-	__u32 size_key;
-	__u32 size_value;
-	__u32 max_elem;
-	__u32 flags;
-	__u32 id;
-	__u32 pinning;
-	__u32 inner_id;
-	__u32 inner_idx;
-};
-
-#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val)		\
-	struct ____btf_map_##name {				\
-		type_key key;					\
-		type_val value;					\
-	};							\
-	struct ____btf_map_##name				\
-	    __attribute__ ((section(".maps." #name), used))	\
-	    ____btf_map_##name = { }
-
-#endif /* __BPF_ELF__ */
diff --git a/drivers/net/tap/bpf/bpf_extract.py b/drivers/net/tap/bpf/bpf_extract.py
deleted file mode 100644
index 73c4dafe4eca..000000000000
--- a/drivers/net/tap/bpf/bpf_extract.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright (c) 2023 Stephen Hemminger <stephen@networkplumber.org>
-
-import argparse
-import sys
-import struct
-from tempfile import TemporaryFile
-from elftools.elf.elffile import ELFFile
-
-
-def load_sections(elffile):
-    """Get sections of interest from ELF"""
-    result = []
-    parts = [("cls_q", "cls_q_insns"), ("l3_l4", "l3_l4_hash_insns")]
-    for name, tag in parts:
-        section = elffile.get_section_by_name(name)
-        if section:
-            insns = struct.iter_unpack('<BBhL', section.data())
-            result.append([tag, insns])
-    return result
-
-
-def dump_section(name, insns, out):
-    """Dump the array of BPF instructions"""
-    print(f'\nstatic struct bpf_insn {name}[] = {{', file=out)
-    for bpf in insns:
-        code = bpf[0]
-        src = bpf[1] >> 4
-        dst = bpf[1] & 0xf
-        off = bpf[2]
-        imm = bpf[3]
-        print(f'\t{{{code:#04x}, {dst:4d}, {src:4d}, {off:8d}, {imm:#010x}}},',
-              file=out)
-    print('};', file=out)
-
-
-def parse_args():
-    """Parse command line arguments"""
-    parser = argparse.ArgumentParser()
-    parser.add_argument('-s',
-                        '--source',
-                        type=str,
-                        help="original source file")
-    parser.add_argument('-o', '--out', type=str, help="output C file path")
-    parser.add_argument("file",
-                        nargs='+',
-                        help="object file path or '-' for stdin")
-    return parser.parse_args()
-
-
-def open_input(path):
-    """Open the file or stdin"""
-    if path == "-":
-        temp = TemporaryFile()
-        temp.write(sys.stdin.buffer.read())
-        return temp
-    return open(path, 'rb')
-
-
-def write_header(out, source):
-    """Write file intro header"""
-    print("/* SPDX-License-Identifier: BSD-3-Clause", file=out)
-    if source:
-        print(f' * Auto-generated from {source}', file=out)
-    print(" * This not the original source file. Do NOT edit it.", file=out)
-    print(" */\n", file=out)
-
-
-def main():
-    '''program main function'''
-    args = parse_args()
-
-    with open(args.out, 'w',
-              encoding="utf-8") if args.out else sys.stdout as out:
-        write_header(out, args.source)
-        for path in args.file:
-            elffile = ELFFile(open_input(path))
-            sections = load_sections(elffile)
-            for name, insns in sections:
-                dump_section(name, insns, out)
-
-
-if __name__ == "__main__":
-    main()
diff --git a/drivers/net/tap/bpf/tap_bpf_program.c b/drivers/net/tap/bpf/tap_bpf_program.c
deleted file mode 100644
index f05aed021c30..000000000000
--- a/drivers/net/tap/bpf/tap_bpf_program.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
- * Copyright 2017 Mellanox Technologies, Ltd
- */
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <asm/types.h>
-#include <linux/in.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/if_tunnel.h>
-#include <linux/filter.h>
-
-#include "bpf_api.h"
-#include "bpf_elf.h"
-#include "../tap_rss.h"
-
-/** Create IPv4 address */
-#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
-		(((b) & 0xff) << 16) | \
-		(((c) & 0xff) << 8)  | \
-		((d) & 0xff))
-
-#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
-		((b) & 0xff))
-
-/*
- * The queue number is offset by a unique QUEUE_OFFSET, to distinguish
- * packets that have gone through this rule (skb->cb[1] != 0) from others.
- */
-#define QUEUE_OFFSET		0x7cafe800
-#define PIN_GLOBAL_NS		2
-
-#define KEY_IDX			0
-#define BPF_MAP_ID_KEY	1
-
-struct vlan_hdr {
-	__be16 proto;
-	__be16 tci;
-};
-
-struct bpf_elf_map __attribute__((section("maps"), used))
-map_keys = {
-	.type           =       BPF_MAP_TYPE_HASH,
-	.id             =       BPF_MAP_ID_KEY,
-	.size_key       =       sizeof(__u32),
-	.size_value     =       sizeof(struct rss_key),
-	.max_elem       =       256,
-	.pinning        =       PIN_GLOBAL_NS,
-};
-
-__section("cls_q") int
-match_q(struct __sk_buff *skb)
-{
-	__u32 queue = skb->cb[1];
-	/* queue is set by tap_flow_bpf_cls_q() before load */
-	volatile __u32 q = 0xdeadbeef;
-	__u32 match_queue = QUEUE_OFFSET + q;
-
-	/* printt("match_q$i() queue = %d\n", queue); */
-
-	if (queue != match_queue)
-		return TC_ACT_OK;
-
-	/* queue match */
-	skb->cb[1] = 0;
-	return TC_ACT_UNSPEC;
-}
-
-
-struct ipv4_l3_l4_tuple {
-	__u32    src_addr;
-	__u32    dst_addr;
-	__u16    dport;
-	__u16    sport;
-} __attribute__((packed));
-
-struct ipv6_l3_l4_tuple {
-	__u8        src_addr[16];
-	__u8        dst_addr[16];
-	__u16       dport;
-	__u16       sport;
-} __attribute__((packed));
-
-static const __u8 def_rss_key[TAP_RSS_HASH_KEY_SIZE] = {
-	0xd1, 0x81, 0xc6, 0x2c,
-	0xf7, 0xf4, 0xdb, 0x5b,
-	0x19, 0x83, 0xa2, 0xfc,
-	0x94, 0x3e, 0x1a, 0xdb,
-	0xd9, 0x38, 0x9e, 0x6b,
-	0xd1, 0x03, 0x9c, 0x2c,
-	0xa7, 0x44, 0x99, 0xad,
-	0x59, 0x3d, 0x56, 0xd9,
-	0xf3, 0x25, 0x3c, 0x06,
-	0x2a, 0xdc, 0x1f, 0xfc,
-};
-
-static __u32  __attribute__((always_inline))
-rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
-		__u8 input_len)
-{
-	__u32 i, j, hash = 0;
-#pragma unroll
-	for (j = 0; j < input_len; j++) {
-#pragma unroll
-		for (i = 0; i < 32; i++) {
-			if (input_tuple[j] & (1U << (31 - i))) {
-				hash ^= ((const __u32 *)def_rss_key)[j] << i |
-				(__u32)((uint64_t)
-				(((const __u32 *)def_rss_key)[j + 1])
-					>> (32 - i));
-			}
-		}
-	}
-	return hash;
-}
-
-static int __attribute__((always_inline))
-rss_l3_l4(struct __sk_buff *skb)
-{
-	void *data_end = (void *)(long)skb->data_end;
-	void *data = (void *)(long)skb->data;
-	__u16 proto = (__u16)skb->protocol;
-	__u32 key_idx = 0xdeadbeef;
-	__u32 hash;
-	struct rss_key *rsskey;
-	__u64 off = ETH_HLEN;
-	int j;
-	__u8 *key = 0;
-	__u32 len;
-	__u32 queue = 0;
-	bool mf = 0;
-	__u16 frag_off = 0;
-
-	rsskey = map_lookup_elem(&map_keys, &key_idx);
-	if (!rsskey) {
-		printt("hash(): rss key is not configured\n");
-		return TC_ACT_OK;
-	}
-	key = (__u8 *)rsskey->key;
-
-	/* Get correct proto for 802.1ad */
-	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
-		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
-		    sizeof(proto) > data_end)
-			return TC_ACT_OK;
-		proto = *(__u16 *)(data + ETH_ALEN * 2 +
-				   sizeof(struct vlan_hdr));
-		off += sizeof(struct vlan_hdr);
-	}
-
-	if (proto == htons(ETH_P_IP)) {
-		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
-			> data_end)
-			return TC_ACT_OK;
-
-		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
-		__u8 *frag_off_addr = data + off + offsetof(struct iphdr, frag_off);
-		__u8 *prot_addr = data + off + offsetof(struct iphdr, protocol);
-		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
-		struct ipv4_l3_l4_tuple v4_tuple = {
-			.src_addr = IPv4(*(src_dst_addr + 0),
-					*(src_dst_addr + 1),
-					*(src_dst_addr + 2),
-					*(src_dst_addr + 3)),
-			.dst_addr = IPv4(*(src_dst_addr + 4),
-					*(src_dst_addr + 5),
-					*(src_dst_addr + 6),
-					*(src_dst_addr + 7)),
-			.sport = 0,
-			.dport = 0,
-		};
-		/** Fetch the L4-payer port numbers only in-case of TCP/UDP
-		 ** and also if the packet is not fragmented. Since fragmented
-		 ** chunks do not have L4 TCP/UDP header.
-		 **/
-		if (*prot_addr == IPPROTO_UDP || *prot_addr == IPPROTO_TCP) {
-			frag_off = PORT(*(frag_off_addr + 0),
-					*(frag_off_addr + 1));
-			mf = frag_off & 0x2000;
-			frag_off = frag_off & 0x1fff;
-			if (mf == 0 && frag_off == 0) {
-				v4_tuple.sport = PORT(*(src_dst_port + 0),
-						*(src_dst_port + 1));
-				v4_tuple.dport = PORT(*(src_dst_port + 2),
-						*(src_dst_port + 3));
-			}
-		}
-		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
-	} else if (proto == htons(ETH_P_IPV6)) {
-		if (data + off + sizeof(struct ipv6hdr) +
-					sizeof(__u32) > data_end)
-			return TC_ACT_OK;
-		__u8 *src_dst_addr = data + off +
-					offsetof(struct ipv6hdr, saddr);
-		__u8 *src_dst_port = data + off +
-					sizeof(struct ipv6hdr);
-		__u8 *next_hdr = data + off +
-					offsetof(struct ipv6hdr, nexthdr);
-
-		struct ipv6_l3_l4_tuple v6_tuple;
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.src_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + j));
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.dst_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + 4 + j));
-
-		/** Fetch the L4 header port-numbers only if next-header
-		 * is TCP/UDP **/
-		if (*next_hdr == IPPROTO_UDP || *next_hdr == IPPROTO_TCP) {
-			v6_tuple.sport = PORT(*(src_dst_port + 0),
-				      *(src_dst_port + 1));
-			v6_tuple.dport = PORT(*(src_dst_port + 2),
-				      *(src_dst_port + 3));
-		} else {
-			v6_tuple.sport = 0;
-			v6_tuple.dport = 0;
-		}
-
-		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
-	} else {
-		return TC_ACT_PIPE;
-	}
-
-	queue = rsskey->queues[(hash % rsskey->nb_queues) &
-				       (TAP_MAX_QUEUES - 1)];
-	skb->cb[1] = QUEUE_OFFSET + queue;
-	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
-
-	return TC_ACT_RECLASSIFY;
-}
-
-#define RSS(L)						\
-	__section(#L) int				\
-		L ## _hash(struct __sk_buff *skb)	\
-	{						\
-		return rss_ ## L (skb);			\
-	}
-
-RSS(l3_l4)
-
-BPF_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/tap/bpf/tap_rss.c b/drivers/net/tap/bpf/tap_rss.c
new file mode 100644
index 000000000000..43bd6cca673e
--- /dev/null
+++ b/drivers/net/tap/bpf/tap_rss.c
@@ -0,0 +1,269 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+ * Copyright 2017 Mellanox Technologies, Ltd
+ */
+
+#include <stdbool.h>
+
+#include <linux/in.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/pkt_cls.h>
+#include <linux/bpf.h>
+
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+
+#include "../tap_rss.h"
+
+/*
+ * This map provides configuration information about flows
+ * which need BPF RSS.
+ *
+ * The hash is indexed by the tc_index.
+ */
+struct {
+	__uint(type, BPF_MAP_TYPE_HASH);
+	__uint(key_size, sizeof(__u16));
+	__uint(value_size, sizeof(struct rss_key));
+	__uint(max_entries, TAP_RSS_MAX);
+} rss_map SEC(".maps");
+
+/*
+ * Compute Toeplitz hash over the input tuple.
+ * This is same as rte_softrss_be in lib/hash
+ * but loop needs to be setup to match BPF restrictions.
+ */
+static __u32 __attribute__((always_inline))
+softrss_be(const __u32 *input_tuple, __u32 input_len, const __u32 *key)
+{
+	__u32 i, j, hash = 0;
+
+#pragma unroll
+	for (j = 0; j < input_len; j++) {
+#pragma unroll
+		for (i = 0; i < 32; i++) {
+			if (input_tuple[j] & (1U << (31 - i)))
+				hash ^= key[j] << i | key[j + 1] >> (32 - i);
+		}
+	}
+	return hash;
+}
+
+#define IP_MF		0x2000		/** IP header Flags **/
+#define IP_OFFSET	0x1FFF		/** IP header fragment offset **/
+
+static bool __attribute__((always_inline))
+is_ipv4_fragment(const struct iphdr *iph)
+{
+	return (iph->frag_off & bpf_htons(IP_MF | IP_OFFSET)) != 0;
+}
+
+/* Compute RSS hash for IPv4 packet.
+ * return in 0 if RSS not specified
+ */
+static __u32 __attribute__((always_inline))
+parse_ipv4(const struct __sk_buff *skb, __u32 hash_type, const __u32 *key)
+{
+	struct iphdr iph;
+	__u32 off = 0;
+
+	if (bpf_skb_load_bytes_relative(skb, off, &iph, sizeof(iph), BPF_HDR_START_NET))
+		return 0;	/* no IP header present */
+
+	struct {
+		__u32    src_addr;
+		__u32    dst_addr;
+		__u16    dport;
+		__u16    sport;
+	} v4_tuple = {
+		.src_addr = bpf_ntohl(iph.saddr),
+		.dst_addr = bpf_ntohl(iph.daddr),
+	};
+
+	/* If only calculating L3 hash, do it now */
+	if (hash_type & (1 << HASH_FIELD_IPV4_L3))
+		return softrss_be((__u32 *)&v4_tuple, sizeof(v4_tuple) / sizeof(__u32) - 1, key);
+
+	/* Get ports for non-fragmented TCP/UDP */
+	if (is_ipv4_fragment(&iph) ||
+	    !(iph.protocol == IPPROTO_UDP || iph.protocol == IPPROTO_TCP)) {
+		return 0;
+	} else {
+		__u16 src_dst_port[2];
+
+		off += iph.ihl * 4;
+		if (bpf_skb_load_bytes_relative(skb, off,
+						&src_dst_port, sizeof(src_dst_port), BPF_HDR_START_NET))
+			return 0; /* TCP or UDP header missing */
+
+		v4_tuple.sport = bpf_ntohs(src_dst_port[0]);
+		v4_tuple.dport = bpf_ntohs(src_dst_port[1]);
+		return softrss_be((__u32 *)&v4_tuple, sizeof(v4_tuple) / sizeof(__u32), key);
+	}
+}
+
+/* parse ipv6 extended headers, update offset and return next proto.
+ * returns next proto on success, -1 on malformed header
+ */
+static int __attribute__((always_inline))
+skip_ip6_ext(__u16 proto, const struct __sk_buff *skb, __u32 *off, int *frag)
+{
+	struct ext_hdr {
+		__u8 next_hdr;
+		__u8 len;
+	} xh;
+	unsigned int i;
+
+	*frag = 0;
+
+#define MAX_EXT_HDRS 5
+#pragma unroll
+	for (i = 0; i < MAX_EXT_HDRS; i++) {
+		switch (proto) {
+		case IPPROTO_HOPOPTS:
+		case IPPROTO_ROUTING:
+		case IPPROTO_DSTOPTS:
+			if (bpf_skb_load_bytes_relative(skb, *off, &xh, sizeof(xh), BPF_HDR_START_NET))
+				return -1;
+
+			*off += (xh.len + 1) * 8;
+			proto = xh.next_hdr;
+			break;
+		case IPPROTO_FRAGMENT:
+			if (bpf_skb_load_bytes_relative(skb, *off, &xh, sizeof(xh), BPF_HDR_START_NET))
+				return -1;
+
+			*off += 8;
+			proto = xh.next_hdr;
+			*frag = 1;
+			return proto; /* this is always the last ext hdr */
+		default:
+			return proto;
+		}
+	}
+
+	/* too many extension headers give up */
+	return -1;
+}
+
+static __u32 __attribute__((always_inline))
+parse_ipv6(const struct __sk_buff *skb, __u32 hash_type, const __u32 *key)
+{
+	struct {
+		__u32       src_addr[4];
+		__u32       dst_addr[4];
+		__u16       dport;
+		__u16       sport;
+	} v6_tuple = { };
+	struct ipv6hdr ip6h;
+	__u32 off = 0, j;
+	int proto, frag;
+
+	if (bpf_skb_load_bytes_relative(skb, off, &ip6h, sizeof(ip6h), BPF_HDR_START_NET))
+		return 0;
+
+#pragma unroll
+	for (j = 0; j < 4; j++) {
+		v6_tuple.src_addr[j] = bpf_ntohl(ip6h.saddr.in6_u.u6_addr32[j]);
+		v6_tuple.dst_addr[j] = bpf_ntohl(ip6h.daddr.in6_u.u6_addr32[j]);
+	}
+
+	if (hash_type & (1 << HASH_FIELD_IPV6_L3))
+		return softrss_be((__u32 *)&v6_tuple, sizeof(v6_tuple) / sizeof(__u32) - 1, key);
+
+	off += sizeof(ip6h);
+	proto = skip_ip6_ext(ip6h.nexthdr, skb, &off, &frag);
+	if (proto < 0)
+		return 0;
+
+	if (frag || !(proto == IPPROTO_UDP || proto == IPPROTO_TCP)) {
+		return 0;
+	} else {
+		__u16 src_dst_port[2];
+
+		if (bpf_skb_load_bytes_relative(skb, off, &src_dst_port, sizeof(src_dst_port),
+						BPF_HDR_START_NET))
+			return 0;
+
+		v6_tuple.sport = bpf_ntohs(src_dst_port[0]);
+		v6_tuple.dport = bpf_ntohs(src_dst_port[1]);
+	}
+
+	return softrss_be((__u32 *)&v6_tuple, sizeof(v6_tuple) / sizeof(__u32), key);
+}
+
+/*
+ * Compute RSS hash for packets.
+ * Returns 0 if no hash is possible.
+ */
+static __u32 __attribute__((always_inline))
+calculate_rss_hash(const struct __sk_buff *skb, const struct rss_key *rsskey)
+{
+	const __u32 *key = (const __u32 *)rsskey->key;
+
+	if (skb->protocol == bpf_htons(ETH_P_IP))
+		return parse_ipv4(skb, rsskey->hash_fields, key);
+	else if (skb->protocol == bpf_htons(ETH_P_IPV6))
+		return parse_ipv6(skb, rsskey->hash_fields, key);
+	else
+		return 0;
+}
+
+/* scale value to be into range [0, n), assumes val is large */
+static __u32  __attribute__((always_inline))
+reciprocal_scale(__u32 val, __u32 n)
+{
+	return (__u32)(((__u64)val * n) >> 32);
+}
+
+/* layout of qdisc skb cb (from sch_generic.h) */
+struct qdisc_skb_cb {
+	struct {
+		unsigned int	pkt_len;
+		__u16		slave_dev_queue_mapping;
+		__u16		tc_classid;
+	};
+#define QDISC_CB_PRIV_LEN 20
+	unsigned char		data[QDISC_CB_PRIV_LEN];
+};
+
+/*
+ * When this BPF program is run by tc from the filter classifier,
+ * it is able to read skb metadata and packet data.
+ *
+ * For packets where RSS is not possible, then just return TC_ACT_OK.
+ * When RSS is desired, change the skb->queue_mapping and set TC_ACT_PIPE
+ * to continue processing.
+ */
+SEC("tc/ingress") int
+rss_flow_action(struct __sk_buff *skb)
+{
+	const struct rss_key *rsskey;
+	char fmt[] = "rss_flow_action classid:%u\n";
+	__u16 classid;
+	__u32 hash;
+
+	/* TC layer puts the BPF_CLASSID into the skb cb area */
+	classid = ((const struct qdisc_skb_cb *)skb->cb)->tc_classid;
+	bpf_trace_printk(fmt, sizeof(fmt), classid);
+
+	/* Lookup RSS configuration for that BPF class */
+	rsskey = bpf_map_lookup_elem(&rss_map, &classid);
+	if (rsskey == NULL) {
+		bpf_printk("hash(): rss not configured");
+		return TC_ACT_OK;
+	}
+
+	hash = calculate_rss_hash(skb, rsskey);
+	bpf_printk("hash %u\n", hash);
+	if (hash) {
+		/* Fold hash to the number of queues configured */
+		skb->queue_mapping = reciprocal_scale(hash, rsskey->nb_queues);
+		bpf_printk("queue %u\n", skb->queue_mapping);
+		return TC_ACT_PIPE;
+	}
+	return TC_ACT_OK;
+}
+
+char _license[] SEC("license") = "Dual BSD/GPL";
diff --git a/drivers/net/tap/meson.build b/drivers/net/tap/meson.build
index 5099ccdff11b..52e0fde3b06c 100644
--- a/drivers/net/tap/meson.build
+++ b/drivers/net/tap/meson.build
@@ -7,33 +7,21 @@ if not is_linux
 endif
 sources = files(
         'rte_eth_tap.c',
-        'tap_bpf_api.c',
         'tap_flow.c',
         'tap_intr.c',
         'tap_netlink.c',
         'tap_tcmsgs.c',
 )
 
+bpf_dep = dependency('libbpf', required: false, method: 'pkg-config')
+if bpf_dep.found()
+    message('drivers/tap: RSS support (bpf)')
+    cflags += '-DHAVE_LIBBPF'
+    ext_deps += bpf_dep
+endif
+
 deps = ['bus_vdev', 'gso', 'hash']
 
 cflags += '-DTAP_MAX_QUEUES=16'
 
-# input array for meson symbol search:
-# [ "MACRO to define if found", "header for the search",
-#   "enum/define", "symbol to search" ]
-#
-args = [
-        [ 'HAVE_TC_FLOWER', 'linux/pkt_cls.h', 'TCA_FLOWER_UNSPEC' ],
-        [ 'HAVE_TC_VLAN_ID', 'linux/pkt_cls.h', 'TCA_FLOWER_KEY_VLAN_PRIO' ],
-        [ 'HAVE_TC_BPF', 'linux/pkt_cls.h', 'TCA_BPF_UNSPEC' ],
-        [ 'HAVE_TC_BPF_FD', 'linux/pkt_cls.h', 'TCA_BPF_FD' ],
-        [ 'HAVE_TC_ACT_BPF', 'linux/tc_act/tc_bpf.h', 'TCA_ACT_BPF_UNSPEC' ],
-        [ 'HAVE_TC_ACT_BPF_FD', 'linux/tc_act/tc_bpf.h', 'TCA_ACT_BPF_FD' ],
-]
-config = configuration_data()
-foreach arg:args
-    config.set(arg[0], cc.has_header_symbol(arg[1], arg[2]))
-endforeach
-configure_file(output : 'tap_autoconf.h', configuration : config)
-
 require_iova_in_mbuf = false
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index b41fa971cb7e..a98cc8f01ae1 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -1138,6 +1138,7 @@ tap_dev_close(struct rte_eth_dev *dev)
 		tap_flow_implicit_flush(internals, NULL);
 		tap_nl_final(internals->nlsk_fd);
 		internals->nlsk_fd = -1;
+		tap_flow_bpf_destroy(internals);
 	}
 
 	for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) {
@@ -1959,6 +1960,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
 	strlcpy(pmd->name, tap_name, sizeof(pmd->name));
 	pmd->type = type;
 	pmd->ka_fd = -1;
+	pmd->rss = NULL;
 	pmd->nlsk_fd = -1;
 	pmd->gso_ctx_mp = NULL;
 
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 5ac93f93e961..0cf2b30bb03b 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -79,12 +79,11 @@ struct pmd_internals {
 	int flow_isolate;                 /* 1 if flow isolation is enabled */
 	int flower_support;               /* 1 if kernel supports, else 0 */
 	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
-	int rss_enabled;                  /* 1 if RSS is enabled, else 0 */
 	int persist;			  /* 1 if keep link up, else 0 */
-	/* implicit rules set when RSS is enabled */
-	int map_fd;                       /* BPF RSS map fd */
-	int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */
-	LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
+
+	struct tap_rss *rss;		  /* BPF program */
+	uint16_t bpf_flowid;		  /* next BPF class id */
+
 	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
 	/* implicit rte_flow rules set when a remote device is active */
 	LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
diff --git a/drivers/net/tap/tap_bpf_api.c b/drivers/net/tap/tap_bpf_api.c
deleted file mode 100644
index 9e05e2ddf19b..000000000000
--- a/drivers/net/tap/tap_bpf_api.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2017 Mellanox Technologies, Ltd
- */
-
-#include <unistd.h>
-#include <syscall.h>
-#include <linux/bpf.h>
-
-#include <tap_flow.h>
-#include <tap_autoconf.h>
-
-#include <tap_bpf_insns.h>
-
-
-static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
-		size_t insns_cnt, const char *license);
-
-/**
- * Load BPF program (section cls_q) into the kernel and return a bpf fd
- *
- * @param queue_idx
- *   Queue index matching packet cb
- *
- * @return
- *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
- */
-int tap_flow_bpf_cls_q(__u32 queue_idx)
-{
-	cls_q_insns[1].imm = queue_idx;
-
-	return bpf_load(BPF_PROG_TYPE_SCHED_CLS,
-		(struct bpf_insn *)cls_q_insns,
-		RTE_DIM(cls_q_insns),
-		"Dual BSD/GPL");
-}
-
-/**
- * Load BPF program (section l3_l4) into the kernel and return a bpf fd.
- *
- * @param[in] key_idx
- *   RSS MAP key index
- *
- * @param[in] map_fd
- *   BPF RSS map file descriptor
- *
- * @return
- *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
- */
-int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
-{
-	l3_l4_hash_insns[4].imm = key_idx;
-	l3_l4_hash_insns[9].imm = map_fd;
-
-	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
-		(struct bpf_insn *)l3_l4_hash_insns,
-		RTE_DIM(l3_l4_hash_insns),
-		"Dual BSD/GPL");
-}
-
-/**
- * Helper function to convert a pointer to unsigned 64 bits
- *
- * @param[in] ptr
- *   pointer to address
- *
- * @return
- *   64 bit unsigned long type of pointer address
- */
-static inline __u64 ptr_to_u64(const void *ptr)
-{
-	return (__u64)(unsigned long)ptr;
-}
-
-/**
- * Call BPF system call
- *
- * @param[in] cmd
- *   BPF command for program loading, map creation, map entry update, etc
- *
- * @param[in] attr
- *   System call attributes relevant to system call command
- *
- * @param[in] size
- *   size of attr parameter
- *
- * @return
- *   -1 if BPF system call failed, 0 otherwise
- */
-static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
-			unsigned int size)
-{
-#ifdef __NR_bpf
-	return syscall(__NR_bpf, cmd, attr, size);
-#else
-	TAP_LOG(ERR, "No bpf syscall, kernel headers too old?\n");
-	errno = ENOSYS;
-	return -1;
-#endif
-}
-
-/**
- * Load BPF instructions to kernel
- *
- * @param[in] type
- *   BPF program type: classifier or action
- *
- * @param[in] insns
- *   Array of BPF instructions (equivalent to BPF instructions)
- *
- * @param[in] insns_cnt
- *   Number of BPF instructions (size of array)
- *
- * @param[in] license
- *   License string that must be acknowledged by the kernel
- *
- * @return
- *   -1 if the BPF program couldn't be loaded, fd (file descriptor) otherwise
- */
-static int bpf_load(enum bpf_prog_type type,
-		  const struct bpf_insn *insns,
-		  size_t insns_cnt,
-		  const char *license)
-{
-	union bpf_attr attr = {};
-
-	bzero(&attr, sizeof(attr));
-	attr.prog_type = type;
-	attr.insn_cnt = (__u32)insns_cnt;
-	attr.insns = ptr_to_u64(insns);
-	attr.license = ptr_to_u64(license);
-	attr.log_buf = ptr_to_u64(NULL);
-	attr.log_level = 0;
-	attr.kern_version = 0;
-
-	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
-}
-
-/**
- * Create BPF map for RSS rules
- *
- * @param[in] key_size
- *   map RSS key size
- *
- * @param[in] value_size
- *   Map RSS value size
- *
- * @param[in] max_entries
- *   Map max number of RSS entries (limit on max RSS rules)
- *
- * @return
- *   -1 if BPF map couldn't be created, map fd otherwise
- */
-int tap_flow_bpf_rss_map_create(unsigned int key_size,
-		unsigned int value_size,
-		unsigned int max_entries)
-{
-	union bpf_attr attr = {};
-
-	bzero(&attr, sizeof(attr));
-	attr.map_type    = BPF_MAP_TYPE_HASH;
-	attr.key_size    = key_size;
-	attr.value_size  = value_size;
-	attr.max_entries = max_entries;
-
-	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
-}
-
-/**
- * Update RSS entry in BPF map
- *
- * @param[in] fd
- *   RSS map fd
- *
- * @param[in] key
- *   Pointer to RSS key whose entry is updated
- *
- * @param[in] value
- *   Pointer to RSS new updated value
- *
- * @return
- *   -1 if RSS entry failed to be updated, 0 otherwise
- */
-int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value)
-{
-	union bpf_attr attr = {};
-
-	bzero(&attr, sizeof(attr));
-
-	attr.map_type = BPF_MAP_TYPE_HASH;
-	attr.map_fd = fd;
-	attr.key = ptr_to_u64(key);
-	attr.value = ptr_to_u64(value);
-	attr.flags = BPF_ANY;
-
-	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
-}
diff --git a/drivers/net/tap/tap_bpf_insns.h b/drivers/net/tap/tap_bpf_insns.h
deleted file mode 100644
index 88aec6885a06..000000000000
--- a/drivers/net/tap/tap_bpf_insns.h
+++ /dev/null
@@ -1,1742 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Auto-generated from tap_bpf_program.c
- * This not the original source file. Do NOT edit it.
- */
-
-
-static struct bpf_insn cls_q_insns[] = {
-	{0x61,    2,    1,       52, 0x00000000},
-	{0x18,    3,    0,        0, 0xdeadbeef},
-	{0x00,    0,    0,        0, 0x00000000},
-	{0x63,   10,    3,       -4, 0x00000000},
-	{0xb7,    0,    0,        0, 0x00000000},
-	{0x61,    3,   10,       -4, 0x00000000},
-	{0x07,    3,    0,        0, 0x7cafe800},
-	{0x67,    3,    0,        0, 0x00000020},
-	{0x77,    3,    0,        0, 0x00000020},
-	{0x5d,    2,    3,        4, 0x00000000},
-	{0xb7,    2,    0,        0, 0x00000000},
-	{0x63,    1,    2,       52, 0x00000000},
-	{0x18,    0,    0,        0, 0xffffffff},
-	{0x00,    0,    0,        0, 0x00000000},
-	{0x95,    0,    0,        0, 0x00000000},
-};
-
-static struct bpf_insn l3_l4_hash_insns[] = {
-	{0xbf,    7,    1,        0, 0x00000000},
-	{0x61,    6,    7,       16, 0x00000000},
-	{0x61,    8,    7,       76, 0x00000000},
-	{0x61,    9,    7,       80, 0x00000000},
-	{0x18,    1,    0,        0, 0xdeadbeef},
-	{0x00,    0,    0,        0, 0x00000000},
-	{0x63,   10,    1,       -4, 0x00000000},
-	{0xbf,    2,   10,        0, 0x00000000},
-	{0x07,    2,    0,        0, 0xfffffffc},
-	{0x18,    1,    0,        0, 0x00000000},
-	{0x00,    0,    0,        0, 0x00000000},
-	{0x85,    0,    0,        0, 0x00000001},
-	{0x55,    0,    0,       21, 0x00000000},
-	{0xb7,    1,    0,        0, 0x00000a64},
-	{0x6b,   10,    1,      -16, 0x00000000},
-	{0x18,    1,    0,        0, 0x69666e6f},
-	{0x00,    0,    0,        0, 0x65727567},
-	{0x7b,   10,    1,      -24, 0x00000000},
-	{0x18,    1,    0,        0, 0x6e207369},
-	{0x00,    0,    0,        0, 0x6320746f},
-	{0x7b,   10,    1,      -32, 0x00000000},
-	{0x18,    1,    0,        0, 0x20737372},
-	{0x00,    0,    0,        0, 0x2079656b},
-	{0x7b,   10,    1,      -40, 0x00000000},
-	{0x18,    1,    0,        0, 0x68736168},
-	{0x00,    0,    0,        0, 0x203a2928},
-	{0x7b,   10,    1,      -48, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0x73,   10,    7,      -14, 0x00000000},
-	{0xbf,    1,   10,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0xffffffd0},
-	{0xb7,    2,    0,        0, 0x00000023},
-	{0x85,    0,    0,        0, 0x00000006},
-	{0x05,    0,    0,     1680, 0x00000000},
-	{0xb7,    1,    0,        0, 0x0000000e},
-	{0x61,    2,    7,       20, 0x00000000},
-	{0x15,    2,    0,       10, 0x00000000},
-	{0x61,    2,    7,       28, 0x00000000},
-	{0x55,    2,    0,        8, 0x0000a888},
-	{0xbf,    2,    7,        0, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0xbf,    1,    8,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0x00000012},
-	{0x2d,    1,    9,     1670, 0x00000000},
-	{0xb7,    1,    0,        0, 0x00000012},
-	{0x69,    6,    8,       16, 0x00000000},
-	{0xbf,    7,    2,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x0000ffff},
-	{0x7b,   10,    7,      -56, 0x00000000},
-	{0x15,    6,    0,      443, 0x0000dd86},
-	{0xb7,    7,    0,        0, 0x00000003},
-	{0x55,    6,    0,     1662, 0x00000008},
-	{0x0f,    8,    1,        0, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0xbf,    1,    8,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0x00000018},
-	{0x2d,    1,    9,     1657, 0x00000000},
-	{0xb7,    1,    0,        0, 0x00000000},
-	{0x71,    3,    8,       12, 0x00000000},
-	{0x71,    2,    8,        9, 0x00000000},
-	{0x15,    2,    0,        1, 0x00000011},
-	{0x55,    2,    0,       21, 0x00000006},
-	{0x71,    2,    8,        7, 0x00000000},
-	{0x71,    4,    8,        6, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x67,    5,    0,        0, 0x00000008},
-	{0x57,    5,    0,        0, 0x00001f00},
-	{0x4f,    5,    2,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x4f,    4,    5,        0, 0x00000000},
-	{0x55,    4,    0,       12, 0x00000000},
-	{0xbf,    2,    8,        0, 0x00000000},
-	{0x07,    2,    0,        0, 0x00000014},
-	{0x71,    4,    2,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000018},
-	{0x71,    1,    2,        1, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000010},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    4,    2,        3, 0x00000000},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    2,    2,        2, 0x00000000},
-	{0x67,    2,    0,        0, 0x00000008},
-	{0x4f,    1,    2,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000038},
-	{0xc7,    4,    0,        0, 0x00000038},
-	{0xb7,    2,    0,        0, 0x00000000},
-	{0x65,    4,    0,        1, 0xffffffff},
-	{0xb7,    7,    0,        0, 0x2cc681d1},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x598d03a2},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb31a0745},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x66340e8a},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xcc681d15},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000004},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x98d03a2b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000002},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x31a07456},
-	{0x71,    4,    8,       13, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6340e8ad},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc681d15b},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d03a2b7},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1a07456f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x340e8ade},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x681d15bd},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd03a2b7b},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa07456f6},
-	{0x71,    3,    8,       14, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x40e8aded},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000038},
-	{0xc7,    4,    0,        0, 0x00000038},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0x81d15bdb},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x03a2b7b7},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x07456f6f},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x0e8adedf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1d15bdbf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000004},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3a2b7b7e},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000002},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7456f6fd},
-	{0x71,    4,    8,       15, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe8adedfa},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd15bdbf4},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa2b7b7e9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x456f6fd3},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8adedfa7},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x15bdbf4f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x2b7b7e9e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x56f6fd3d},
-	{0x71,    3,    8,       16, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xadedfa7b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000038},
-	{0xc7,    4,    0,        0, 0x00000038},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5bdbf4f7},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb7b7e9ef},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6f6fd3df},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xdedfa7bf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xbdbf4f7f},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000004},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7b7e9eff},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000002},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf6fd3dff},
-	{0x71,    4,    8,       17, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xedfa7bfe},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdbf4f7fc},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb7e9eff9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6fd3dff2},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdfa7bfe5},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbf4f7fca},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7e9eff94},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfd3dff28},
-	{0x71,    3,    8,       18, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfa7bfe51},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x67,    6,    0,        0, 0x00000038},
-	{0xc7,    6,    0,        0, 0x00000038},
-	{0xbf,    4,    5,        0, 0x00000000},
-	{0xa7,    4,    0,        0, 0xf4f7fca2},
-	{0x6d,    2,    6,        1, 0x00000000},
-	{0xbf,    4,    5,        0, 0x00000000},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000040},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xe9eff945},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000020},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd3dff28a},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000010},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xa7bfe514},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000008},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x4f7fca28},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x9eff9450},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x3dff28a0},
-	{0x71,    5,    8,       19, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x7bfe5141},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    7,    4,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf7fca283},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    7,    4,        0, 0x00000000},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xeff94506},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xdff28a0c},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xbfe51418},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7fca2831},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xff945063},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xff28a0c6},
-	{0x57,    5,    0,        0, 0x00000001},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xfe51418c},
-	{0xbf,    4,    1,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000020},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0xbf,    3,    7,        0, 0x00000000},
-	{0xa7,    3,    0,        0, 0xfca28319},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    3,    7,        0, 0x00000000},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x40000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf9450633},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x20000000},
-	{0x79,    6,   10,      -56, 0x00000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf28a0c67},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x10000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xe51418ce},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x08000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xca28319d},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x04000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x9450633b},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x02000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x28a0c676},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x01000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x51418ced},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00800000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xa28319db},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00400000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x450633b6},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00200000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8a0c676c},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00100000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x1418ced8},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00080000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x28319db1},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00040000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x50633b63},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00020000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xa0c676c6},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00010000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x418ced8d},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00008000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8319db1a},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00004000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x0633b634},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00002000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x0c676c68},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00001000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x18ced8d1},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000800},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x319db1a3},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000400},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x633b6347},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000200},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xc676c68f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000100},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8ced8d1f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000080},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x19db1a3e},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000040},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x33b6347d},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000020},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x676c68fa},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000010},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xced8d1f4},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000008},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x9db1a3e9},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000004},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x3b6347d2},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000002},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x76c68fa5},
-	{0x57,    1,    0,        0, 0x00000001},
-	{0x15,    1,    0,     1194, 0x00000000},
-	{0xa7,    3,    0,        0, 0xed8d1f4a},
-	{0x05,    0,    0,     1192, 0x00000000},
-	{0x0f,    8,    1,        0, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0xbf,    1,    8,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0x0000002c},
-	{0x2d,    1,    9,     1216, 0x00000000},
-	{0x61,    2,    8,        8, 0x00000000},
-	{0xdc,    2,    0,        0, 0x00000040},
-	{0xc7,    2,    0,        0, 0x00000020},
-	{0x71,    3,    8,        6, 0x00000000},
-	{0x15,    3,    0,        2, 0x00000011},
-	{0xb7,    1,    0,        0, 0x00000000},
-	{0x55,    3,    0,       12, 0x00000006},
-	{0xbf,    3,    8,        0, 0x00000000},
-	{0x07,    3,    0,        0, 0x00000028},
-	{0x71,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000018},
-	{0x71,    1,    3,        1, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000010},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    4,    3,        3, 0x00000000},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    3,    3,        2, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000008},
-	{0x4f,    1,    3,        0, 0x00000000},
-	{0xbf,    4,    2,        0, 0x00000000},
-	{0x77,    4,    0,        0, 0x0000001f},
-	{0x57,    4,    0,        0, 0x2cc681d1},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x598d03a2},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb31a0745},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x66340e8a},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xcc681d15},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x98d03a2b},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x31a07456},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x6340e8ad},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xc681d15b},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x8d03a2b7},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00200000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x1a07456f},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x340e8ade},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x681d15bd},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd03a2b7b},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xa07456f6},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00010000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x40e8aded},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x81d15bdb},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00004000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x03a2b7b7},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x07456f6f},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x0e8adedf},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x1d15bdbf},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x3a2b7b7e},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x7456f6fd},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xe8adedfa},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd15bdbf4},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xa2b7b7e9},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x456f6fd3},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x8adedfa7},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x15bdbf4f},
-	{0x61,    3,    8,       12, 0x00000000},
-	{0xbf,    5,    2,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x2b7b7e9e},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    2,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x56f6fd3d},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    2,    0,        0, 0x00000001},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xadedfa7b},
-	{0xb7,    2,    0,        0, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0x5bdbf4f7},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x40000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb7b7e9ef},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x20000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6f6fd3df},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x10000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdedfa7bf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x08000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbdbf4f7f},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x04000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7b7e9eff},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x02000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf6fd3dff},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x01000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xedfa7bfe},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00800000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdbf4f7fc},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00400000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb7e9eff9},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00200000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6fd3dff2},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00100000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdfa7bfe5},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00080000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbf4f7fca},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00040000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7e9eff94},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00020000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfd3dff28},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00010000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfa7bfe51},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00008000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf4f7fca2},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00004000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe9eff945},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00002000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd3dff28a},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00001000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa7bfe514},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000800},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x4f7fca28},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000400},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x9eff9450},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000200},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3dff28a0},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000100},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7bfe5141},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000080},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf7fca283},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xeff94506},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdff28a0c},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbfe51418},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7fca2831},
-	{0x61,    4,    8,       16, 0x00000000},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000004},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xff945063},
-	{0xdc,    4,    0,        0, 0x00000040},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000002},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xff28a0c6},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfe51418c},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0xfca28319},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf9450633},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf28a0c67},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe51418ce},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xca28319d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9450633b},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x28a0c676},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x51418ced},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa28319db},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x450633b6},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00200000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8a0c676c},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1418ced8},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x28319db1},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x50633b63},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa0c676c6},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00010000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x418ced8d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8319db1a},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00004000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x0633b634},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x0c676c68},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x18ced8d1},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x319db1a3},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x633b6347},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc676c68f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8ced8d1f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x19db1a3e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x33b6347d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x676c68fa},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xced8d1f4},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9db1a3e9},
-	{0x61,    3,    8,       20, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3b6347d2},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x76c68fa5},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xed8d1f4a},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdb1a3e94},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x40000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb6347d28},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x20000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6c68fa51},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x10000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd8d1f4a3},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x08000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb1a3e946},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x04000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6347d28d},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x02000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc68fa51a},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x01000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d1f4a35},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00800000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1a3e946b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00400000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x347d28d7},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00200000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x68fa51ae},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00100000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd1f4a35c},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00080000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa3e946b9},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00040000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x47d28d73},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00020000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8fa51ae7},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00010000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1f4a35cf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00008000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3e946b9e},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00004000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7d28d73c},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00002000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfa51ae78},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00001000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf4a35cf1},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000800},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe946b9e3},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000400},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd28d73c7},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000200},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa51ae78e},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000100},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x4a35cf1c},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000080},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x946b9e38},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x28d73c71},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x51ae78e3},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa35cf1c6},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x46b9e38d},
-	{0x61,    4,    8,       24, 0x00000000},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000004},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d73c71b},
-	{0xdc,    4,    0,        0, 0x00000040},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000002},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1ae78e36},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x35cf1c6c},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6b9e38d9},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xd73c71b2},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xae78e364},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5cf1c6c9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb9e38d92},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x73c71b25},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe78e364b},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xcf1c6c96},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9e38d92c},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3c71b259},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00200000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x78e364b2},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf1c6c964},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe38d92c9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc71b2593},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8e364b27},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00010000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1c6c964e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x38d92c9c},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00004000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x71b25938},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe364b270},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc6c964e0},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8d92c9c0},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1b259380},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x364b2700},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6c964e01},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xd92c9c03},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb2593807},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x64b2700f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc964e01e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x92c9c03d},
-	{0x61,    3,    8,       28, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x2593807a},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x4b2700f4},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x964e01e8},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0x2c9c03d1},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x40000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x593807a3},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x20000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb2700f46},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x10000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x64e01e8d},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x08000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc9c03d1a},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x04000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x93807a35},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x02000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x2700f46b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x01000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x4e01e8d6},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00800000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x9c03d1ad},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00400000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3807a35b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00200000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x700f46b6},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00100000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe01e8d6c},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00080000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc03d1ad9},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00040000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x807a35b3},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00020000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x00f46b66},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00010000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x01e8d6cc},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00008000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x03d1ad99},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00004000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x07a35b32},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00002000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x0f46b665},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00001000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1e8d6cca},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000800},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3d1ad994},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000400},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7a35b328},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000200},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf46b6651},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000100},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe8d6cca2},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000080},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd1ad9944},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa35b3289},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x46b66512},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d6cca25},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1ad9944a},
-	{0x61,    4,    8,       32, 0x00000000},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000004},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x35b32894},
-	{0xdc,    4,    0,        0, 0x00000040},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000002},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6b665129},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd6cca253},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0xad9944a7},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5b32894f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb665129f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6cca253e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xd9944a7d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb32894fb},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x665129f6},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xcca253ec},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9944a7d9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x32894fb2},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00200000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x65129f65},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xca253eca},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x944a7d95},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x2894fb2a},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5129f655},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00010000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa253ecab},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x44a7d956},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00004000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x894fb2ac},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x129f6558},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x253ecab1},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x4a7d9563},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x94fb2ac7},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x29f6558f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x53ecab1e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa7d9563d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x4fb2ac7a},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9f6558f5},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3ecab1ea},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7d9563d5},
-	{0x61,    3,    8,       36, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xfb2ac7ab},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf6558f56},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xecab1eac},
-	{0xbf,    4,    7,        0, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd9563d59},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    4,    7,        0, 0x00000000},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x40000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb2ac7ab2},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x20000000},
-	{0x79,    6,   10,      -56, 0x00000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x6558f564},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x10000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xcab1eac8},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x08000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x9563d590},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x04000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x2ac7ab20},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x02000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x558f5641},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x01000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xab1eac83},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00800000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x563d5906},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00400000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xac7ab20c},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00200000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x58f56418},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00100000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb1eac831},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00080000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x63d59063},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00040000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xc7ab20c7},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00020000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x8f56418f},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00010000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x1eac831e},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00008000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x3d59063c},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00004000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x7ab20c78},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00002000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xf56418f0},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00001000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xeac831e1},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000800},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd59063c2},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000400},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xab20c784},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000200},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x56418f09},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000100},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xac831e12},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000080},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x59063c25},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000040},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb20c784b},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000020},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x6418f097},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000010},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xc831e12f},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000008},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x9063c25f},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x20c784be},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x418f097c},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x831e12f9},
-	{0xbf,    5,    1,        0, 0x00000000},
-	{0x67,    5,    0,        0, 0x00000020},
-	{0xc7,    5,    0,        0, 0x00000020},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0xa7,    3,    0,        0, 0x063c25f3},
-	{0x6d,    2,    5,        1, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x40000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x0c784be7},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x20000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x18f097cf},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x10000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x31e12f9f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x08000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x63c25f3f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x04000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xc784be7f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x02000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8f097cff},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x01000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x1e12f9fe},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00800000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x3c25f3fc},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00400000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x784be7f8},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00200000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf097cff0},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00100000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xe12f9fe0},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00080000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xc25f3fc1},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00040000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x84be7f83},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00020000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x097cff07},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00010000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x12f9fe0f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00008000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x25f3fc1f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00004000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x4be7f83f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00002000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x97cff07f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00001000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x2f9fe0fe},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000800},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x5f3fc1fd},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000400},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xbe7f83fb},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000200},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x7cff07f7},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000100},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf9fe0fee},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000080},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf3fc1fdc},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000040},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xe7f83fb8},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000020},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xcff07f70},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000010},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x9fe0fee1},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000008},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x3fc1fdc2},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000004},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x7f83fb85},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000002},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xff07f70a},
-	{0x57,    1,    0,        0, 0x00000001},
-	{0x15,    1,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xfe0fee15},
-	{0x71,    1,    0,      201, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000008},
-	{0x71,    2,    0,      200, 0x00000000},
-	{0x4f,    1,    2,        0, 0x00000000},
-	{0x71,    2,    0,      202, 0x00000000},
-	{0x67,    2,    0,        0, 0x00000010},
-	{0x71,    4,    0,      203, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000018},
-	{0x4f,    4,    2,        0, 0x00000000},
-	{0x4f,    4,    1,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000020},
-	{0x77,    3,    0,        0, 0x00000020},
-	{0x9f,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x0000000f},
-	{0x67,    3,    0,        0, 0x00000002},
-	{0x0f,    0,    3,        0, 0x00000000},
-	{0x71,    1,    0,      137, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000008},
-	{0x71,    2,    0,      136, 0x00000000},
-	{0x4f,    1,    2,        0, 0x00000000},
-	{0x71,    2,    0,      138, 0x00000000},
-	{0x67,    2,    0,        0, 0x00000010},
-	{0x71,    3,    0,      139, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000018},
-	{0x4f,    3,    2,        0, 0x00000000},
-	{0x4f,    3,    1,        0, 0x00000000},
-	{0x07,    3,    0,        0, 0x7cafe800},
-	{0x63,    6,    3,       52, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000001},
-	{0xbf,    0,    7,        0, 0x00000000},
-	{0x95,    0,    0,        0, 0x00000000},
-};
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index a5d38ee7c46c..b9184cd1c9ff 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -11,27 +11,25 @@
 
 #include <rte_byteorder.h>
 #include <rte_jhash.h>
+#include <rte_thash.h>
 #include <rte_malloc.h>
 #include <rte_eth_tap.h>
+
 #include <tap_flow.h>
-#include <tap_autoconf.h>
 #include <tap_tcmsgs.h>
 #include <tap_rss.h>
 
 
-/* RSS key management */
-enum bpf_rss_key_e {
-	KEY_CMD_GET = 1,
-	KEY_CMD_RELEASE,
-	KEY_CMD_INIT,
-	KEY_CMD_DEINIT,
-};
-
-enum key_status_e {
-	KEY_STAT_UNSPEC,
-	KEY_STAT_USED,
-	KEY_STAT_AVAILABLE,
-};
+#pragma GCC diagnostic push
+#ifdef HAVE_LIBBPF
+/* Workaround for warning in bpftool generated skeleton code */
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#include "tap_rss.skel.h"
+#else
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#include "tap_rss.stub.h"
+#endif
+#pragma GCC diagnostic pop
 
 #define ISOLATE_HANDLE 1
 #define REMOTE_PROMISCUOUS_HANDLE 2
@@ -39,8 +37,7 @@ enum key_status_e {
 struct rte_flow {
 	LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure */
 	struct rte_flow *remote_flow; /* associated remote flow */
-	int bpf_fd[SEC_MAX]; /* list of bfs fds per ELF section */
-	uint32_t key_idx; /* RSS rule key index into BPF map */
+	uint16_t flowid;
 	struct nlmsg msg;
 };
 
@@ -70,7 +67,7 @@ struct action_data {
 		} skbedit;
 		struct bpf {
 			struct tc_act_bpf bpf;
-			int bpf_fd;
+			uint16_t classid;
 			const char *annotation;
 		} bpf;
 	};
@@ -110,10 +107,7 @@ tap_flow_isolate(struct rte_eth_dev *dev,
 		 int set,
 		 struct rte_flow_error *error);
 
-static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx);
-static int rss_enable(struct pmd_internals *pmd,
-			const struct rte_flow_attr *attr,
-			struct rte_flow_error *error);
+static int rss_enable(struct pmd_internals *pmd, struct rte_flow_error *error);
 static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 			const struct rte_flow_action_rss *rss,
 			struct rte_flow_error *error);
@@ -827,7 +821,8 @@ tap_flow_item_validate(const struct rte_flow_item *item,
  *   -1 on failure, 0 on success
  */
 static int
-add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
+add_action(struct rte_flow *flow, struct pmd_internals *pmd,
+	   size_t *act_index, struct action_data *adata)
 {
 	struct nlmsg *msg = &flow->msg;
 
@@ -856,13 +851,18 @@ add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 		tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
 			     adata->skbedit.queue);
 	} else if (strcmp("bpf", adata->id) == 0) {
-		tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
+		struct bpf_program *rss_prog = pmd->rss->progs.rss_flow_action;
+
+		tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, bpf_program__fd(rss_prog));
 		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
 			   strlen(adata->bpf.annotation) + 1,
 			   adata->bpf.annotation);
 		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS,
 			   sizeof(adata->bpf.bpf),
 			   &adata->bpf.bpf);
+		tap_nlattr_add(&msg->nh, TCA_BPF_CLASSID,
+			       sizeof(adata->bpf.classid),
+			       &adata->bpf.classid);
 	} else {
 		return -1;
 	}
@@ -890,7 +890,8 @@ add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
  *   -1 on failure, 0 on success
  */
 static int
-add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
+add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
+	    int nb_actions, struct action_data *data,
 	    int classifier_action)
 {
 	struct nlmsg *msg = &flow->msg;
@@ -900,7 +901,7 @@ add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
 	if (tap_nlattr_nested_start(msg, classifier_action) < 0)
 		return -1;
 	for (i = 0; i < nb_actions; i++)
-		if (add_action(flow, &act_index, data + i) < 0)
+		if (add_action(flow, pmd,  &act_index, data + i) < 0)
 			return -1;
 	tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
 	return 0;
@@ -1060,7 +1061,7 @@ priv_flow_process(struct pmd_internals *pmd,
 			adata.mirred.action = TC_ACT_PIPE;
 		else
 			adata.mirred.action = TC_ACT_STOLEN;
-		if (add_actions(flow, 1, &adata, TCA_FLOWER_ACT) < 0)
+		if (add_actions(flow, pmd, 1, &adata, TCA_FLOWER_ACT) < 0)
 			goto exit_action_not_supported;
 		else
 			goto end;
@@ -1083,7 +1084,7 @@ priv_flow_process(struct pmd_internals *pmd,
 					},
 				};
 
-				err = add_actions(flow, 1, &adata,
+				err = add_actions(flow, pmd, 1, &adata,
 						  TCA_FLOWER_ACT);
 			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_PASSTHRU) {
@@ -1099,7 +1100,7 @@ priv_flow_process(struct pmd_internals *pmd,
 					},
 				};
 
-				err = add_actions(flow, 1, &adata,
+				err = add_actions(flow, pmd, 1, &adata,
 						  TCA_FLOWER_ACT);
 			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
@@ -1124,8 +1125,8 @@ priv_flow_process(struct pmd_internals *pmd,
 					},
 				};
 
-				err = add_actions(flow, 1, &adata,
-					TCA_FLOWER_ACT);
+				err = add_actions(flow, pmd, 1, &adata,
+						  TCA_FLOWER_ACT);
 			}
 		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
 			const struct rte_flow_action_rss *rss =
@@ -1135,8 +1136,8 @@ priv_flow_process(struct pmd_internals *pmd,
 			if (action++)
 				goto exit_action_not_supported;
 
-			if (!pmd->rss_enabled) {
-				err = rss_enable(pmd, attr, error);
+			if (pmd->rss == NULL) {
+				err = rss_enable(pmd, error);
 				if (err)
 					goto exit_action_not_supported;
 			}
@@ -1239,23 +1240,14 @@ tap_flow_set_handle(struct rte_flow *flow)
 static void
 tap_flow_free(struct pmd_internals *pmd, struct rte_flow *flow)
 {
-	int i;
+	struct tap_rss *rss = pmd->rss;
 
 	if (!flow)
 		return;
 
-	if (pmd->rss_enabled) {
-		/* Close flow BPF file descriptors */
-		for (i = 0; i < SEC_MAX; i++)
-			if (flow->bpf_fd[i] != 0) {
-				close(flow->bpf_fd[i]);
-				flow->bpf_fd[i] = 0;
-			}
-
-		/* Release the map key for this RSS rule */
-		bpf_rss_key(KEY_CMD_RELEASE, &flow->key_idx);
-		flow->key_idx = 0;
-	}
+	if (rss)
+		bpf_map__delete_elem(rss->maps.rss_map, &flow->flowid,
+				     sizeof(flow->flowid), 0);
 
 	/* Free flow allocated memory */
 	rte_free(flow);
@@ -1723,13 +1715,16 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error)
 	return 0;
 }
 
-#define MAX_RSS_KEYS 256
-#define KEY_IDX_OFFSET (3 * MAX_RSS_KEYS)
-#define SEC_NAME_CLS_Q "cls_q"
-
-static const char *sec_name[SEC_MAX] = {
-	[SEC_L3_L4] = "l3_l4",
-};
+/**
+ * Cleanup when device is closed
+ */
+void tap_flow_bpf_destroy(struct pmd_internals *pmd)
+{
+	if (pmd->rss == NULL)
+		return;
+	tap_rss__destroy(pmd->rss);
+	pmd->rss = NULL;
+}
 
 /**
  * Enable RSS on tap: create TC rules for queuing.
@@ -1745,225 +1740,76 @@ static const char *sec_name[SEC_MAX] = {
  *
  * @return 0 on success, negative value on failure.
  */
-static int rss_enable(struct pmd_internals *pmd,
-			const struct rte_flow_attr *attr,
-			struct rte_flow_error *error)
+static int rss_enable(struct pmd_internals *pmd, struct rte_flow_error *error)
 {
-	struct rte_flow *rss_flow = NULL;
-	struct nlmsg *msg = NULL;
-	/* 4096 is the maximum number of instructions for a BPF program */
-	char annotation[64];
-	int i;
-	int err = 0;
-
-	/* unlimit locked memory */
-	struct rlimit memlock_limit = {
-		.rlim_cur = RLIM_INFINITY,
-		.rlim_max = RLIM_INFINITY,
-	};
-	setrlimit(RLIMIT_MEMLOCK, &memlock_limit);
-
-	 /* Get a new map key for a new RSS rule */
-	err = bpf_rss_key(KEY_CMD_INIT, NULL);
-	if (err < 0) {
-		rte_flow_error_set(
-			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
-			"Failed to initialize BPF RSS keys");
-
-		return -1;
-	}
-
-	/*
-	 *  Create BPF RSS MAP
-	 */
-	pmd->map_fd = tap_flow_bpf_rss_map_create(sizeof(__u32), /* key size */
-				sizeof(struct rss_key),
-				MAX_RSS_KEYS);
-	if (pmd->map_fd < 0) {
-		TAP_LOG(ERR,
-			"Failed to create BPF map (%d): %s",
-				errno, strerror(errno));
-		rte_flow_error_set(
-			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
-			"Kernel too old or not configured "
-			"to support BPF maps");
+	int err;
 
-		return -ENOTSUP;
+	/* Load the BPF program (defined in tap_bpf.h from skeleton) */
+	pmd->rss = tap_rss__open_and_load();
+	if (pmd->rss == NULL) {
+		TAP_LOG(ERR, "Failed to load BPF object: %s", strerror(errno));
+		rte_flow_error_set(error, errno, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"BPF object could not be loaded");
+		return -errno;
 	}
 
-	/*
-	 * Add a rule per queue to match reclassified packets and direct them to
-	 * the correct queue.
-	 */
-	for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
-		pmd->bpf_fd[i] = tap_flow_bpf_cls_q(i);
-		if (pmd->bpf_fd[i] < 0) {
-			TAP_LOG(ERR,
-				"Failed to load BPF section %s for queue %d",
-				SEC_NAME_CLS_Q, i);
-			rte_flow_error_set(
-				error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
-				NULL,
-				"Kernel too old or not configured "
-				"to support BPF programs loading");
-
-			return -ENOTSUP;
-		}
-
-		rss_flow = rte_zmalloc(__func__, sizeof(struct rte_flow), 0);
-		if (!rss_flow) {
-			TAP_LOG(ERR,
-				"Cannot allocate memory for rte_flow");
-			return -1;
-		}
-		msg = &rss_flow->msg;
-		tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, NLM_F_REQUEST |
-			    NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
-		msg->t.tcm_info = TC_H_MAKE(0, htons(ETH_P_ALL));
-		tap_flow_set_handle(rss_flow);
-		uint16_t group = attr->group << GROUP_SHIFT;
-		uint16_t prio = group | (i + PRIORITY_OFFSET);
-		msg->t.tcm_info = TC_H_MAKE(prio << 16, msg->t.tcm_info);
-		msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
-
-		tap_nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
-		if (tap_nlattr_nested_start(msg, TCA_OPTIONS) < 0)
-			return -1;
-		tap_nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]);
-		snprintf(annotation, sizeof(annotation), "[%s%d]",
-			SEC_NAME_CLS_Q, i);
-		tap_nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation) + 1,
-			   annotation);
-		/* Actions */
-		{
-			struct action_data adata = {
-				.id = "skbedit",
-				.skbedit = {
-					.skbedit = {
-						.action = TC_ACT_PIPE,
-					},
-					.queue = i,
-				},
-			};
-			if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
-				return -1;
-		}
-		tap_nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
-
-		/* Netlink message is now ready to be sent */
-		if (tap_nl_send(pmd->nlsk_fd, &msg->nh) < 0)
-			return -1;
-		err = tap_nl_recv_ack(pmd->nlsk_fd);
-		if (err < 0) {
-			TAP_LOG(ERR,
-				"Kernel refused TC filter rule creation (%d): %s",
-				errno, strerror(errno));
-			return err;
-		}
-		LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
+	/* Attach the maps defined in BPF program */
+	err = tap_rss__attach(pmd->rss);
+	if (err < 0) {
+		TAP_LOG(ERR, "Failed to attach BPF object: %d", err);
+		rte_flow_error_set(error, -err, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+			"BPF object could not be attached");
+		tap_flow_bpf_destroy(pmd);
+		return err;
 	}
 
-	pmd->rss_enabled = 1;
-	return err;
+	return 0;
 }
 
-/**
- * Manage bpf RSS keys repository with operations: init, get, release
- *
- * @param[in] cmd
- *   Command on RSS keys: init, get, release
- *
- * @param[in, out] key_idx
- *   Pointer to RSS Key index (out for get command, in for release command)
- *
- * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise.
- */
-static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
-{
-	__u32 i;
-	int err = 0;
-	static __u32 num_used_keys;
-	static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC};
-	static __u32 rss_keys_initialized;
-	__u32 key;
-
-	switch (cmd) {
-	case KEY_CMD_GET:
-		if (!rss_keys_initialized) {
-			err = -1;
-			break;
-		}
-
-		if (num_used_keys == RTE_DIM(rss_keys)) {
-			err = -1;
-			break;
-		}
-
-		*key_idx = num_used_keys % RTE_DIM(rss_keys);
-		while (rss_keys[*key_idx] == KEY_STAT_USED)
-			*key_idx = (*key_idx + 1) % RTE_DIM(rss_keys);
-
-		rss_keys[*key_idx] = KEY_STAT_USED;
-
-		/*
-		 * Add an offset to key_idx in order to handle a case of
-		 * RSS and non RSS flows mixture.
-		 * If a non RSS flow is destroyed it has an eBPF map
-		 * index 0 (initialized on flow creation) and might
-		 * unintentionally remove RSS entry 0 from eBPF map.
-		 * To avoid this issue, add an offset to the real index
-		 * during a KEY_CMD_GET operation and subtract this offset
-		 * during a KEY_CMD_RELEASE operation in order to restore
-		 * the real index.
-		 */
-		*key_idx += KEY_IDX_OFFSET;
-		num_used_keys++;
-	break;
-
-	case KEY_CMD_RELEASE:
-		if (!rss_keys_initialized)
-			break;
-
-		/*
-		 * Subtract offset to restore real key index
-		 * If a non RSS flow is falsely trying to release map
-		 * entry 0 - the offset subtraction will calculate the real
-		 * map index as an out-of-range value and the release operation
-		 * will be silently ignored.
-		 */
-		key = *key_idx - KEY_IDX_OFFSET;
-		if (key >= RTE_DIM(rss_keys))
-			break;
-
-		if (rss_keys[key] == KEY_STAT_USED) {
-			rss_keys[key] = KEY_STAT_AVAILABLE;
-			num_used_keys--;
-		}
-	break;
 
-	case KEY_CMD_INIT:
-		for (i = 0; i < RTE_DIM(rss_keys); i++)
-			rss_keys[i] = KEY_STAT_AVAILABLE;
+/* Choose next flow id to use for BPF action */
+static int tap_rss_flow_assign(struct pmd_internals *pmd, uint16_t *flow_id)
+{
+	struct rte_flow *flow;
+	uint16_t id;
 
-		rss_keys_initialized = 1;
-		num_used_keys = 0;
-	break;
+	id = pmd->bpf_flowid;
 
-	case KEY_CMD_DEINIT:
-		for (i = 0; i < RTE_DIM(rss_keys); i++)
-			rss_keys[i] = KEY_STAT_UNSPEC;
+next_id:
+	/* Skip 0xffff and 0 as id's */
+	if (++id == UINT16_MAX)
+		id = 1;
 
-		rss_keys_initialized = 0;
-		num_used_keys = 0;
-	break;
+	/* Wrapped around, all id's have been used */
+	if (id == pmd->bpf_flowid)
+		return -1;
 
-	default:
-		break;
+	/* Make sure this id has not been used already */
+	for (flow = LIST_FIRST(&pmd->flows); flow; flow = LIST_NEXT(flow, next)) {
+		if (flow->flowid == id)
+			goto next_id;
 	}
 
-	return err;
+	/* Record starting point for next time */
+	pmd->bpf_flowid = id;
+	*flow_id = id;
+	return 0;
 }
 
+/* Default RSS hash key also used by mlx devices */
+static const uint8_t rss_hash_default_key[] = {
+	0x2c, 0xc6, 0x81, 0xd1,
+	0x5b, 0xdb, 0xf4, 0xf7,
+	0xfc, 0xa2, 0x83, 0x19,
+	0xdb, 0x1a, 0x3e, 0x94,
+	0x6b, 0x9e, 0x38, 0xd9,
+	0x2c, 0x9c, 0x03, 0xd1,
+	0xad, 0x99, 0x44, 0xa7,
+	0xd9, 0x56, 0x3d, 0x59,
+	0x06, 0x3c, 0x25, 0xf3,
+	0xfc, 0x1f, 0xdc, 0x2a,
+};
+
 /**
  * Add RSS hash calculations and queue selection
  *
@@ -1982,11 +1828,11 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 			   const struct rte_flow_action_rss *rss,
 			   struct rte_flow_error *error)
 {
-	/* 4096 is the maximum number of instructions for a BPF program */
+	struct rss_key rss_entry = { };
+	const uint8_t *key_in;
+	uint32_t hash_type = 0;
 	unsigned int i;
 	int err;
-	struct rss_key rss_entry = { .hash_fields = 0,
-				     .key_size = 0 };
 
 	/* Check supported RSS features */
 	if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT)
@@ -1998,31 +1844,69 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
 			 "a nonzero RSS encapsulation level is not supported");
 
-	/* Get a new map key for a new RSS rule */
-	err = bpf_rss_key(KEY_CMD_GET, &flow->key_idx);
+	if (rss->queue_num == 0 || rss->queue_num >= TAP_MAX_QUEUES)
+		return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  "invalid number of queues");
+
+	/* allow RSS key_len 0 in case of NULL (default) RSS key. */
+	if (rss->key_len == 0) {
+		if (rss->key != NULL)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+						  &rss->key_len, "RSS hash key length 0");
+		key_in = rss_hash_default_key;
+	} else {
+		if (rss->key_len != TAP_RSS_HASH_KEY_SIZE)
+			return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+						  NULL, "RSS hash invalid key length");
+		if (rss->key == NULL)
+			return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+						  NULL, "RSS hash key is NULL");
+		key_in = rss->key;
+	}
+
+	if (rss->types & TAP_RSS_HF_MASK)
+		return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					  NULL, "RSS hash type not supported");
+
+	if (rss->types & (RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV4_TCP))
+		hash_type |= RTE_BIT32(HASH_FIELD_IPV4_L3_L4);
+	else if (rss->types & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4))
+		hash_type |= RTE_BIT32(HASH_FIELD_IPV4_L3);
+
+	if (rss->types & (RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_NONFRAG_IPV6_TCP))
+		hash_type |= RTE_BIT32(HASH_FIELD_IPV6_L3_L4);
+	else if (rss->types & (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_IPV6_EX))
+		hash_type |= RTE_BIT32(HASH_FIELD_IPV6_L3);
+
+
+	/* Choose new flow id, which is used as index into the BPF map */
+	err = tap_rss_flow_assign(pmd, &flow->flowid);
 	if (err < 0) {
 		rte_flow_error_set(
 			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
-			"Failed to get BPF RSS key");
+			"Failed to get BPF flowid");
 
 		return -1;
 	}
 
+	rss_entry.hash_fields = hash_type;
+	rte_convert_rss_key((const uint32_t *)key_in, (uint32_t *)rss_entry.key,
+			    TAP_RSS_HASH_KEY_SIZE);
+
 	/* Update RSS map entry with queues */
 	rss_entry.nb_queues = rss->queue_num;
 	for (i = 0; i < rss->queue_num; i++)
 		rss_entry.queues[i] = rss->queue[i];
-	rss_entry.hash_fields =
-		(1 << HASH_FIELD_IPV4_L3_L4) | (1 << HASH_FIELD_IPV6_L3_L4);
 
 	/* Add this RSS entry to map */
-	err = tap_flow_bpf_update_rss_elem(pmd->map_fd,
-				&flow->key_idx, &rss_entry);
-
+	err = bpf_map__update_elem(pmd->rss->maps.rss_map,
+				   &flow->flowid, sizeof(uint16_t),
+				   &rss_entry, sizeof(rss_entry), 0);
 	if (err) {
 		TAP_LOG(ERR,
 			"Failed to update BPF map entry #%u (%d): %s",
-			flow->key_idx, errno, strerror(errno));
+			flow->flowid, errno, strerror(errno));
 		rte_flow_error_set(
 			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
 			"Kernel too old or not configured "
@@ -2031,33 +1915,14 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 		return -ENOTSUP;
 	}
 
-
-	/*
-	 * Load bpf rules to calculate hash for this key_idx
-	 */
-
-	flow->bpf_fd[SEC_L3_L4] =
-		tap_flow_bpf_calc_l3_l4_hash(flow->key_idx, pmd->map_fd);
-	if (flow->bpf_fd[SEC_L3_L4] < 0) {
-		TAP_LOG(ERR,
-			"Failed to load BPF section %s (%d): %s",
-				sec_name[SEC_L3_L4], errno, strerror(errno));
-		rte_flow_error_set(
-			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
-			"Kernel too old or not configured "
-			"to support BPF program loading");
-
-		return -ENOTSUP;
-	}
-
 	/* Actions */
 	{
 		struct action_data adata[] = {
 			{
 				.id = "bpf",
 				.bpf = {
-					.bpf_fd = flow->bpf_fd[SEC_L3_L4],
-					.annotation = sec_name[SEC_L3_L4],
+					.annotation = "tap_rss",
+					.classid = flow->flowid,
 					.bpf = {
 						.action = TC_ACT_PIPE,
 					},
@@ -2065,8 +1930,8 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 			},
 		};
 
-		if (add_actions(flow, RTE_DIM(adata), adata,
-			TCA_FLOWER_ACT) < 0)
+		if (add_actions(flow, pmd, RTE_DIM(adata), adata,
+				TCA_FLOWER_ACT) < 0)
 			return -1;
 	}
 
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 240fbc3dfaef..41f9833619a1 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -9,7 +9,6 @@
 #include <rte_flow.h>
 #include <rte_flow_driver.h>
 #include <rte_eth_tap.h>
-#include <tap_autoconf.h>
 
 /**
  * In TC, priority 0 means we require the kernel to allocate one for us.
@@ -41,10 +40,6 @@ enum implicit_rule_index {
 	TAP_REMOTE_MAX_IDX,
 };
 
-enum bpf_fd_idx {
-	SEC_L3_L4,
-	SEC_MAX,
-};
 
 int tap_dev_flow_ops_get(struct rte_eth_dev *dev,
 			 const struct rte_flow_ops **ops);
@@ -57,10 +52,6 @@ int tap_flow_implicit_destroy(struct pmd_internals *pmd,
 int tap_flow_implicit_flush(struct pmd_internals *pmd,
 			    struct rte_flow_error *error);
 
-int tap_flow_bpf_cls_q(__u32 queue_idx);
-int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
-int tap_flow_bpf_rss_map_create(unsigned int key_size, unsigned int value_size,
-			unsigned int max_entries);
-int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value);
+void tap_flow_bpf_destroy(struct pmd_internals *pmd);
 
 #endif /* _TAP_FLOW_H_ */
diff --git a/drivers/net/tap/tap_rss.h b/drivers/net/tap/tap_rss.h
index dff46a012f94..51b7ff0d007e 100644
--- a/drivers/net/tap/tap_rss.h
+++ b/drivers/net/tap/tap_rss.h
@@ -9,6 +9,9 @@
 #define TAP_MAX_QUEUES 16
 #endif
 
+/* Size of the map from BPF classid to queue table */
+#define TAP_RSS_MAX	TAP_MAX_QUEUES
+
 /* Fixed RSS hash key size in bytes. */
 #define TAP_RSS_HASH_KEY_SIZE 40
 
@@ -21,20 +24,13 @@ enum hash_field {
 	HASH_FIELD_IPV4_L3_L4,	/* IPv4 src/dst addr + L4 src/dst ports */
 	HASH_FIELD_IPV6_L3,	/* IPv6 src/dst addr */
 	HASH_FIELD_IPV6_L3_L4,	/* IPv6 src/dst addr + L4 src/dst ports */
-	HASH_FIELD_L2_SRC,	/* Ethernet src addr */
-	HASH_FIELD_L2_DST,	/* Ethernet dst addr */
-	HASH_FIELD_L3_SRC,	/* L3 src addr */
-	HASH_FIELD_L3_DST,	/* L3 dst addr */
-	HASH_FIELD_L4_SRC,	/* TCP/UDP src ports */
-	HASH_FIELD_L4_DST,	/* TCP/UDP dst ports */
 };
 
 struct rss_key {
-	 __u8 key[128];
 	__u32 hash_fields;
-	__u32 key_size;
-	__u32 queues[TAP_MAX_QUEUES];
+	__u8 key[TAP_RSS_HASH_KEY_SIZE];
 	__u32 nb_queues;
+	__u32 queues[TAP_MAX_QUEUES];
 } __attribute__((packed));
 
 #endif /* _TAP_RSS_H_ */
diff --git a/drivers/net/tap/tap_rss.skel.h b/drivers/net/tap/tap_rss.skel.h
new file mode 100644
index 000000000000..16b396f84919
--- /dev/null
+++ b/drivers/net/tap/tap_rss.skel.h
@@ -0,0 +1,11625 @@
+/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
+
+/* THIS FILE IS AUTOGENERATED BY BPFTOOL! */
+#ifndef __TAP_RSS_SKEL_H__
+#define __TAP_RSS_SKEL_H__
+
+#include <errno.h>
+#include <stdlib.h>
+#include <bpf/libbpf.h>
+
+struct tap_rss {
+	struct bpf_object_skeleton *skeleton;
+	struct bpf_object *obj;
+	struct {
+		struct bpf_map *rss_map;
+		struct bpf_map *rodata_str1_1;
+		struct bpf_map *rodata;
+	} maps;
+	struct {
+		struct bpf_program *rss_flow_action;
+	} progs;
+	struct {
+		struct bpf_link *rss_flow_action;
+	} links;
+
+#ifdef __cplusplus
+	static inline struct tap_rss *open(const struct bpf_object_open_opts *opts = nullptr);
+	static inline struct tap_rss *open_and_load();
+	static inline int load(struct tap_rss *skel);
+	static inline int attach(struct tap_rss *skel);
+	static inline void detach(struct tap_rss *skel);
+	static inline void destroy(struct tap_rss *skel);
+	static inline const void *elf_bytes(size_t *sz);
+#endif /* __cplusplus */
+};
+
+static void
+tap_rss__destroy(struct tap_rss *obj)
+{
+	if (!obj)
+		return;
+	if (obj->skeleton)
+		bpf_object__destroy_skeleton(obj->skeleton);
+	free(obj);
+}
+
+static inline int
+tap_rss__create_skeleton(struct tap_rss *obj);
+
+static inline struct tap_rss *
+tap_rss__open_opts(const struct bpf_object_open_opts *opts)
+{
+	struct tap_rss *obj;
+	int err;
+
+	obj = (struct tap_rss *)calloc(1, sizeof(*obj));
+	if (!obj) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	err = tap_rss__create_skeleton(obj);
+	if (err)
+		goto err_out;
+
+	err = bpf_object__open_skeleton(obj->skeleton, opts);
+	if (err)
+		goto err_out;
+
+	return obj;
+err_out:
+	tap_rss__destroy(obj);
+	errno = -err;
+	return NULL;
+}
+
+static inline struct tap_rss *
+tap_rss__open(void)
+{
+	return tap_rss__open_opts(NULL);
+}
+
+static inline int
+tap_rss__load(struct tap_rss *obj)
+{
+	return bpf_object__load_skeleton(obj->skeleton);
+}
+
+static inline struct tap_rss *
+tap_rss__open_and_load(void)
+{
+	struct tap_rss *obj;
+	int err;
+
+	obj = tap_rss__open();
+	if (!obj)
+		return NULL;
+	err = tap_rss__load(obj);
+	if (err) {
+		tap_rss__destroy(obj);
+		errno = -err;
+		return NULL;
+	}
+	return obj;
+}
+
+static inline int
+tap_rss__attach(struct tap_rss *obj)
+{
+	return bpf_object__attach_skeleton(obj->skeleton);
+}
+
+static inline void
+tap_rss__detach(struct tap_rss *obj)
+{
+	bpf_object__detach_skeleton(obj->skeleton);
+}
+
+static inline const void *tap_rss__elf_bytes(size_t *sz);
+
+static inline int
+tap_rss__create_skeleton(struct tap_rss *obj)
+{
+	struct bpf_object_skeleton *s;
+	int err;
+
+	s = (struct bpf_object_skeleton *)calloc(1, sizeof(*s));
+	if (!s)	{
+		err = -ENOMEM;
+		goto err;
+	}
+
+	s->sz = sizeof(*s);
+	s->name = "tap_rss";
+	s->obj = &obj->obj;
+
+	/* maps */
+	s->map_cnt = 3;
+	s->map_skel_sz = sizeof(*s->maps);
+	s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt, s->map_skel_sz);
+	if (!s->maps) {
+		err = -ENOMEM;
+		goto err;
+	}
+
+	s->maps[0].name = "rss_map";
+	s->maps[0].map = &obj->maps.rss_map;
+
+	s->maps[1].name = ".rodata.str1.1";
+	s->maps[1].map = &obj->maps.rodata_str1_1;
+
+	s->maps[2].name = "tap_rss.rodata";
+	s->maps[2].map = &obj->maps.rodata;
+
+	/* programs */
+	s->prog_cnt = 1;
+	s->prog_skel_sz = sizeof(*s->progs);
+	s->progs = (struct bpf_prog_skeleton *)calloc(s->prog_cnt, s->prog_skel_sz);
+	if (!s->progs) {
+		err = -ENOMEM;
+		goto err;
+	}
+
+	s->progs[0].name = "rss_flow_action";
+	s->progs[0].prog = &obj->progs.rss_flow_action;
+	s->progs[0].link = &obj->links.rss_flow_action;
+
+	s->data = (void *)tap_rss__elf_bytes(&s->data_sz);
+
+	obj->skeleton = s;
+	return 0;
+err:
+	bpf_object__destroy_skeleton(s);
+	return err;
+}
+
+static inline const void *tap_rss__elf_bytes(size_t *sz)
+{
+	*sz = 301248;
+	return (const void *)"\
+\x7f\x45\x4c\x46\x02\x01\x01\0\0\0\0\0\0\0\0\0\x01\0\xf7\0\x01\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x40\x91\x04\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\x40\0\x1e\0\
+\x01\0\xbf\x17\0\0\0\0\0\0\xb7\x01\0\0\x25\x75\x0a\0\x63\x1a\xc8\xff\0\0\0\0\
+\x18\x01\0\0\x63\x6c\x61\x73\0\0\0\0\x73\x69\x64\x3a\x7b\x1a\xc0\xff\0\0\0\0\
+\x18\x01\0\0\x5f\x61\x63\x74\0\0\0\0\x69\x6f\x6e\x20\x7b\x1a\xb8\xff\0\0\0\0\
+\x18\x01\0\0\x72\x73\x73\x5f\0\0\0\0\x66\x6c\x6f\x77\x7b\x1a\xb0\xff\0\0\0\0\
+\x69\x73\x36\0\0\0\0\0\x6b\x3a\xae\xff\0\0\0\0\xbf\xa1\0\0\0\0\0\0\x07\x01\0\0\
+\xb0\xff\xff\xff\xb7\x02\0\0\x1c\0\0\0\x85\0\0\0\x06\0\0\0\xbf\xa2\0\0\0\0\0\0\
+\x07\x02\0\0\xae\xff\xff\xff\x18\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x85\0\0\0\x01\
+\0\0\0\x55\0\x06\0\0\0\0\0\x18\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb7\x02\0\0\x1b\
+\0\0\0\x85\0\0\0\x06\0\0\0\xb7\x07\0\0\0\0\0\0\x05\0\xb9\x1e\0\0\0\0\xbf\x02\0\
+\0\0\0\0\0\xbf\x03\0\0\0\0\0\0\x07\x03\0\0\x04\0\0\0\x61\x71\x10\0\0\0\0\0\x15\
+\x01\x08\0\x08\0\0\0\x15\x01\xeb\x02\x86\xdd\0\0\xb7\x07\0\0\0\0\0\0\x18\x01\0\
+\0\x1b\0\0\0\0\0\0\0\0\0\0\0\xb7\x02\0\0\x09\0\0\0\xb7\x03\0\0\0\0\0\0\x85\0\0\
+\0\x06\0\0\0\x05\0\xac\x1e\0\0\0\0\x7b\x3a\x98\xff\0\0\0\0\x7b\x0a\x78\xff\0\0\
+\0\0\x71\x26\x03\0\0\0\0\0\x71\x29\x02\0\0\0\0\0\x71\x28\0\0\0\0\0\0\xbf\x71\0\
+\0\0\0\0\0\x7b\x2a\x80\xff\0\0\0\0\x71\x27\x01\0\0\0\0\0\xb7\x02\0\0\0\0\0\0\
+\x7b\x2a\x90\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xd8\xff\xff\xff\x7b\
+\x1a\x88\xff\0\0\0\0\xb7\x04\0\0\x14\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\
+\0\0\0\x55\0\x7d\x1e\0\0\0\0\x67\x07\0\0\x08\0\0\0\x4f\x87\0\0\0\0\0\0\x67\x09\
+\0\0\x10\0\0\0\x67\x06\0\0\x18\0\0\0\x4f\x96\0\0\0\0\0\0\x4f\x76\0\0\0\0\0\0\
+\x61\xa8\xe8\xff\0\0\0\0\xdc\x08\0\0\x20\0\0\0\x61\xa9\xe4\xff\0\0\0\0\xdc\x09\
+\0\0\x20\0\0\0\x57\x06\0\0\x01\0\0\0\x15\x06\xae\x0d\0\0\0\0\xb7\x05\0\0\0\0\0\
+\0\x79\xa4\x78\xff\0\0\0\0\xbf\x41\0\0\0\0\0\0\x07\x01\0\0\x08\0\0\0\xbf\x92\0\
+\0\0\0\0\0\x57\x02\0\0\0\0\0\x40\x15\x02\x07\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\
+\x61\x25\0\0\0\0\0\0\x67\x05\0\0\x01\0\0\0\x61\x12\0\0\0\0\0\0\x77\x02\0\0\x1f\
+\0\0\0\x57\x02\0\0\x01\0\0\0\x4f\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\
+\0\0\0\0\x20\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\
+\x67\x02\0\0\x02\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x1e\0\0\0\x57\x03\0\0\
+\x03\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\
+\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x10\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\
+\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x03\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\
+\x1d\0\0\0\x57\x03\0\0\x07\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\
+\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x08\x15\x02\x09\0\0\0\0\
+\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x04\0\0\0\x61\x13\0\
+\0\0\0\0\0\x77\x03\0\0\x1c\0\0\0\x57\x03\0\0\x0f\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\
+\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x04\
+\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\
+\x05\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x1b\0\0\0\x57\x03\0\0\x1f\0\0\0\x4f\
+\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\
+\x57\x02\0\0\0\0\0\x02\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\
+\0\0\0\0\0\x67\x02\0\0\x06\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x1a\0\0\0\x57\
+\x03\0\0\x3f\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\
+\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x01\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\
+\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x07\0\0\0\x61\x13\0\0\0\0\0\0\x77\
+\x03\0\0\x19\0\0\0\x57\x03\0\0\x7f\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\
+\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\0\0\x80\0\x15\x02\x09\0\
+\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x08\0\0\0\x61\
+\x13\0\0\0\0\0\0\x77\x03\0\0\x18\0\0\0\x57\x03\0\0\xff\0\0\0\x4f\x32\0\0\0\0\0\
+\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\0\0\
+\x40\0\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\
+\x02\0\0\x09\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x17\0\0\0\x57\x03\0\0\xff\
+\x01\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\
+\0\0\0\0\0\x57\x02\0\0\0\0\x20\0\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\
+\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x0a\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x16\
+\0\0\0\x57\x03\0\0\xff\x03\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\
+\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\0\0\x10\0\x15\x02\x09\0\0\0\0\0\
+\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x0b\0\0\0\x61\x13\0\0\
+\0\0\0\0\x77\x03\0\0\x15\0\0\0\x57\x03\0\0\xff\x07\0\0\x4f\x32\0\0\0\0\0\0\xaf\
+\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\0\0\x08\0\
+\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\
+\x0c\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x14\0\0\0\x57\x03\0\0\xff\x0f\0\0\
+\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\
+\0\x57\x02\0\0\0\0\x04\0\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\
+\0\0\0\0\0\0\x67\x02\0\0\x0d\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x13\0\0\0\
+\x57\x03\0\0\xff\x1f\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\
+\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\0\0\x02\0\x15\x02\x09\0\0\0\0\0\x79\xa2\
+\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x0e\0\0\0\x61\x13\0\0\0\0\0\0\
+\x77\x03\0\0\x12\0\0\0\x57\x03\0\0\xff\x3f\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\
+\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\0\0\x01\0\x15\x02\
+\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x0f\0\0\
+\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x11\0\0\0\x57\x03\0\0\xff\x7f\0\0\x4f\x32\0\
+\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\
+\0\0\0\x80\0\0\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\
+\0\x67\x02\0\0\x10\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x10\0\0\0\x57\x03\0\0\
+\xff\xff\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x92\0\0\0\0\0\0\x57\x02\0\0\0\x40\0\0\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\
+\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x11\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\
+\0\x0f\0\0\0\x57\x03\0\0\xff\xff\x01\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\
+\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\0\x20\0\0\x15\x02\x09\0\0\
+\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x12\0\0\0\x61\
+\x13\0\0\0\0\0\0\x77\x03\0\0\x0e\0\0\0\x57\x03\0\0\xff\xff\x03\0\x4f\x32\0\0\0\
+\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\
+\0\x10\0\0\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\
+\x67\x02\0\0\x13\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x0d\0\0\0\x57\x03\0\0\
+\xff\xff\x07\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x92\0\0\0\0\0\0\x57\x02\0\0\0\x08\0\0\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\
+\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x14\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\
+\0\x0c\0\0\0\x57\x03\0\0\xff\xff\x0f\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\
+\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\0\x04\0\0\x15\x02\x09\0\0\
+\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x15\0\0\0\x61\
+\x13\0\0\0\0\0\0\x77\x03\0\0\x0b\0\0\0\x57\x03\0\0\xff\xff\x1f\0\x4f\x32\0\0\0\
+\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\
+\0\x02\0\0\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\
+\x67\x02\0\0\x16\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x0a\0\0\0\x57\x03\0\0\
+\xff\xff\x3f\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x92\0\0\0\0\0\0\x57\x02\0\0\0\x01\0\0\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\
+\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x17\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\
+\0\x09\0\0\0\x57\x03\0\0\xff\xff\x7f\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\
+\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\x80\0\0\0\x15\x02\x09\0\0\
+\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x18\0\0\0\x61\
+\x13\0\0\0\0\0\0\x77\x03\0\0\x08\0\0\0\x57\x03\0\0\xff\xff\xff\0\x4f\x32\0\0\0\
+\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\
+\x40\0\0\0\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\
+\x67\x02\0\0\x19\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x07\0\0\0\x57\x03\0\0\
+\xff\xff\xff\x01\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\
+\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\x20\0\0\0\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\
+\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x1a\0\0\0\x61\x13\0\0\0\0\0\0\x77\
+\x03\0\0\x06\0\0\0\x57\x03\0\0\xff\xff\xff\x03\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\
+\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\x10\0\0\0\x15\x02\
+\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x1b\0\0\
+\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x05\0\0\0\x57\x03\0\0\xff\xff\xff\x07\x4f\
+\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\
+\x57\x02\0\0\x08\0\0\0\x15\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\
+\0\0\0\0\0\x67\x02\0\0\x1c\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x04\0\0\0\x57\
+\x03\0\0\xff\xff\xff\x0f\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\
+\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\x04\0\0\0\x15\x02\x09\0\0\0\0\0\x79\xa2\
+\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x1d\0\0\0\x61\x13\0\0\0\0\0\0\
+\x77\x03\0\0\x03\0\0\0\x57\x03\0\0\xff\xff\xff\x1f\x4f\x32\0\0\0\0\0\0\xaf\x52\
+\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x57\x02\0\0\x02\0\0\0\x15\
+\x02\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x1e\
+\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x02\0\0\0\x57\x03\0\0\xff\xff\xff\x3f\
+\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\x57\x09\0\0\x01\0\
+\0\0\x15\x09\x09\0\0\0\0\0\x79\xa2\x98\xff\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\
+\0\0\x1f\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x01\0\0\0\x57\x03\0\0\xff\xff\
+\xff\x7f\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\x07\x04\0\
+\0\x0c\0\0\0\xbf\x82\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x40\x15\x02\x08\0\0\0\0\0\
+\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x01\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x1f\
+\0\0\0\x57\x03\0\0\x01\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\
+\0\0\0\0\0\xbf\x82\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x20\x15\x02\x08\0\0\0\0\0\x61\
+\x12\0\0\0\0\0\0\x67\x02\0\0\x02\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x1e\0\0\
+\0\x57\x03\0\0\x03\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\
+\0\0\0\xbf\x82\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x10\x15\x02\x08\0\0\0\0\0\x61\x12\
+\0\0\0\0\0\0\x67\x02\0\0\x03\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x1d\0\0\0\
+\x57\x03\0\0\x07\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\
+\0\0\xbf\x82\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x08\x15\x02\x08\0\0\0\0\0\x61\x12\0\
+\0\0\0\0\0\x67\x02\0\0\x04\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x1c\0\0\0\x57\
+\x03\0\0\x0f\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\
+\xbf\x82\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x04\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\
+\0\0\0\x67\x02\0\0\x05\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x1b\0\0\0\x57\x03\
+\0\0\x1f\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x02\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x06\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x1a\0\0\0\x57\x03\0\0\
+\x3f\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x82\
+\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x01\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\0\
+\x67\x02\0\0\x07\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x19\0\0\0\x57\x03\0\0\
+\x7f\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x82\
+\0\0\0\0\0\0\x57\x02\0\0\0\0\x80\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\0\
+\x67\x02\0\0\x08\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x18\0\0\0\x57\x03\0\0\
+\xff\0\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\x82\
+\0\0\0\0\0\0\x57\x02\0\0\0\0\x40\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\0\
+\x67\x02\0\0\x09\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x17\0\0\0\x57\x03\0\0\
+\xff\x01\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\0\x20\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x0a\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x16\0\0\0\x57\x03\0\0\
+\xff\x03\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\0\x10\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x0b\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x15\0\0\0\x57\x03\0\0\
+\xff\x07\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\0\x08\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x0c\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x14\0\0\0\x57\x03\0\0\
+\xff\x0f\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\0\x04\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x0d\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x13\0\0\0\x57\x03\0\0\
+\xff\x1f\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\0\x02\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x0e\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x12\0\0\0\x57\x03\0\0\
+\xff\x3f\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\0\x01\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x0f\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x11\0\0\0\x57\x03\0\0\
+\xff\x7f\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\x80\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x10\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x10\0\0\0\x57\x03\0\0\
+\xff\xff\0\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\x40\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x11\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x0f\0\0\0\x57\x03\0\0\
+\xff\xff\x01\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\x20\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x12\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x0e\0\0\0\x57\x03\0\0\
+\xff\xff\x03\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\x10\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x13\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x0d\0\0\0\x57\x03\0\0\
+\xff\xff\x07\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\x08\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x14\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x0c\0\0\0\x57\x03\0\0\
+\xff\xff\x0f\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\x04\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x15\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x0b\0\0\0\x57\x03\0\0\
+\xff\xff\x1f\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\x02\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x16\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x0a\0\0\0\x57\x03\0\0\
+\xff\xff\x3f\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\0\x01\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x17\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x09\0\0\0\x57\x03\0\0\
+\xff\xff\x7f\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\x80\0\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x18\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x08\0\0\0\x57\x03\0\0\
+\xff\xff\xff\0\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\xbf\
+\x82\0\0\0\0\0\0\x57\x02\0\0\x40\0\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\
+\0\x67\x02\0\0\x19\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x07\0\0\0\x57\x03\0\0\
+\xff\xff\xff\x01\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\0\
+\xbf\x82\0\0\0\0\0\0\x57\x02\0\0\x20\0\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\
+\0\0\0\x67\x02\0\0\x1a\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x06\0\0\0\x57\x03\
+\0\0\xff\xff\xff\x03\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\0\0\
+\0\xbf\x82\0\0\0\0\0\0\x57\x02\0\0\x10\0\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\
+\0\0\0\0\x67\x02\0\0\x1b\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x05\0\0\0\x57\
+\x03\0\0\xff\xff\xff\x07\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\0\0\
+\0\0\0\xbf\x82\0\0\0\0\0\0\x57\x02\0\0\x08\0\0\0\x15\x02\x08\0\0\0\0\0\x61\x12\
+\0\0\0\0\0\0\x67\x02\0\0\x1c\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x04\0\0\0\
+\x57\x03\0\0\xff\xff\xff\x0f\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\0\
+\0\0\0\0\0\xbf\x82\0\0\0\0\0\0\x57\x02\0\0\x04\0\0\0\x15\x02\x08\0\0\0\0\0\x61\
+\x12\0\0\0\0\0\0\x67\x02\0\0\x1d\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x03\0\0\
+\0\x57\x03\0\0\xff\xff\xff\x1f\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x25\
+\0\0\0\0\0\0\xbf\x82\0\0\0\0\0\0\x57\x02\0\0\x02\0\0\0\x15\x02\x08\0\0\0\0\0\
+\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x1e\0\0\0\x61\x43\0\0\0\0\0\0\x77\x03\0\0\x02\
+\0\0\0\x57\x03\0\0\xff\xff\xff\x3f\x4f\x32\0\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\
+\x25\0\0\0\0\0\0\x7b\x5a\x90\xff\0\0\0\0\x57\x08\0\0\x01\0\0\0\x15\x08\xae\x1b\
+\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x1f\0\0\0\x61\x42\0\0\0\0\0\0\x05\0\
+\xe0\x0a\0\0\0\0\x7b\x3a\x98\xff\0\0\0\0\x7b\x0a\x78\xff\0\0\0\0\x71\x26\x03\0\
+\0\0\0\0\xbf\x71\0\0\0\0\0\0\x71\x27\x02\0\0\0\0\0\x71\x28\0\0\0\0\0\0\x7b\x2a\
+\x80\xff\0\0\0\0\x71\x29\x01\0\0\0\0\0\xb7\x02\0\0\0\0\0\0\x7b\x2a\x90\xff\0\0\
+\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xd8\xff\xff\xff\x7b\x1a\x88\xff\0\0\0\0\
+\xb7\x04\0\0\x28\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x55\0\x99\x1b\
+\0\0\0\0\x67\x09\0\0\x08\0\0\0\x4f\x89\0\0\0\0\0\0\x67\x07\0\0\x10\0\0\0\x67\
+\x06\0\0\x18\0\0\0\x4f\x76\0\0\0\0\0\0\x4f\x96\0\0\0\0\0\0\x61\xa1\xfc\xff\0\0\
+\0\0\xdc\x01\0\0\x20\0\0\0\x7b\x1a\x68\xff\0\0\0\0\x61\xa1\xec\xff\0\0\0\0\xdc\
+\x01\0\0\x20\0\0\0\x7b\x1a\x70\xff\0\0\0\0\x61\xa0\xf8\xff\0\0\0\0\xdc\0\0\0\
+\x20\0\0\0\x61\xa1\xe8\xff\0\0\0\0\xdc\x01\0\0\x20\0\0\0\x7b\x1a\xa0\xff\0\0\0\
+\0\x61\xa1\xf4\xff\0\0\0\0\xdc\x01\0\0\x20\0\0\0\x7b\x1a\x58\xff\0\0\0\0\x61\
+\xa7\xe4\xff\0\0\0\0\xdc\x07\0\0\x20\0\0\0\x61\xa1\xf0\xff\0\0\0\0\xdc\x01\0\0\
+\x20\0\0\0\x7b\x1a\x60\xff\0\0\0\0\x61\xa9\xe0\xff\0\0\0\0\xdc\x09\0\0\x20\0\0\
+\0\x57\x06\0\0\x04\0\0\0\x15\x06\xd3\x0e\0\0\0\0\x79\xa2\x78\xff\0\0\0\0\x07\
+\x02\0\0\x08\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x40\xb7\x08\0\0\0\0\0\
+\0\x79\xa4\x98\xff\0\0\0\0\x15\x01\x06\0\0\0\0\0\x61\x48\0\0\0\0\0\0\x67\x08\0\
+\0\x01\0\0\0\x61\x21\0\0\0\0\0\0\x77\x01\0\0\x1f\0\0\0\x57\x01\0\0\x01\0\0\0\
+\x4f\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x20\x79\xa6\x58\xff\
+\0\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\x02\0\0\0\x61\
+\x23\0\0\0\0\0\0\x77\x03\0\0\x1e\0\0\0\x57\x03\0\0\x03\0\0\0\x4f\x31\0\0\0\0\0\
+\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\
+\0\x10\x79\xa5\x60\xff\0\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\
+\x01\0\0\x03\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1d\0\0\0\x57\x03\0\0\x07\0\
+\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\
+\0\0\0\x57\x01\0\0\0\0\0\x08\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\
+\0\0\x04\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1c\0\0\0\x57\x03\0\0\x0f\0\0\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\0\x04\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x05\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1b\0\0\0\x57\x03\0\0\x1f\0\0\0\x4f\
+\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\
+\x57\x01\0\0\0\0\0\x02\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x06\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1a\0\0\0\x57\x03\0\0\x3f\0\0\0\x4f\
+\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\
+\x57\x01\0\0\0\0\0\x01\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x07\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x19\0\0\0\x57\x03\0\0\x7f\0\0\0\x4f\
+\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\
+\x57\x01\0\0\0\0\x80\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x08\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x18\0\0\0\x57\x03\0\0\xff\0\0\0\x4f\
+\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\
+\x57\x01\0\0\0\0\x40\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x09\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x17\0\0\0\x57\x03\0\0\xff\x01\0\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\x20\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x0a\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x16\0\0\0\x57\x03\0\0\xff\x03\0\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\x10\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x0b\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x15\0\0\0\x57\x03\0\0\xff\x07\0\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\x08\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x0c\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x14\0\0\0\x57\x03\0\0\xff\x0f\0\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\x04\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x0d\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x13\0\0\0\x57\x03\0\0\xff\x1f\0\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\x02\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x0e\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x12\0\0\0\x57\x03\0\0\xff\x3f\0\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\x01\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x0f\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x11\0\0\0\x57\x03\0\0\xff\x7f\0\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\x80\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x10\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x10\0\0\0\x57\x03\0\0\xff\xff\0\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\x40\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x11\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0f\0\0\0\x57\x03\0\0\xff\xff\x01\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\x20\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x12\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0e\0\0\0\x57\x03\0\0\xff\xff\x03\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\x10\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x13\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0d\0\0\0\x57\x03\0\0\xff\xff\x07\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\x08\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x14\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0c\0\0\0\x57\x03\0\0\xff\xff\x0f\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\x04\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x15\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0b\0\0\0\x57\x03\0\0\xff\xff\x1f\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\x02\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x16\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0a\0\0\0\x57\x03\0\0\xff\xff\x3f\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\0\x01\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x17\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x09\0\0\0\x57\x03\0\0\xff\xff\x7f\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\x80\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x18\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x08\0\0\0\x57\x03\0\0\xff\xff\xff\0\
+\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\
+\0\x57\x01\0\0\x40\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\
+\x19\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x07\0\0\0\x57\x03\0\0\xff\xff\xff\
+\x01\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\
+\0\0\0\x57\x01\0\0\x20\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\
+\0\0\x1a\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x06\0\0\0\x57\x03\0\0\xff\xff\
+\xff\x03\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\
+\0\0\0\0\0\x57\x01\0\0\x10\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\
+\x01\0\0\x1b\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x05\0\0\0\x57\x03\0\0\xff\
+\xff\xff\x07\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\x08\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x1c\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x04\0\0\0\x57\x03\0\0\
+\xff\xff\xff\x0f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\
+\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\x04\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\
+\0\0\0\x67\x01\0\0\x1d\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x03\0\0\0\x57\x03\
+\0\0\xff\xff\xff\x1f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\
+\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\x02\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\
+\0\0\0\0\x67\x01\0\0\x1e\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x02\0\0\0\x57\
+\x03\0\0\xff\xff\xff\x3f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\
+\0\0\0\x57\x09\0\0\x01\0\0\0\x15\x09\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\
+\0\0\x1f\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x01\0\0\0\x57\x03\0\0\xff\xff\
+\xff\x7f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\x79\xa1\
+\x78\xff\0\0\0\0\x07\x01\0\0\x0c\0\0\0\xbf\x73\0\0\0\0\0\0\x57\x03\0\0\0\0\0\
+\x40\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x01\0\0\0\x61\x14\0\
+\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\0\0\x01\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\
+\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x20\
+\x79\xa9\x70\xff\0\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x02\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\x03\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x10\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x03\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\x07\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x08\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x04\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\x0f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x04\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x05\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\x1f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x02\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x06\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\x3f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x01\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x07\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\x7f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\x80\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x08\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\xff\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\x40\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x09\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\xff\x01\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x20\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x0a\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\xff\x03\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x10\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x0b\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\xff\x07\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x08\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x0c\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\xff\x0f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x04\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x0d\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\xff\x1f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x02\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x0e\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\xff\x3f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x01\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x0f\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\xff\x7f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x80\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x10\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\xff\xff\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x40\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x11\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\xff\xff\x01\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x20\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x12\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0e\0\0\0\x57\x04\0\0\xff\xff\x03\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x10\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x13\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\xff\xff\x07\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x08\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x14\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\xff\xff\x0f\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x04\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x15\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\xff\xff\x1f\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x02\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x16\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\xff\xff\x3f\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x01\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x17\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\xff\xff\x7f\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\x80\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x18\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\xff\xff\xff\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\x40\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x19\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\xff\xff\xff\
+\x01\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\
+\0\0\0\x57\x03\0\0\x20\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\
+\0\0\x1a\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\0\0\xff\xff\
+\xff\x03\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\
+\0\0\0\0\0\x57\x03\0\0\x10\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\
+\x03\0\0\x1b\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\x04\0\0\xff\
+\xff\xff\x07\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x73\0\0\0\0\0\0\x57\x03\0\0\x08\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x1c\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\0\x57\x04\0\0\
+\xff\xff\xff\x0f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\xbf\x73\0\0\0\0\0\0\x57\x03\0\0\x04\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\
+\0\0\0\x67\x03\0\0\x1d\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x03\0\0\0\x57\x04\
+\0\0\xff\xff\xff\x1f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\
+\0\xbf\x73\0\0\0\0\0\0\x57\x03\0\0\x02\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\
+\0\0\0\0\x67\x03\0\0\x1e\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x02\0\0\0\x57\
+\x04\0\0\xff\xff\xff\x3f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\
+\0\0\0\x57\x07\0\0\x01\0\0\0\x15\x07\x08\0\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\
+\0\0\x1f\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x01\0\0\0\x57\x03\0\0\xff\xff\
+\xff\x7f\x4f\x32\0\0\0\0\0\0\xaf\x82\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\x79\xa7\
+\x78\xff\0\0\0\0\xbf\x72\0\0\0\0\0\0\x07\x02\0\0\x10\0\0\0\x79\xa3\xa0\xff\0\0\
+\0\0\x57\x03\0\0\0\0\0\x40\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\
+\0\x01\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\0\0\x01\0\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\
+\0\0\0\x57\x03\0\0\0\0\0\x20\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\
+\0\0\x02\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\x03\0\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\
+\0\0\0\x57\x03\0\0\0\0\0\x10\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\
+\0\0\x03\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\x07\0\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\
+\0\0\0\x57\x03\0\0\0\0\0\x08\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\
+\0\0\x04\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\x0f\0\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\
+\0\0\0\x57\x03\0\0\0\0\0\x04\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\
+\0\0\x05\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\x1f\0\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\
+\0\0\0\x57\x03\0\0\0\0\0\x02\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\
+\0\0\x06\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\x3f\0\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\
+\0\0\0\x57\x03\0\0\0\0\0\x01\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\
+\0\0\x07\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\x7f\0\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\
+\0\0\0\x57\x03\0\0\0\0\x80\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\
+\0\0\x08\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\xff\0\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\
+\0\0\0\x57\x03\0\0\0\0\x40\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\
+\0\0\x09\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\xff\x01\0\
+\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\
+\0\0\0\0\x57\x03\0\0\0\0\x20\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\
+\x03\0\0\x0a\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\xff\
+\x03\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\
+\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\x10\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0b\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\
+\xff\x07\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\
+\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\x08\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\
+\0\0\0\x67\x03\0\0\x0c\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x14\0\0\0\x57\x04\
+\0\0\xff\x0f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\x04\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\
+\0\0\0\0\0\x67\x03\0\0\x0d\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x13\0\0\0\x57\
+\x04\0\0\xff\x1f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\
+\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\x02\0\x15\x03\x08\0\0\0\0\0\x61\x13\
+\0\0\0\0\0\0\x67\x03\0\0\x0e\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x12\0\0\0\
+\x57\x04\0\0\xff\x3f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\
+\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\x01\0\x15\x03\x08\0\0\0\0\0\x61\
+\x13\0\0\0\0\0\0\x67\x03\0\0\x0f\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x11\0\0\
+\0\x57\x04\0\0\xff\x7f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\
+\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\x80\0\0\x15\x03\x08\0\0\0\0\0\
+\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x10\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x10\
+\0\0\0\x57\x04\0\0\xff\xff\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\
+\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\x40\0\0\x15\x03\x08\0\0\0\0\
+\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x11\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\
+\x0f\0\0\0\x57\x04\0\0\xff\xff\x01\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\
+\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\x20\0\0\x15\x03\x08\
+\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x12\0\0\0\x61\x24\0\0\0\0\0\0\x77\
+\x04\0\0\x0e\0\0\0\x57\x04\0\0\xff\xff\x03\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\
+\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\x10\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x13\0\0\0\x61\x24\0\0\0\0\0\
+\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\xff\xff\x07\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\x08\0\0\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x14\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\xff\xff\x0f\0\x4f\x43\0\0\0\0\0\0\xaf\
+\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\x04\
+\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x15\0\0\0\x61\x24\0\
+\0\0\0\0\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\xff\xff\x1f\0\x4f\x43\0\0\0\0\0\0\
+\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\
+\x02\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x16\0\0\0\x61\
+\x24\0\0\0\0\0\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\xff\xff\x3f\0\x4f\x43\0\0\0\
+\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\
+\0\0\0\x01\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x17\0\0\0\
+\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\xff\xff\x7f\0\x4f\x43\0\
+\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\
+\x03\0\0\x80\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x18\0\
+\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\xff\xff\xff\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\
+\0\x57\x03\0\0\x40\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x19\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\xff\xff\xff\
+\x01\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\
+\xff\0\0\0\0\x57\x03\0\0\x20\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x1a\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\0\0\
+\xff\xff\xff\x03\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\x10\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\
+\0\0\0\0\0\x67\x03\0\0\x1b\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\
+\x04\0\0\xff\xff\xff\x07\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\
+\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\x08\0\0\0\x15\x03\x08\0\0\0\0\0\x61\
+\x13\0\0\0\0\0\0\x67\x03\0\0\x1c\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\
+\0\x57\x04\0\0\xff\xff\xff\x0f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\
+\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\x04\0\0\0\x15\x03\x08\0\0\0\0\
+\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x1d\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\
+\x03\0\0\0\x57\x04\0\0\xff\xff\xff\x1f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\
+\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\x02\0\0\0\x15\x03\x08\
+\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x1e\0\0\0\x61\x24\0\0\0\0\0\0\x77\
+\x04\0\0\x02\0\0\0\x57\x04\0\0\xff\xff\xff\x3f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\
+\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\x01\0\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x1f\0\0\0\x61\x23\0\0\0\0\0\
+\0\x77\x03\0\0\x01\0\0\0\x57\x03\0\0\xff\xff\xff\x7f\x4f\x31\0\0\0\0\0\0\xaf\
+\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x71\0\0\0\0\0\0\x07\x01\0\0\x14\0\0\0\
+\xbf\x93\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x40\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\
+\0\0\0\x67\x03\0\0\x01\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\
+\0\0\x01\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x20\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x02\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\
+\x03\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x93\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x10\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x03\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\
+\x07\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x93\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x08\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x04\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\
+\x0f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x93\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x04\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x05\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\
+\x1f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x93\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x02\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x06\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\
+\x3f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x93\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x01\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x07\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\
+\x7f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x93\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\x80\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x08\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\
+\xff\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x93\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\x40\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x09\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\
+\xff\x01\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\0\x20\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0a\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\
+\xff\x03\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\0\x10\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0b\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\
+\xff\x07\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\0\x08\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0c\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\
+\xff\x0f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\0\x04\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0d\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\
+\xff\x1f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\0\x02\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0e\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\
+\xff\x3f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\0\x01\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0f\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\
+\xff\x7f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\x80\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x10\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\
+\xff\xff\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\x40\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x11\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\
+\xff\xff\x01\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\x20\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x12\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0e\0\0\0\x57\x04\0\0\
+\xff\xff\x03\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\x10\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x13\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\
+\xff\xff\x07\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\x08\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x14\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\
+\xff\xff\x0f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\x04\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x15\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\
+\xff\xff\x1f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\x02\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x16\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\
+\xff\xff\x3f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\0\x01\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x17\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\
+\xff\xff\x7f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\x80\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x18\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\
+\xff\xff\xff\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x93\0\0\0\0\0\0\x57\x03\0\0\x40\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x19\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\
+\xff\xff\xff\x01\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\xbf\x93\0\0\0\0\0\0\x57\x03\0\0\x20\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\
+\0\0\0\x67\x03\0\0\x1a\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\
+\0\0\xff\xff\xff\x03\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\
+\0\xbf\x93\0\0\0\0\0\0\x57\x03\0\0\x10\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\
+\0\0\0\0\x67\x03\0\0\x1b\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\
+\x04\0\0\xff\xff\xff\x07\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\
+\0\0\0\xbf\x93\0\0\0\0\0\0\x57\x03\0\0\x08\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\
+\0\0\0\0\0\0\x67\x03\0\0\x1c\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\0\
+\x57\x04\0\0\xff\xff\xff\x0f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\
+\0\0\0\0\0\xbf\x93\0\0\0\0\0\0\x57\x03\0\0\x04\0\0\0\x15\x03\x08\0\0\0\0\0\x61\
+\x23\0\0\0\0\0\0\x67\x03\0\0\x1d\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x03\0\0\
+\0\x57\x04\0\0\xff\xff\xff\x1f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\
+\0\0\0\0\0\0\xbf\x93\0\0\0\0\0\0\x57\x03\0\0\x02\0\0\0\x15\x03\x08\0\0\0\0\0\
+\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x1e\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x02\
+\0\0\0\x57\x04\0\0\xff\xff\xff\x3f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\
+\x38\0\0\0\0\0\0\x57\x09\0\0\x01\0\0\0\x15\x09\x08\0\0\0\0\0\x61\x22\0\0\0\0\0\
+\0\x67\x02\0\0\x1f\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x01\0\0\0\x57\x03\0\0\
+\xff\xff\xff\x7f\x4f\x32\0\0\0\0\0\0\xaf\x82\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\
+\xbf\x72\0\0\0\0\0\0\x07\x02\0\0\x18\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\
+\0\x40\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x01\0\0\0\x61\x24\
+\0\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\0\0\x01\0\0\0\x4f\x43\0\0\0\0\0\0\
+\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\0\
+\x20\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x02\0\0\0\x61\x24\0\
+\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\x03\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\
+\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x10\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x03\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\x07\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x08\x15\
+\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x04\0\0\0\x61\x24\0\0\0\0\0\
+\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\x0f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\
+\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x04\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x05\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\x1f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\
+\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x02\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x06\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\x3f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\
+\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x01\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x07\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\x7f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\
+\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\x80\0\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x08\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\xff\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\
+\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\x40\0\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x09\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\xff\x01\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\
+\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\x20\0\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x0a\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\xff\x03\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\
+\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\x10\0\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x0b\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\xff\x07\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\
+\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\x08\0\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x0c\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\xff\x0f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\
+\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\x04\0\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x0d\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\xff\x1f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\
+\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\x02\0\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x0e\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\xff\x3f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\
+\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\0\x01\0\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x0f\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\xff\x7f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\
+\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\x80\0\0\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x10\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\xff\xff\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\
+\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\x40\0\0\x15\x03\
+\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x11\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\xff\xff\x01\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\
+\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\x20\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x12\0\0\0\x61\x24\0\0\0\0\0\
+\0\x77\x04\0\0\x0e\0\0\0\x57\x04\0\0\xff\xff\x03\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\x10\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x13\0\0\0\x61\x24\0\0\0\0\0\
+\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\xff\xff\x07\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\x08\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x14\0\0\0\x61\x24\0\0\0\0\0\
+\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\xff\xff\x0f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\x04\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x15\0\0\0\x61\x24\0\0\0\0\0\
+\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\xff\xff\x1f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\x02\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x16\0\0\0\x61\x24\0\0\0\0\0\
+\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\xff\xff\x3f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\0\x01\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x17\0\0\0\x61\x24\0\0\0\0\0\
+\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\xff\xff\x7f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\x80\0\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x18\0\0\0\x61\x24\0\0\0\0\0\
+\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\xff\xff\xff\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\x40\0\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x19\0\0\0\x61\x24\0\0\0\0\0\
+\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\xff\xff\xff\x01\x4f\x43\0\0\0\0\0\0\xaf\
+\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\x20\0\0\0\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x1a\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\0\0\xff\xff\xff\x03\x4f\x43\0\0\0\0\0\0\
+\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\x10\0\
+\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x1b\0\0\0\x61\x24\0\
+\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\x04\0\0\xff\xff\xff\x07\x4f\x43\0\0\0\0\0\
+\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\x08\
+\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x1c\0\0\0\x61\x24\
+\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\0\x57\x04\0\0\xff\xff\xff\x0f\x4f\x43\0\0\0\0\
+\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\0\
+\x04\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x1d\0\0\0\x61\
+\x24\0\0\0\0\0\0\x77\x04\0\0\x03\0\0\0\x57\x04\0\0\xff\xff\xff\x1f\x4f\x43\0\0\
+\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x53\0\0\0\0\0\0\x57\x03\0\
+\0\x02\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x1e\0\0\0\
+\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x02\0\0\0\x57\x04\0\0\xff\xff\xff\x3f\x4f\x43\
+\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x57\x05\0\0\x01\0\0\0\x15\
+\x05\x08\0\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x1f\0\0\0\x61\x23\0\0\0\0\0\
+\0\x77\x03\0\0\x01\0\0\0\x57\x03\0\0\xff\xff\xff\x7f\x4f\x31\0\0\0\0\0\0\xaf\
+\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x71\0\0\0\0\0\0\x07\x01\0\0\x1c\0\0\0\
+\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x40\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\
+\0\0\0\x67\x03\0\0\x01\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\
+\0\0\x01\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x20\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x02\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\
+\x03\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x10\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x03\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\
+\x07\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x08\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x04\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\
+\x0f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x04\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x05\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\
+\x1f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x02\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x06\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\
+\x3f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x01\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x07\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\
+\x7f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\x80\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x08\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\
+\xff\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\x40\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x09\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\
+\xff\x01\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x20\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0a\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\
+\xff\x03\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x10\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0b\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\
+\xff\x07\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x08\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0c\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\
+\xff\x0f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x04\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0d\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\
+\xff\x1f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x02\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0e\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\
+\xff\x3f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x01\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0f\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\
+\xff\x7f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x80\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x10\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\
+\xff\xff\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x40\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x11\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\
+\xff\xff\x01\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x20\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x12\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0e\0\0\0\x57\x04\0\0\
+\xff\xff\x03\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x10\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x13\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\
+\xff\xff\x07\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x08\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x14\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\
+\xff\xff\x0f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x04\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x15\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\
+\xff\xff\x1f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x02\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x16\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\
+\xff\xff\x3f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x01\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x17\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\
+\xff\xff\x7f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\x80\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x18\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\
+\xff\xff\xff\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\x40\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x19\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\
+\xff\xff\xff\x01\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\x20\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\
+\0\0\0\x67\x03\0\0\x1a\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\
+\0\0\xff\xff\xff\x03\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\
+\0\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\x10\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\
+\0\0\0\0\x67\x03\0\0\x1b\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\
+\x04\0\0\xff\xff\xff\x07\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\
+\0\0\0\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\x08\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\
+\0\0\0\0\0\0\x67\x03\0\0\x1c\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\0\
+\x57\x04\0\0\xff\xff\xff\x0f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\
+\0\0\0\0\0\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\x04\0\0\0\x15\x03\x08\0\0\0\0\0\x61\
+\x23\0\0\0\0\0\0\x67\x03\0\0\x1d\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x03\0\0\
+\0\x57\x04\0\0\xff\xff\xff\x1f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\
+\0\0\0\0\0\0\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\x02\0\0\0\x15\x03\x08\0\0\0\0\0\
+\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x1e\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x02\
+\0\0\0\x57\x04\0\0\xff\xff\xff\x3f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\
+\x38\0\0\0\0\0\0\x57\x06\0\0\x01\0\0\0\x15\x06\x08\0\0\0\0\0\x61\x22\0\0\0\0\0\
+\0\x67\x02\0\0\x1f\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x01\0\0\0\x57\x03\0\0\
+\xff\xff\xff\x7f\x4f\x32\0\0\0\0\0\0\xaf\x82\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\
+\xbf\x72\0\0\0\0\0\0\x07\x02\0\0\x20\0\0\0\xbf\x03\0\0\0\0\0\0\x57\x03\0\0\0\0\
+\0\x40\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x01\0\0\0\x61\x24\
+\0\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\0\0\x01\0\0\0\x4f\x43\0\0\0\0\0\0\
+\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\0\x57\x03\0\0\0\0\0\
+\x20\x79\xa6\x68\xff\0\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\
+\0\0\x02\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\x03\0\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\0\x10\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x03\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\x07\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x08\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x04\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\x0f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x04\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x05\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\x1f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x02\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x06\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\x3f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x01\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x07\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\x7f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\x80\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x08\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\xff\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\x40\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x09\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\xff\x01\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x20\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x0a\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\xff\x03\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x10\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x0b\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\xff\x07\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x08\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x0c\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\xff\x0f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x04\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x0d\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\xff\x1f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x02\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x0e\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\xff\x3f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x01\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x0f\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\xff\x7f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\x80\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x10\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\xff\xff\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\x40\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x11\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\xff\xff\x01\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\x20\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x12\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0e\0\0\0\x57\x04\0\0\xff\xff\x03\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\x10\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x13\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\xff\xff\x07\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\x08\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x14\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\xff\xff\x0f\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\x04\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x15\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\xff\xff\x1f\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\x02\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x16\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\xff\xff\x3f\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\0\x01\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x17\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\xff\xff\x7f\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\x80\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x18\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\xff\xff\xff\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\0\0\
+\0\x57\x03\0\0\x40\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x19\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\xff\xff\xff\
+\x01\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\0\0\
+\0\0\0\x57\x03\0\0\x20\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\
+\0\0\x1a\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\0\0\xff\xff\
+\xff\x03\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x03\0\
+\0\0\0\0\0\x57\x03\0\0\x10\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\
+\x03\0\0\x1b\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\x04\0\0\xff\
+\xff\xff\x07\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x03\0\0\0\0\0\0\x57\x03\0\0\x08\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x1c\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\0\x57\x04\0\0\
+\xff\xff\xff\x0f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\xbf\x03\0\0\0\0\0\0\x57\x03\0\0\x04\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\
+\0\0\0\x67\x03\0\0\x1d\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x03\0\0\0\x57\x04\
+\0\0\xff\xff\xff\x1f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\
+\0\xbf\x03\0\0\0\0\0\0\x57\x03\0\0\x02\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\
+\0\0\0\0\x67\x03\0\0\x1e\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x02\0\0\0\x57\
+\x04\0\0\xff\xff\xff\x3f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\
+\0\0\0\x57\0\0\0\x01\0\0\0\x15\0\x08\0\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\
+\x1f\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x01\0\0\0\x57\x03\0\0\xff\xff\xff\
+\x7f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\x07\x07\0\0\
+\x24\0\0\0\xbf\x61\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x40\x15\x01\x08\0\0\0\0\0\x61\
+\x21\0\0\0\0\0\0\x67\x01\0\0\x01\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x1f\0\0\
+\0\x57\x03\0\0\x01\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\
+\0\0\0\xbf\x61\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x20\x15\x01\x08\0\0\0\0\0\x61\x21\
+\0\0\0\0\0\0\x67\x01\0\0\x02\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x1e\0\0\0\
+\x57\x03\0\0\x03\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\
+\0\0\xbf\x61\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x10\x15\x01\x08\0\0\0\0\0\x61\x21\0\
+\0\0\0\0\0\x67\x01\0\0\x03\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x1d\0\0\0\x57\
+\x03\0\0\x07\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\
+\xbf\x61\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x08\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\
+\0\0\0\x67\x01\0\0\x04\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x1c\0\0\0\x57\x03\
+\0\0\x0f\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x04\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x05\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x1b\0\0\0\x57\x03\0\0\
+\x1f\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x61\
+\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x02\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\
+\x67\x01\0\0\x06\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x1a\0\0\0\x57\x03\0\0\
+\x3f\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x61\
+\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x01\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\
+\x67\x01\0\0\x07\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x19\0\0\0\x57\x03\0\0\
+\x7f\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x61\
+\0\0\0\0\0\0\x57\x01\0\0\0\0\x80\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\
+\x67\x01\0\0\x08\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x18\0\0\0\x57\x03\0\0\
+\xff\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x61\
+\0\0\0\0\0\0\x57\x01\0\0\0\0\x40\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\
+\x67\x01\0\0\x09\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x17\0\0\0\x57\x03\0\0\
+\xff\x01\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\0\x20\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x0a\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x16\0\0\0\x57\x03\0\0\
+\xff\x03\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\0\x10\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x0b\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x15\0\0\0\x57\x03\0\0\
+\xff\x07\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\0\x08\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x0c\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x14\0\0\0\x57\x03\0\0\
+\xff\x0f\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\0\x04\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x0d\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x13\0\0\0\x57\x03\0\0\
+\xff\x1f\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\0\x02\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x0e\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x12\0\0\0\x57\x03\0\0\
+\xff\x3f\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\0\x01\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x0f\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x11\0\0\0\x57\x03\0\0\
+\xff\x7f\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\x80\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x10\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x10\0\0\0\x57\x03\0\0\
+\xff\xff\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\x40\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x11\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x0f\0\0\0\x57\x03\0\0\
+\xff\xff\x01\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\x20\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x12\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x0e\0\0\0\x57\x03\0\0\
+\xff\xff\x03\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\x10\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x13\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x0d\0\0\0\x57\x03\0\0\
+\xff\xff\x07\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\x08\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x14\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x0c\0\0\0\x57\x03\0\0\
+\xff\xff\x0f\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\x04\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x15\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x0b\0\0\0\x57\x03\0\0\
+\xff\xff\x1f\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\x02\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x16\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x0a\0\0\0\x57\x03\0\0\
+\xff\xff\x3f\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\0\x01\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x17\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x09\0\0\0\x57\x03\0\0\
+\xff\xff\x7f\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\x80\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x18\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x08\0\0\0\x57\x03\0\0\
+\xff\xff\xff\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x61\0\0\0\0\0\0\x57\x01\0\0\x40\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x19\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x07\0\0\0\x57\x03\0\0\
+\xff\xff\xff\x01\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\
+\xbf\x61\0\0\0\0\0\0\x57\x01\0\0\x20\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\
+\0\0\0\x67\x01\0\0\x1a\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x06\0\0\0\x57\x03\
+\0\0\xff\xff\xff\x03\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\
+\0\xbf\x61\0\0\0\0\0\0\x57\x01\0\0\x10\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\
+\0\0\0\0\x67\x01\0\0\x1b\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x05\0\0\0\x57\
+\x03\0\0\xff\xff\xff\x07\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\
+\0\0\0\xbf\x61\0\0\0\0\0\0\x57\x01\0\0\x08\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\
+\0\0\0\0\0\0\x67\x01\0\0\x1c\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x04\0\0\0\
+\x57\x03\0\0\xff\xff\xff\x0f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\
+\0\0\0\0\0\xbf\x61\0\0\0\0\0\0\x57\x01\0\0\x04\0\0\0\x15\x01\x08\0\0\0\0\0\x61\
+\x21\0\0\0\0\0\0\x67\x01\0\0\x1d\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x03\0\0\
+\0\x57\x03\0\0\xff\xff\xff\x1f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\
+\0\0\0\0\0\0\xbf\x61\0\0\0\0\0\0\x57\x01\0\0\x02\0\0\0\x15\x01\x08\0\0\0\0\0\
+\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x1e\0\0\0\x61\x73\0\0\0\0\0\0\x77\x03\0\0\x02\
+\0\0\0\x57\x03\0\0\xff\xff\xff\x3f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\
+\x18\0\0\0\0\0\0\x7b\x8a\x90\xff\0\0\0\0\xbf\x75\0\0\0\0\0\0\x57\x06\0\0\x01\0\
+\0\0\x15\x06\xcd\x10\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x1f\0\0\0\x61\x52\
+\0\0\0\0\0\0\x77\x02\0\0\x01\0\0\0\x57\x02\0\0\xff\xff\xff\x7f\x4f\x21\0\0\0\0\
+\0\0\x79\xa2\x90\xff\0\0\0\0\xaf\x21\0\0\0\0\0\0\x7b\x1a\x90\xff\0\0\0\0\x05\0\
+\xc3\x10\0\0\0\0\x69\xa1\xde\xff\0\0\0\0\x57\x01\0\0\x3f\xff\0\0\x55\x01\xc0\
+\x10\0\0\0\0\x71\xa1\xe1\xff\0\0\0\0\x15\x01\x01\0\x11\0\0\0\x55\x01\xbd\x10\
+\x06\0\0\0\x71\xa2\xd8\xff\0\0\0\0\x67\x02\0\0\x02\0\0\0\x57\x02\0\0\x3c\0\0\0\
+\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xd0\xff\xff\xff\x79\xa1\x88\xff\0\0\0\0\xb7\
+\x04\0\0\x04\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\xb7\x07\0\0\0\0\0\
+\0\x55\0\x07\x04\0\0\0\0\x79\xa6\x78\xff\0\0\0\0\xbf\x62\0\0\0\0\0\0\x07\x02\0\
+\0\x08\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x40\x79\xa4\x98\xff\0\0\0\0\
+\x15\x01\x07\0\0\0\0\0\x61\x41\0\0\0\0\0\0\x67\x01\0\0\x01\0\0\0\x61\x23\0\0\0\
+\0\0\0\x77\x03\0\0\x1f\0\0\0\x57\x03\0\0\x01\0\0\0\x4f\x31\0\0\0\0\0\0\xbf\x17\
+\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x20\x15\x01\x08\0\0\0\0\0\
+\x61\x41\0\0\0\0\0\0\x67\x01\0\0\x02\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1e\
+\0\0\0\x57\x03\0\0\x03\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\
+\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x10\x15\x01\x08\0\0\0\0\0\x61\
+\x41\0\0\0\0\0\0\x67\x01\0\0\x03\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1d\0\0\
+\0\x57\x03\0\0\x07\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\
+\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x08\x15\x01\x08\0\0\0\0\0\x61\x41\
+\0\0\0\0\0\0\x67\x01\0\0\x04\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1c\0\0\0\
+\x57\x03\0\0\x0f\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\
+\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x04\x15\x01\x08\0\0\0\0\0\x61\x41\0\
+\0\0\0\0\0\x67\x01\0\0\x05\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1b\0\0\0\x57\
+\x03\0\0\x1f\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\
+\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x02\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\
+\0\0\0\x67\x01\0\0\x06\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1a\0\0\0\x57\x03\
+\0\0\x3f\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x01\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x07\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x19\0\0\0\x57\x03\0\0\
+\x7f\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\x91\
+\0\0\0\0\0\0\x57\x01\0\0\0\0\x80\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\
+\x67\x01\0\0\x08\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x18\0\0\0\x57\x03\0\0\
+\xff\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\x91\
+\0\0\0\0\0\0\x57\x01\0\0\0\0\x40\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\0\
+\x67\x01\0\0\x09\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x17\0\0\0\x57\x03\0\0\
+\xff\x01\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\x20\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x0a\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x16\0\0\0\x57\x03\0\0\
+\xff\x03\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\x10\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x0b\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x15\0\0\0\x57\x03\0\0\
+\xff\x07\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\x08\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x0c\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x14\0\0\0\x57\x03\0\0\
+\xff\x0f\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\x04\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x0d\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x13\0\0\0\x57\x03\0\0\
+\xff\x1f\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\x02\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x0e\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x12\0\0\0\x57\x03\0\0\
+\xff\x3f\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\x01\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x0f\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x11\0\0\0\x57\x03\0\0\
+\xff\x7f\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\x80\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x10\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x10\0\0\0\x57\x03\0\0\
+\xff\xff\0\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\x40\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x11\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0f\0\0\0\x57\x03\0\0\
+\xff\xff\x01\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\x20\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x12\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0e\0\0\0\x57\x03\0\0\
+\xff\xff\x03\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\x10\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x13\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0d\0\0\0\x57\x03\0\0\
+\xff\xff\x07\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\x08\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x14\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0c\0\0\0\x57\x03\0\0\
+\xff\xff\x0f\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\x04\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x15\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0b\0\0\0\x57\x03\0\0\
+\xff\xff\x1f\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\x02\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x16\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0a\0\0\0\x57\x03\0\0\
+\xff\xff\x3f\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\x01\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x17\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x09\0\0\0\x57\x03\0\0\
+\xff\xff\x7f\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\x80\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x18\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x08\0\0\0\x57\x03\0\0\
+\xff\xff\xff\0\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\x40\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x19\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x07\0\0\0\x57\x03\0\0\
+\xff\xff\xff\x01\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\
+\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\x20\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\0\
+\0\0\0\x67\x01\0\0\x1a\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x06\0\0\0\x57\x03\
+\0\0\xff\xff\xff\x03\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\
+\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\x10\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\0\0\
+\0\0\0\0\x67\x01\0\0\x1b\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x05\0\0\0\x57\
+\x03\0\0\xff\xff\xff\x07\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\
+\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\x08\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x41\
+\0\0\0\0\0\0\x67\x01\0\0\x1c\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x04\0\0\0\
+\x57\x03\0\0\xff\xff\xff\x0f\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\
+\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\x04\0\0\0\x15\x01\x08\0\0\0\0\0\x61\
+\x41\0\0\0\0\0\0\x67\x01\0\0\x1d\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x03\0\0\
+\0\x57\x03\0\0\xff\xff\xff\x1f\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\
+\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\x02\0\0\0\x15\x01\x08\0\0\0\0\0\
+\x61\x41\0\0\0\0\0\0\x67\x01\0\0\x1e\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x02\
+\0\0\0\x57\x03\0\0\xff\xff\xff\x3f\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\
+\x17\0\0\0\0\0\0\x57\x09\0\0\x01\0\0\0\x15\x09\x08\0\0\0\0\0\x61\x41\0\0\0\0\0\
+\0\x67\x01\0\0\x1f\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x01\0\0\0\x57\x03\0\0\
+\xff\xff\xff\x7f\x4f\x31\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\0\xbf\x17\0\0\0\0\0\0\
+\xbf\x61\0\0\0\0\0\0\x07\x01\0\0\x0c\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\
+\0\x40\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x01\0\0\0\x61\x14\
+\0\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\0\0\x01\0\0\0\x4f\x43\0\0\0\0\0\0\
+\xaf\x73\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\0\
+\x20\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x02\0\0\0\x61\x14\0\
+\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\x03\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\
+\x73\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x10\
+\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x03\0\0\0\x61\x14\0\0\0\
+\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\x07\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\
+\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x08\x15\
+\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x04\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\x0f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\
+\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x04\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x05\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\x1f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\0\
+\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x02\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x06\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\x3f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\0\
+\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x01\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x07\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\x7f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\0\
+\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\x80\0\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x08\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\xff\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\0\
+\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\x40\0\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x09\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\xff\x01\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\
+\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\x20\0\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x0a\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\xff\x03\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\
+\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\x10\0\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x0b\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\xff\x07\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\
+\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\x08\0\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x0c\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\xff\x0f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\
+\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\x04\0\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x0d\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\xff\x1f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\
+\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\x02\0\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x0e\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\xff\x3f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\
+\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\0\x01\0\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x0f\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\xff\x7f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\
+\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\x80\0\0\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x10\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\xff\xff\0\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\0\
+\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\x40\0\0\x15\x03\
+\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x11\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\xff\xff\x01\0\x4f\x43\0\0\0\0\0\0\xaf\x73\0\
+\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\x20\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x12\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x0e\0\0\0\x57\x04\0\0\xff\xff\x03\0\x4f\x43\0\0\0\0\0\0\xaf\x73\
+\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\x10\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x13\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\xff\xff\x07\0\x4f\x43\0\0\0\0\0\0\xaf\x73\
+\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\x08\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x14\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\xff\xff\x0f\0\x4f\x43\0\0\0\0\0\0\xaf\x73\
+\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\x04\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x15\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\xff\xff\x1f\0\x4f\x43\0\0\0\0\0\0\xaf\x73\
+\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\x02\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x16\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\xff\xff\x3f\0\x4f\x43\0\0\0\0\0\0\xaf\x73\
+\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\0\x01\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x17\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\xff\xff\x7f\0\x4f\x43\0\0\0\0\0\0\xaf\x73\
+\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\x80\0\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x18\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\xff\xff\xff\0\x4f\x43\0\0\0\0\0\0\xaf\x73\
+\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\x40\0\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x19\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\xff\xff\xff\x01\x4f\x43\0\0\0\0\0\0\xaf\
+\x73\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\x20\0\0\0\
+\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x1a\0\0\0\x61\x14\0\0\0\
+\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\0\0\xff\xff\xff\x03\x4f\x43\0\0\0\0\0\0\
+\xaf\x73\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\xbf\x83\0\0\0\0\0\0\x57\x03\0\0\x10\0\
+\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x1b\0\0\0\x61\x14\0\
+\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\x04\0\0\xff\xff\xff\x07\x4f\x43\0\0\0\0\0\
+\0\xaf\x73\0\0\0\0\0\0\xbf\x37\0\0\0\0\0\0\x69\xa3\xd2\xff\0\0\0\0\xbf\x84\0\0\
+\0\0\0\0\x57\x04\0\0\x08\0\0\0\x15\x04\x08\0\0\0\0\0\x61\x24\0\0\0\0\0\0\x67\
+\x04\0\0\x1c\0\0\0\x61\x15\0\0\0\0\0\0\x77\x05\0\0\x04\0\0\0\x57\x05\0\0\xff\
+\xff\xff\x0f\x4f\x54\0\0\0\0\0\0\xaf\x74\0\0\0\0\0\0\xbf\x47\0\0\0\0\0\0\x67\
+\x03\0\0\x10\0\0\0\x69\xa4\xd0\xff\0\0\0\0\xbf\x85\0\0\0\0\0\0\x57\x05\0\0\x04\
+\0\0\0\x15\x05\x08\0\0\0\0\0\x61\x25\0\0\0\0\0\0\x67\x05\0\0\x1d\0\0\0\x61\x10\
+\0\0\0\0\0\0\x77\0\0\0\x03\0\0\0\x57\0\0\0\xff\xff\xff\x1f\x4f\x05\0\0\0\0\0\0\
+\xaf\x75\0\0\0\0\0\0\xbf\x57\0\0\0\0\0\0\x4f\x43\0\0\0\0\0\0\xbf\x84\0\0\0\0\0\
+\0\x57\x04\0\0\x02\0\0\0\x15\x04\x08\0\0\0\0\0\x61\x24\0\0\0\0\0\0\x67\x04\0\0\
+\x1e\0\0\0\x61\x15\0\0\0\0\0\0\x77\x05\0\0\x02\0\0\0\x57\x05\0\0\xff\xff\xff\
+\x3f\x4f\x54\0\0\0\0\0\0\xaf\x74\0\0\0\0\0\0\xbf\x47\0\0\0\0\0\0\xdc\x03\0\0\
+\x20\0\0\0\x57\x08\0\0\x01\0\0\0\x15\x08\x08\0\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\
+\x02\0\0\x1f\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x01\0\0\0\x57\x04\0\0\xff\
+\xff\xff\x7f\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\x27\0\0\0\0\0\0\x07\
+\x06\0\0\x10\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x40\x15\x02\x08\0\0\0\
+\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x01\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x1f\0\0\0\x57\x04\0\0\x01\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x20\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x02\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x1e\0\0\0\x57\x04\0\0\x03\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x10\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x03\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x1d\0\0\0\x57\x04\0\0\x07\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x08\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x04\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x1c\0\0\0\x57\x04\0\0\x0f\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x04\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x05\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x1b\0\0\0\x57\x04\0\0\x1f\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x02\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x06\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x1a\0\0\0\x57\x04\0\0\x3f\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x01\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x07\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x19\0\0\0\x57\x04\0\0\x7f\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\x80\0\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x08\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x18\0\0\0\x57\x04\0\0\xff\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\x40\0\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x09\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x17\0\0\0\x57\x04\0\0\xff\x01\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\x20\0\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x0a\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x16\0\0\0\x57\x04\0\0\xff\x03\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\x10\0\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x0b\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x15\0\0\0\x57\x04\0\0\xff\x07\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\x08\0\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x0c\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x14\0\0\0\x57\x04\0\0\xff\x0f\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\x04\0\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x0d\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x13\0\0\0\x57\x04\0\0\xff\x1f\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\x02\0\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x0e\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x12\0\0\0\x57\x04\0\0\xff\x3f\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\0\x01\0\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x0f\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x11\0\0\0\x57\x04\0\0\xff\x7f\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\x80\0\0\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x10\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x10\0\0\0\x57\x04\0\0\xff\xff\0\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\xbf\
+\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\x40\0\0\x15\x02\x08\0\0\0\0\
+\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x11\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\0\
+\x0f\0\0\0\x57\x04\0\0\xff\xff\x01\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\
+\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\x20\0\0\x15\x02\x08\0\0\
+\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x12\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\
+\0\x0e\0\0\0\x57\x04\0\0\xff\xff\x03\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\
+\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\x10\0\0\x15\x02\x08\0\0\
+\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x13\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\
+\0\x0d\0\0\0\x57\x04\0\0\xff\xff\x07\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\
+\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\x08\0\0\x15\x02\x08\0\0\
+\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x14\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\
+\0\x0c\0\0\0\x57\x04\0\0\xff\xff\x0f\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\
+\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\x04\0\0\x15\x02\x08\0\0\
+\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x15\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\
+\0\x0b\0\0\0\x57\x04\0\0\xff\xff\x1f\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\
+\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\x02\0\0\x15\x02\x08\0\0\
+\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x16\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\
+\0\x0a\0\0\0\x57\x04\0\0\xff\xff\x3f\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\
+\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\0\x01\0\0\x15\x02\x08\0\0\
+\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x17\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\
+\0\x09\0\0\0\x57\x04\0\0\xff\xff\x7f\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\
+\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\x80\0\0\0\x15\x02\x08\0\0\
+\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x18\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\
+\0\x08\0\0\0\x57\x04\0\0\xff\xff\xff\0\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\0\
+\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\x40\0\0\0\x15\x02\x08\0\0\
+\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x19\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\0\
+\0\x07\0\0\0\x57\x04\0\0\xff\xff\xff\x01\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\0\
+\0\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\x20\0\0\0\x15\x02\x08\0\
+\0\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x1a\0\0\0\x61\x64\0\0\0\0\0\0\x77\x04\
+\0\0\x06\0\0\0\x57\x04\0\0\xff\xff\xff\x03\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\0\0\
+\0\0\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\x10\0\0\0\x15\x02\x08\
+\0\0\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x1b\0\0\0\x61\x64\0\0\0\0\0\0\x77\
+\x04\0\0\x05\0\0\0\x57\x04\0\0\xff\xff\xff\x07\x4f\x42\0\0\0\0\0\0\xaf\x72\0\0\
+\0\0\0\0\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\x08\0\0\0\x15\x02\
+\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x1c\0\0\0\x61\x64\0\0\0\0\0\0\
+\x77\x04\0\0\x04\0\0\0\x57\x04\0\0\xff\xff\xff\x0f\x4f\x42\0\0\0\0\0\0\xaf\x72\
+\0\0\0\0\0\0\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\x04\0\0\0\x15\
+\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x1d\0\0\0\x61\x64\0\0\0\0\0\
+\0\x77\x04\0\0\x03\0\0\0\x57\x04\0\0\xff\xff\xff\x1f\x4f\x42\0\0\0\0\0\0\xaf\
+\x72\0\0\0\0\0\0\xbf\x27\0\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\x57\x02\0\0\x02\0\0\0\
+\x15\x02\x08\0\0\0\0\0\x61\x12\0\0\0\0\0\0\x67\x02\0\0\x1e\0\0\0\x61\x64\0\0\0\
+\0\0\0\x77\x04\0\0\x02\0\0\0\x57\x04\0\0\xff\xff\xff\x3f\x4f\x42\0\0\0\0\0\0\
+\xaf\x72\0\0\0\0\0\0\xbf\x27\0\0\0\0\0\0\x57\x03\0\0\x01\0\0\0\x15\x03\x08\0\0\
+\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x1f\0\0\0\x61\x62\0\0\0\0\0\0\x77\x02\0\
+\0\x01\0\0\0\x57\x02\0\0\xff\xff\xff\x7f\x4f\x21\0\0\0\0\0\0\xaf\x71\0\0\0\0\0\
+\0\xbf\x17\0\0\0\0\0\0\x7b\x7a\x90\xff\0\0\0\0\x05\0\xa9\x0c\0\0\0\0\xb7\x02\0\
+\0\x28\0\0\0\x71\xa1\xde\xff\0\0\0\0\x79\xa6\x88\xff\0\0\0\0\x65\x01\x3b\x0c\
+\x2b\0\0\0\x15\x01\x3c\x0c\0\0\0\0\x15\x01\x3b\x0c\x2b\0\0\0\x15\x01\x01\0\x06\
+\0\0\0\x55\x01\xa1\x0c\x11\0\0\0\xbf\x06\0\0\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\
+\x03\0\0\xd0\xff\xff\xff\x79\xa1\x88\xff\0\0\0\0\xb7\x04\0\0\x04\0\0\0\xb7\x05\
+\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x55\0\x99\x0c\0\0\0\0\x79\xa2\x78\xff\0\0\0\
+\0\xbf\x24\0\0\0\0\0\0\x07\x02\0\0\x08\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\
+\0\0\x40\xb7\x08\0\0\0\0\0\0\x15\x01\x07\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\
+\x18\0\0\0\0\0\0\x67\x08\0\0\x01\0\0\0\x61\x21\0\0\0\0\0\0\x77\x01\0\0\x1f\0\0\
+\0\x57\x01\0\0\x01\0\0\0\x4f\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\
+\0\0\x20\xbf\x65\0\0\0\0\0\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\
+\x11\0\0\0\0\0\0\x67\x01\0\0\x02\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1e\0\0\
+\0\x57\x03\0\0\x03\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\
+\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x10\x79\xa0\x58\xff\0\0\0\0\x79\
+\xa3\x68\xff\0\0\0\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\
+\0\0\0\0\x67\x01\0\0\x03\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1d\0\0\0\x57\
+\x03\0\0\x07\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\
+\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x08\x79\xa6\x60\xff\0\0\0\0\x15\x01\x09\
+\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x04\0\0\0\
+\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1c\0\0\0\x57\x03\0\0\x0f\0\0\0\x4f\x31\0\0\0\
+\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\
+\0\0\0\x04\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\
+\x67\x01\0\0\x05\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x1b\0\0\0\x57\x03\0\0\
+\x1f\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\
+\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x02\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\
+\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x06\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\
+\x1a\0\0\0\x57\x03\0\0\x3f\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\
+\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x01\x15\x01\x09\0\0\0\0\
+\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x07\0\0\0\x61\x23\0\
+\0\0\0\0\0\x77\x03\0\0\x19\0\0\0\x57\x03\0\0\x7f\0\0\0\x4f\x31\0\0\0\0\0\0\xaf\
+\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\x80\0\
+\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\
+\x08\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x18\0\0\0\x57\x03\0\0\xff\0\0\0\x4f\
+\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\
+\x57\x01\0\0\0\0\x40\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\
+\0\0\0\0\0\x67\x01\0\0\x09\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x17\0\0\0\x57\
+\x03\0\0\xff\x01\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\
+\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\x20\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\
+\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x0a\0\0\0\x61\x23\0\0\0\0\0\0\x77\
+\x03\0\0\x16\0\0\0\x57\x03\0\0\xff\x03\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\
+\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\x10\0\x15\x01\x09\
+\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x0b\0\0\0\
+\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x15\0\0\0\x57\x03\0\0\xff\x07\0\0\x4f\x31\0\0\
+\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\
+\0\0\0\x08\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\
+\x67\x01\0\0\x0c\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x14\0\0\0\x57\x03\0\0\
+\xff\x0f\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\x04\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\
+\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x0d\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\
+\0\x13\0\0\0\x57\x03\0\0\xff\x1f\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\
+\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\0\x02\0\x15\x01\x09\0\0\
+\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x0e\0\0\0\x61\
+\x23\0\0\0\0\0\0\x77\x03\0\0\x12\0\0\0\x57\x03\0\0\xff\x3f\0\0\x4f\x31\0\0\0\0\
+\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\
+\0\x01\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\
+\x01\0\0\x0f\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x11\0\0\0\x57\x03\0\0\xff\
+\x7f\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\
+\0\0\0\0\0\x57\x01\0\0\0\x80\0\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\
+\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x10\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x10\
+\0\0\0\x57\x03\0\0\xff\xff\0\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\
+\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\x40\0\0\x15\x01\x09\0\0\0\0\0\
+\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x11\0\0\0\x61\x23\0\0\
+\0\0\0\0\x77\x03\0\0\x0f\0\0\0\x57\x03\0\0\xff\xff\x01\0\x4f\x31\0\0\0\0\0\0\
+\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\x20\
+\0\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\
+\0\0\x12\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0e\0\0\0\x57\x03\0\0\xff\xff\
+\x03\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\
+\0\0\0\0\x57\x01\0\0\0\x10\0\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\
+\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x13\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0d\
+\0\0\0\x57\x03\0\0\xff\xff\x07\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\
+\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\x08\0\0\x15\x01\x09\0\0\0\0\
+\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x14\0\0\0\x61\x23\0\
+\0\0\0\0\0\x77\x03\0\0\x0c\0\0\0\x57\x03\0\0\xff\xff\x0f\0\x4f\x31\0\0\0\0\0\0\
+\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\x04\
+\0\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\
+\0\0\x15\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0b\0\0\0\x57\x03\0\0\xff\xff\
+\x1f\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\
+\0\0\0\0\x57\x01\0\0\0\x02\0\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\
+\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x16\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x0a\
+\0\0\0\x57\x03\0\0\xff\xff\x3f\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\
+\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\0\x01\0\0\x15\x01\x09\0\0\0\0\
+\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x17\0\0\0\x61\x23\0\
+\0\0\0\0\0\x77\x03\0\0\x09\0\0\0\x57\x03\0\0\xff\xff\x7f\0\x4f\x31\0\0\0\0\0\0\
+\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\x80\0\
+\0\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\
+\0\0\x18\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x08\0\0\0\x57\x03\0\0\xff\xff\
+\xff\0\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\
+\0\0\0\0\x57\x01\0\0\x40\0\0\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\
+\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x19\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x07\
+\0\0\0\x57\x03\0\0\xff\xff\xff\x01\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\
+\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\x20\0\0\0\x15\x01\x09\0\0\0\0\
+\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x1a\0\0\0\x61\x23\0\
+\0\0\0\0\0\x77\x03\0\0\x06\0\0\0\x57\x03\0\0\xff\xff\xff\x03\x4f\x31\0\0\0\0\0\
+\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\x10\
+\0\0\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\
+\x01\0\0\x1b\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x05\0\0\0\x57\x03\0\0\xff\
+\xff\xff\x07\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x91\0\0\0\0\0\0\x57\x01\0\0\x08\0\0\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\
+\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x1c\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\
+\0\x04\0\0\0\x57\x03\0\0\xff\xff\xff\x0f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\
+\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\x04\0\0\0\x15\x01\x09\0\
+\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x1d\0\0\0\x61\
+\x23\0\0\0\0\0\0\x77\x03\0\0\x03\0\0\0\x57\x03\0\0\xff\xff\xff\x1f\x4f\x31\0\0\
+\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\
+\0\x02\0\0\0\x15\x01\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\0\0\0\0\0\
+\x67\x01\0\0\x1e\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x02\0\0\0\x57\x03\0\0\
+\xff\xff\xff\x3f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\
+\x57\x09\0\0\x01\0\0\0\x15\x09\x09\0\0\0\0\0\x79\xa1\x98\xff\0\0\0\0\x61\x11\0\
+\0\0\0\0\0\x67\x01\0\0\x1f\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x01\0\0\0\x57\
+\x03\0\0\xff\xff\xff\x7f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\
+\0\0\0\xbf\x49\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x07\x01\0\0\x0c\0\0\0\xbf\x73\0\
+\0\0\0\0\0\x57\x03\0\0\0\0\0\x40\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\
+\x03\0\0\x01\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\0\0\x01\0\
+\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\
+\0\0\0\x57\x03\0\0\0\0\0\x20\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\
+\0\0\x02\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\x03\0\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\0\x10\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x03\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\x07\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x08\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x04\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\x0f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x04\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x05\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\x1f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x02\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x06\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\x3f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\0\x01\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x07\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\x7f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\x80\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x08\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\xff\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\0\
+\x57\x03\0\0\0\0\x40\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x09\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\xff\x01\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x20\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x0a\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\xff\x03\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x10\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x0b\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\xff\x07\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x08\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x0c\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\xff\x0f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x04\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x0d\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\xff\x1f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x02\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x0e\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\xff\x3f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\0\x01\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x0f\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\xff\x7f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x80\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x10\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\xff\xff\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x40\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x11\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\xff\xff\x01\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x20\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x12\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0e\0\0\0\x57\x04\0\0\xff\xff\x03\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x10\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x13\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\xff\xff\x07\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x08\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x14\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\xff\xff\x0f\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x04\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x15\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\xff\xff\x1f\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x02\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x16\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\xff\xff\x3f\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\0\x01\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x17\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\xff\xff\x7f\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\x80\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x18\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\xff\xff\xff\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\0\0\
+\0\x57\x03\0\0\x40\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x19\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\xff\xff\xff\
+\x01\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\0\0\
+\0\0\0\x57\x03\0\0\x20\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\
+\0\0\x1a\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\0\0\xff\xff\
+\xff\x03\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x73\0\
+\0\0\0\0\0\x57\x03\0\0\x10\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\
+\x03\0\0\x1b\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\x04\0\0\xff\
+\xff\xff\x07\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x73\0\0\0\0\0\0\x57\x03\0\0\x08\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x1c\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\0\x57\x04\0\0\
+\xff\xff\xff\x0f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\xbf\x73\0\0\0\0\0\0\x57\x03\0\0\x04\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\
+\0\0\0\x67\x03\0\0\x1d\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x03\0\0\0\x57\x04\
+\0\0\xff\xff\xff\x1f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\
+\0\xbf\x73\0\0\0\0\0\0\x57\x03\0\0\x02\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\
+\0\0\0\0\x67\x03\0\0\x1e\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x02\0\0\0\x57\
+\x04\0\0\xff\xff\xff\x3f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\
+\0\0\0\x57\x07\0\0\x01\0\0\0\x15\x07\x08\0\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\
+\0\0\x1f\0\0\0\x61\x13\0\0\0\0\0\0\x77\x03\0\0\x01\0\0\0\x57\x03\0\0\xff\xff\
+\xff\x7f\x4f\x32\0\0\0\0\0\0\xaf\x82\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x92\0\
+\0\0\0\0\0\x07\x02\0\0\x10\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\0\x40\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x01\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\0\0\x01\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\0\x20\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x02\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\x03\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\0\x10\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x03\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\x07\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\0\x08\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x04\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\x0f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\0\x04\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x05\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\x1f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\0\x02\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x06\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\x3f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\0\x01\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x07\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\x7f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\x80\0\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x08\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\xff\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\x40\0\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x09\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\xff\x01\0\0\x4f\x43\0\0\0\0\0\0\xaf\
+\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\0\
+\x20\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x0a\0\0\0\x61\x24\
+\0\0\0\0\0\0\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\xff\x03\0\0\x4f\x43\0\0\0\0\0\0\
+\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\
+\0\x10\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x0b\0\0\0\x61\
+\x24\0\0\0\0\0\0\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\xff\x07\0\0\x4f\x43\0\0\0\0\
+\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\
+\0\0\0\x08\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x0c\0\0\0\
+\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\xff\x0f\0\0\x4f\x43\0\0\
+\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\
+\x03\0\0\0\0\x04\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x0d\0\
+\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\xff\x1f\0\0\x4f\x43\
+\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\
+\x57\x03\0\0\0\0\x02\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x0e\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\xff\x3f\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\
+\0\0\0\x57\x03\0\0\0\0\x01\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\
+\0\0\x0f\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\xff\x7f\0\
+\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\
+\0\0\0\0\x57\x03\0\0\0\x80\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\
+\x03\0\0\x10\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\xff\
+\xff\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\
+\xa0\xff\0\0\0\0\x57\x03\0\0\0\x40\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x11\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\
+\xff\xff\x01\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\
+\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\x20\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\
+\0\0\0\x67\x03\0\0\x12\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0e\0\0\0\x57\x04\
+\0\0\xff\xff\x03\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\x10\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\
+\0\0\0\0\0\x67\x03\0\0\x13\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0d\0\0\0\x57\
+\x04\0\0\xff\xff\x07\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\
+\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\x08\0\0\x15\x03\x08\0\0\0\0\0\x61\
+\x13\0\0\0\0\0\0\x67\x03\0\0\x14\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0c\0\0\
+\0\x57\x04\0\0\xff\xff\x0f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\
+\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\x04\0\0\x15\x03\x08\0\0\0\0\0\
+\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x15\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0b\
+\0\0\0\x57\x04\0\0\xff\xff\x1f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\
+\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\x02\0\0\x15\x03\x08\0\0\
+\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x16\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\
+\0\x0a\0\0\0\x57\x04\0\0\xff\xff\x3f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\
+\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\0\x01\0\0\x15\x03\x08\
+\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x17\0\0\0\x61\x24\0\0\0\0\0\0\x77\
+\x04\0\0\x09\0\0\0\x57\x04\0\0\xff\xff\x7f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\
+\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\x80\0\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x18\0\0\0\x61\x24\0\0\0\0\0\
+\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\xff\xff\xff\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\x40\0\0\0\
+\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x19\0\0\0\x61\x24\0\0\0\
+\0\0\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\xff\xff\xff\x01\x4f\x43\0\0\0\0\0\0\
+\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\
+\x20\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x1a\0\0\0\x61\
+\x24\0\0\0\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\0\0\xff\xff\xff\x03\x4f\x43\0\0\
+\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\
+\x03\0\0\x10\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x1b\0\
+\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\x04\0\0\xff\xff\xff\x07\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\xff\0\0\0\
+\0\x57\x03\0\0\x08\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\x67\x03\0\0\
+\x1c\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\0\x57\x04\0\0\xff\xff\xff\
+\x0f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\xa0\
+\xff\0\0\0\0\x57\x03\0\0\x04\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x1d\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x03\0\0\0\x57\x04\0\0\
+\xff\xff\xff\x1f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\x02\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\
+\0\0\0\0\0\x67\x03\0\0\x1e\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x02\0\0\0\x57\
+\x04\0\0\xff\xff\xff\x3f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\
+\0\0\0\x79\xa3\xa0\xff\0\0\0\0\x57\x03\0\0\x01\0\0\0\x15\x03\x08\0\0\0\0\0\x61\
+\x11\0\0\0\0\0\0\x67\x01\0\0\x1f\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x01\0\0\
+\0\x57\x03\0\0\xff\xff\xff\x7f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\
+\0\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x07\x01\0\0\x14\0\0\0\x79\xa3\x70\xff\0\0\0\0\
+\x57\x03\0\0\0\0\0\x40\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x01\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\0\0\x01\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\
+\0\x57\x03\0\0\0\0\0\x20\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x02\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\x03\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\
+\0\x57\x03\0\0\0\0\0\x10\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x03\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\x07\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\
+\0\x57\x03\0\0\0\0\0\x08\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x04\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\x0f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\
+\0\x57\x03\0\0\0\0\0\x04\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x05\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\x1f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\
+\0\x57\x03\0\0\0\0\0\x02\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x06\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\x3f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\
+\0\x57\x03\0\0\0\0\0\x01\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x07\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\x7f\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\
+\0\x57\x03\0\0\0\0\x80\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x08\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\xff\0\0\0\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\
+\0\x57\x03\0\0\0\0\x40\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x09\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\xff\x01\0\0\
+\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\
+\0\0\0\x57\x03\0\0\0\0\x20\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\
+\0\0\x0a\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\xff\x03\0\
+\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\
+\0\0\0\0\x57\x03\0\0\0\0\x10\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\
+\x03\0\0\x0b\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\xff\
+\x07\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\
+\x70\xff\0\0\0\0\x57\x03\0\0\0\0\x08\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\
+\0\x67\x03\0\0\x0c\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\
+\xff\x0f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\
+\xa3\x70\xff\0\0\0\0\x57\x03\0\0\0\0\x04\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\
+\0\0\0\x67\x03\0\0\x0d\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x13\0\0\0\x57\x04\
+\0\0\xff\x1f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\0\0\x02\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\
+\0\0\0\0\0\x67\x03\0\0\x0e\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x12\0\0\0\x57\
+\x04\0\0\xff\x3f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\
+\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\0\0\x01\0\x15\x03\x08\0\0\0\0\0\x61\x23\
+\0\0\0\0\0\0\x67\x03\0\0\x0f\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x11\0\0\0\
+\x57\x04\0\0\xff\x7f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\
+\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\0\x80\0\0\x15\x03\x08\0\0\0\0\0\x61\
+\x23\0\0\0\0\0\0\x67\x03\0\0\x10\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x10\0\0\
+\0\x57\x04\0\0\xff\xff\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\
+\0\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\0\x40\0\0\x15\x03\x08\0\0\0\0\0\
+\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x11\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x0f\
+\0\0\0\x57\x04\0\0\xff\xff\x01\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\
+\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\0\x20\0\0\x15\x03\x08\0\0\
+\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x12\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\
+\0\x0e\0\0\0\x57\x04\0\0\xff\xff\x03\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\
+\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\0\x10\0\0\x15\x03\x08\
+\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x13\0\0\0\x61\x14\0\0\0\0\0\0\x77\
+\x04\0\0\x0d\0\0\0\x57\x04\0\0\xff\xff\x07\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\
+\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\0\x08\0\0\x15\
+\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x14\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\xff\xff\x0f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\
+\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\0\x04\0\0\
+\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x15\0\0\0\x61\x14\0\0\0\
+\0\0\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\xff\xff\x1f\0\x4f\x43\0\0\0\0\0\0\xaf\
+\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\0\x02\
+\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x16\0\0\0\x61\x14\0\
+\0\0\0\0\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\xff\xff\x3f\0\x4f\x43\0\0\0\0\0\0\
+\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\0\
+\x01\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x17\0\0\0\x61\
+\x14\0\0\0\0\0\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\xff\xff\x7f\0\x4f\x43\0\0\0\
+\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\
+\0\0\x80\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x18\0\0\0\
+\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\xff\xff\xff\0\x4f\x43\0\
+\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\
+\x03\0\0\x40\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x19\0\
+\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\xff\xff\xff\x01\x4f\
+\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\
+\0\x57\x03\0\0\x20\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\
+\x1a\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\0\0\xff\xff\xff\
+\x03\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\
+\xff\0\0\0\0\x57\x03\0\0\x10\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\0\0\0\0\0\
+\x67\x03\0\0\x1b\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\x04\0\0\
+\xff\xff\xff\x07\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\x08\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x23\0\
+\0\0\0\0\0\x67\x03\0\0\x1c\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\0\x57\
+\x04\0\0\xff\xff\xff\x0f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\
+\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\x04\0\0\0\x15\x03\x08\0\0\0\0\0\x61\
+\x23\0\0\0\0\0\0\x67\x03\0\0\x1d\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x03\0\0\
+\0\x57\x04\0\0\xff\xff\xff\x1f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\
+\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\x02\0\0\0\x15\x03\x08\0\0\0\0\
+\0\x61\x23\0\0\0\0\0\0\x67\x03\0\0\x1e\0\0\0\x61\x14\0\0\0\0\0\0\x77\x04\0\0\
+\x02\0\0\0\x57\x04\0\0\xff\xff\xff\x3f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\
+\xbf\x38\0\0\0\0\0\0\x79\xa3\x70\xff\0\0\0\0\x57\x03\0\0\x01\0\0\0\x15\x03\x08\
+\0\0\0\0\0\x61\x22\0\0\0\0\0\0\x67\x02\0\0\x1f\0\0\0\x61\x13\0\0\0\0\0\0\x77\
+\x03\0\0\x01\0\0\0\x57\x03\0\0\xff\xff\xff\x7f\x4f\x32\0\0\0\0\0\0\xaf\x82\0\0\
+\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x07\x02\0\0\x18\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x40\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x01\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\0\0\
+\x01\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x20\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x02\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\
+\x03\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x10\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x03\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\
+\x07\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x08\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x04\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\
+\x0f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x04\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x05\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\
+\x1f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x02\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x06\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\
+\x3f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x01\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x07\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\
+\x7f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\x80\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x08\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\
+\xff\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\x40\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x09\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\
+\xff\x01\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x20\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0a\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\
+\xff\x03\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x10\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0b\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\
+\xff\x07\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x08\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0c\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\
+\xff\x0f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x04\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0d\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\
+\xff\x1f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x02\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0e\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\
+\xff\x3f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x01\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0f\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\
+\xff\x7f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x80\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x10\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\
+\xff\xff\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x40\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x11\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\
+\xff\xff\x01\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x20\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x12\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0e\0\0\0\x57\x04\0\0\
+\xff\xff\x03\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x10\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x13\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\
+\xff\xff\x07\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x08\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x14\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\
+\xff\xff\x0f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x04\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x15\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\
+\xff\xff\x1f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x02\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x16\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\
+\xff\xff\x3f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x01\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x17\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\
+\xff\xff\x7f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\x80\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x18\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\
+\xff\xff\xff\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\x40\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x19\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\
+\xff\xff\xff\x01\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\x20\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\
+\0\0\0\x67\x03\0\0\x1a\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\
+\0\0\xff\xff\xff\x03\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\
+\0\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\x10\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\
+\0\0\0\0\x67\x03\0\0\x1b\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\
+\x04\0\0\xff\xff\xff\x07\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\
+\0\0\0\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\x08\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\
+\0\0\0\0\0\0\x67\x03\0\0\x1c\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\0\
+\x57\x04\0\0\xff\xff\xff\x0f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\
+\0\0\0\0\0\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\x04\0\0\0\x15\x03\x08\0\0\0\0\0\x61\
+\x13\0\0\0\0\0\0\x67\x03\0\0\x1d\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x03\0\0\
+\0\x57\x04\0\0\xff\xff\xff\x1f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\
+\0\0\0\0\0\0\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\x02\0\0\0\x15\x03\x08\0\0\0\0\0\
+\x61\x13\0\0\0\0\0\0\x67\x03\0\0\x1e\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x02\
+\0\0\0\x57\x04\0\0\xff\xff\xff\x3f\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\
+\x38\0\0\0\0\0\0\x57\x06\0\0\x01\0\0\0\x15\x06\x08\0\0\0\0\0\x61\x11\0\0\0\0\0\
+\0\x67\x01\0\0\x1f\0\0\0\x61\x23\0\0\0\0\0\0\x77\x03\0\0\x01\0\0\0\x57\x03\0\0\
+\xff\xff\xff\x7f\x4f\x31\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\
+\xbf\x93\0\0\0\0\0\0\x07\x03\0\0\x1c\0\0\0\xbf\x01\0\0\0\0\0\0\x57\x01\0\0\0\0\
+\0\x40\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x01\0\0\0\x61\x34\
+\0\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\0\0\x01\0\0\0\x4f\x41\0\0\0\0\0\0\
+\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\0\x57\x01\0\0\0\0\0\
+\x20\x79\xa6\x68\xff\0\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\
+\0\0\x02\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\x03\0\0\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\0\x10\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x03\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\x07\0\0\0\x4f\
+\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\0\
+\x57\x01\0\0\0\0\0\x08\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x04\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\x0f\0\0\0\x4f\
+\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\0\
+\x57\x01\0\0\0\0\0\x04\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x05\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\x1f\0\0\0\x4f\
+\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\0\
+\x57\x01\0\0\0\0\0\x02\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x06\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\x3f\0\0\0\x4f\
+\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\0\
+\x57\x01\0\0\0\0\0\x01\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x07\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\x7f\0\0\0\x4f\
+\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\0\
+\x57\x01\0\0\0\0\x80\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x08\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\xff\0\0\0\x4f\
+\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\0\
+\x57\x01\0\0\0\0\x40\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x09\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\xff\x01\0\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\x20\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x0a\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\xff\x03\0\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\x10\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x0b\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\xff\x07\0\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\x08\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x0c\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\xff\x0f\0\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\x04\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x0d\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\xff\x1f\0\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\x02\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x0e\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\xff\x3f\0\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\0\x01\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x0f\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\xff\x7f\0\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\x80\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x10\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\xff\xff\0\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\x40\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x11\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\xff\xff\x01\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\x20\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x12\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x0e\0\0\0\x57\x04\0\0\xff\xff\x03\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\x10\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x13\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\xff\xff\x07\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\x08\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x14\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\xff\xff\x0f\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\x04\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x15\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\xff\xff\x1f\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\x02\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x16\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\xff\xff\x3f\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\0\x01\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x17\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\xff\xff\x7f\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\x80\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x18\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\xff\xff\xff\0\
+\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\0\0\
+\0\x57\x01\0\0\x40\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x19\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\xff\xff\xff\
+\x01\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\0\0\
+\0\0\0\x57\x01\0\0\x20\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\
+\0\0\x1a\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\0\0\xff\xff\
+\xff\x03\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x01\0\
+\0\0\0\0\0\x57\x01\0\0\x10\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\
+\x01\0\0\x1b\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\x04\0\0\xff\
+\xff\xff\x07\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\
+\x01\0\0\0\0\0\0\x57\x01\0\0\x08\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\
+\0\x67\x01\0\0\x1c\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\0\x57\x04\0\0\
+\xff\xff\xff\x0f\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\
+\xbf\x01\0\0\0\0\0\0\x57\x01\0\0\x04\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\
+\0\0\0\x67\x01\0\0\x1d\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x03\0\0\0\x57\x04\
+\0\0\xff\xff\xff\x1f\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\
+\0\xbf\x01\0\0\0\0\0\0\x57\x01\0\0\x02\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\
+\0\0\0\0\x67\x01\0\0\x1e\0\0\0\x61\x34\0\0\0\0\0\0\x77\x04\0\0\x02\0\0\0\x57\
+\x04\0\0\xff\xff\xff\x3f\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\
+\0\0\0\x57\0\0\0\x01\0\0\0\x15\0\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\
+\x1f\0\0\0\x61\x32\0\0\0\0\0\0\x77\x02\0\0\x01\0\0\0\x57\x02\0\0\xff\xff\xff\
+\x7f\x4f\x21\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x91\0\0\0\
+\0\0\0\x07\x01\0\0\x20\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x40\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x01\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x1f\0\0\0\x57\x04\0\0\x01\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\0\
+\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x20\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x02\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\x03\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\0\
+\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x10\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x03\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\x07\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\0\
+\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x08\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x04\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\x0f\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\0\
+\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x04\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x05\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\x1f\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\0\
+\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x02\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x06\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\x3f\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\0\
+\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\0\x01\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x07\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\x7f\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\0\
+\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\x80\0\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x08\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\xff\0\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\0\
+\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\x40\0\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x09\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\xff\x01\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\
+\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\x20\0\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x0a\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\xff\x03\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\
+\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\x10\0\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x0b\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\xff\x07\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\
+\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\x08\0\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x0c\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\xff\x0f\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\
+\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\x04\0\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x0d\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\xff\x1f\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\
+\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\x02\0\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x0e\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\xff\x3f\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\
+\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\0\x01\0\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x0f\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\xff\x7f\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\
+\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\x80\0\0\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x10\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\xff\xff\0\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\0\
+\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\x40\0\0\x15\x02\
+\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x11\0\0\0\x61\x14\0\0\0\0\0\0\
+\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\xff\xff\x01\0\x4f\x42\0\0\0\0\0\0\xaf\x82\0\
+\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\x20\0\0\x15\
+\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x12\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x0e\0\0\0\x57\x04\0\0\xff\xff\x03\0\x4f\x42\0\0\0\0\0\0\xaf\x82\
+\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\x10\0\0\x15\
+\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x13\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\xff\xff\x07\0\x4f\x42\0\0\0\0\0\0\xaf\x82\
+\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\x08\0\0\x15\
+\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x14\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\xff\xff\x0f\0\x4f\x42\0\0\0\0\0\0\xaf\x82\
+\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\x04\0\0\x15\
+\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x15\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\xff\xff\x1f\0\x4f\x42\0\0\0\0\0\0\xaf\x82\
+\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\x02\0\0\x15\
+\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x16\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\xff\xff\x3f\0\x4f\x42\0\0\0\0\0\0\xaf\x82\
+\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\0\x01\0\0\x15\
+\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x17\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\xff\xff\x7f\0\x4f\x42\0\0\0\0\0\0\xaf\x82\
+\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\x80\0\0\0\x15\
+\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x18\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\xff\xff\xff\0\x4f\x42\0\0\0\0\0\0\xaf\x82\
+\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\x40\0\0\0\x15\
+\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x19\0\0\0\x61\x14\0\0\0\0\0\
+\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\xff\xff\xff\x01\x4f\x42\0\0\0\0\0\0\xaf\
+\x82\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\x20\0\0\0\
+\x15\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x1a\0\0\0\x61\x14\0\0\0\
+\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\0\0\xff\xff\xff\x03\x4f\x42\0\0\0\0\0\0\
+\xaf\x82\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\x10\0\
+\0\0\x15\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x1b\0\0\0\x61\x14\0\
+\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\x04\0\0\xff\xff\xff\x07\x4f\x42\0\0\0\0\0\
+\0\xaf\x82\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\x08\
+\0\0\0\x15\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x1c\0\0\0\x61\x14\
+\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\0\x57\x04\0\0\xff\xff\xff\x0f\x4f\x42\0\0\0\0\
+\0\0\xaf\x82\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\0\
+\x04\0\0\0\x15\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x1d\0\0\0\x61\
+\x14\0\0\0\0\0\0\x77\x04\0\0\x03\0\0\0\x57\x04\0\0\xff\xff\xff\x1f\x4f\x42\0\0\
+\0\0\0\0\xaf\x82\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x52\0\0\0\0\0\0\x57\x02\0\
+\0\x02\0\0\0\x15\x02\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x1e\0\0\0\
+\x61\x14\0\0\0\0\0\0\x77\x04\0\0\x02\0\0\0\x57\x04\0\0\xff\xff\xff\x3f\x4f\x42\
+\0\0\0\0\0\0\xaf\x82\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\x57\x05\0\0\x01\0\0\0\x15\
+\x05\x08\0\0\0\0\0\x61\x32\0\0\0\0\0\0\x67\x02\0\0\x1f\0\0\0\x61\x13\0\0\0\0\0\
+\0\x77\x03\0\0\x01\0\0\0\x57\x03\0\0\xff\xff\xff\x7f\x4f\x32\0\0\0\0\0\0\xaf\
+\x82\0\0\0\0\0\0\xbf\x28\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x07\x02\0\0\x24\0\0\0\
+\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x40\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\
+\0\0\0\x67\x03\0\0\x01\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\
+\0\0\x01\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x20\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x02\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\
+\x03\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x10\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x03\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\
+\x07\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x08\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x04\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\
+\x0f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x04\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x05\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\
+\x1f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x02\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x06\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\
+\x3f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\0\x01\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x07\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\
+\x7f\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\x80\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x08\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\
+\xff\0\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\x63\
+\0\0\0\0\0\0\x57\x03\0\0\0\0\x40\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\0\
+\x67\x03\0\0\x09\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\
+\xff\x01\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x20\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0a\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\
+\xff\x03\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x10\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0b\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\
+\xff\x07\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x08\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0c\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\
+\xff\x0f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x04\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0d\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\
+\xff\x1f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x02\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0e\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\
+\xff\x3f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\0\x01\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x0f\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\
+\xff\x7f\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x80\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x10\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\
+\xff\xff\0\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x40\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x11\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\
+\xff\xff\x01\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x20\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x12\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0e\0\0\0\x57\x04\0\0\
+\xff\xff\x03\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x10\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x13\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\
+\xff\xff\x07\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x08\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x14\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\
+\xff\xff\x0f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x04\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x15\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\
+\xff\xff\x1f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x02\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x16\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\
+\xff\xff\x3f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\0\x01\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x17\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\
+\xff\xff\x7f\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\x80\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x18\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\
+\xff\xff\xff\0\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\xbf\
+\x63\0\0\0\0\0\0\x57\x03\0\0\x40\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\0\0\
+\0\x67\x03\0\0\x19\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\
+\xff\xff\xff\x01\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\0\
+\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\x20\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\0\
+\0\0\0\x67\x03\0\0\x1a\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\
+\0\0\xff\xff\xff\x03\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\0\0\
+\0\xbf\x63\0\0\0\0\0\0\x57\x03\0\0\x10\0\0\0\x15\x03\x08\0\0\0\0\0\x61\x13\0\0\
+\0\0\0\0\x67\x03\0\0\x1b\0\0\0\x61\x24\0\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\
+\x04\0\0\xff\xff\xff\x07\x4f\x43\0\0\0\0\0\0\xaf\x83\0\0\0\0\0\0\xbf\x38\0\0\0\
+\0\0\0\x69\xa3\xd2\xff\0\0\0\0\xbf\x64\0\0\0\0\0\0\x57\x04\0\0\x08\0\0\0\x15\
+\x04\x08\0\0\0\0\0\x61\x14\0\0\0\0\0\0\x67\x04\0\0\x1c\0\0\0\x61\x25\0\0\0\0\0\
+\0\x77\x05\0\0\x04\0\0\0\x57\x05\0\0\xff\xff\xff\x0f\x4f\x54\0\0\0\0\0\0\xaf\
+\x84\0\0\0\0\0\0\xbf\x48\0\0\0\0\0\0\x67\x03\0\0\x10\0\0\0\x69\xa4\xd0\xff\0\0\
+\0\0\xbf\x65\0\0\0\0\0\0\x57\x05\0\0\x04\0\0\0\x15\x05\x08\0\0\0\0\0\x61\x15\0\
+\0\0\0\0\0\x67\x05\0\0\x1d\0\0\0\x61\x20\0\0\0\0\0\0\x77\0\0\0\x03\0\0\0\x57\0\
+\0\0\xff\xff\xff\x1f\x4f\x05\0\0\0\0\0\0\xaf\x85\0\0\0\0\0\0\xbf\x58\0\0\0\0\0\
+\0\x4f\x43\0\0\0\0\0\0\xbf\x64\0\0\0\0\0\0\x57\x04\0\0\x02\0\0\0\x15\x04\x08\0\
+\0\0\0\0\x61\x14\0\0\0\0\0\0\x67\x04\0\0\x1e\0\0\0\x61\x25\0\0\0\0\0\0\x77\x05\
+\0\0\x02\0\0\0\x57\x05\0\0\xff\xff\xff\x3f\x4f\x54\0\0\0\0\0\0\xaf\x84\0\0\0\0\
+\0\0\xbf\x48\0\0\0\0\0\0\xdc\x03\0\0\x20\0\0\0\x57\x06\0\0\x01\0\0\0\x15\x06\
+\x08\0\0\0\0\0\x61\x11\0\0\0\0\0\0\x67\x01\0\0\x1f\0\0\0\x61\x24\0\0\0\0\0\0\
+\x77\x04\0\0\x01\0\0\0\x57\x04\0\0\xff\xff\xff\x7f\x4f\x41\0\0\0\0\0\0\xaf\x81\
+\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\x07\x09\0\0\x28\0\0\0\xbf\x31\0\0\0\0\0\0\x57\
+\x01\0\0\0\0\0\x40\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x01\0\
+\0\0\x61\x94\0\0\0\0\0\0\x77\x04\0\0\x1f\0\0\0\x57\x04\0\0\x01\0\0\0\x4f\x41\0\
+\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\
+\0\0\0\0\0\x20\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x02\0\0\0\
+\x61\x94\0\0\0\0\0\0\x77\x04\0\0\x1e\0\0\0\x57\x04\0\0\x03\0\0\0\x4f\x41\0\0\0\
+\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\
+\0\0\0\x10\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x03\0\0\0\x61\
+\x94\0\0\0\0\0\0\x77\x04\0\0\x1d\0\0\0\x57\x04\0\0\x07\0\0\0\x4f\x41\0\0\0\0\0\
+\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\0\
+\0\x08\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x04\0\0\0\x61\x94\
+\0\0\0\0\0\0\x77\x04\0\0\x1c\0\0\0\x57\x04\0\0\x0f\0\0\0\x4f\x41\0\0\0\0\0\0\
+\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\0\0\
+\x04\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x05\0\0\0\x61\x94\0\
+\0\0\0\0\0\x77\x04\0\0\x1b\0\0\0\x57\x04\0\0\x1f\0\0\0\x4f\x41\0\0\0\0\0\0\xaf\
+\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x02\
+\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x06\0\0\0\x61\x94\0\0\0\
+\0\0\0\x77\x04\0\0\x1a\0\0\0\x57\x04\0\0\x3f\0\0\0\x4f\x41\0\0\0\0\0\0\xaf\x81\
+\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\0\0\x01\x15\
+\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x07\0\0\0\x61\x94\0\0\0\0\0\
+\0\x77\x04\0\0\x19\0\0\0\x57\x04\0\0\x7f\0\0\0\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\
+\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\0\x80\0\x15\x01\
+\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x08\0\0\0\x61\x94\0\0\0\0\0\0\
+\x77\x04\0\0\x18\0\0\0\x57\x04\0\0\xff\0\0\0\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\0\
+\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\0\x40\0\x15\x01\
+\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x09\0\0\0\x61\x94\0\0\0\0\0\0\
+\x77\x04\0\0\x17\0\0\0\x57\x04\0\0\xff\x01\0\0\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\
+\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\0\x20\0\x15\x01\
+\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x0a\0\0\0\x61\x94\0\0\0\0\0\0\
+\x77\x04\0\0\x16\0\0\0\x57\x04\0\0\xff\x03\0\0\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\
+\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\0\x10\0\x15\x01\
+\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x0b\0\0\0\x61\x94\0\0\0\0\0\0\
+\x77\x04\0\0\x15\0\0\0\x57\x04\0\0\xff\x07\0\0\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\
+\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\0\x08\0\x15\x01\
+\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x0c\0\0\0\x61\x94\0\0\0\0\0\0\
+\x77\x04\0\0\x14\0\0\0\x57\x04\0\0\xff\x0f\0\0\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\
+\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\0\x04\0\x15\x01\
+\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x0d\0\0\0\x61\x94\0\0\0\0\0\0\
+\x77\x04\0\0\x13\0\0\0\x57\x04\0\0\xff\x1f\0\0\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\
+\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\0\x02\0\x15\x01\
+\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x0e\0\0\0\x61\x94\0\0\0\0\0\0\
+\x77\x04\0\0\x12\0\0\0\x57\x04\0\0\xff\x3f\0\0\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\
+\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\0\x01\0\x15\x01\
+\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x0f\0\0\0\x61\x94\0\0\0\0\0\0\
+\x77\x04\0\0\x11\0\0\0\x57\x04\0\0\xff\x7f\0\0\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\
+\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\x80\0\0\x15\x01\
+\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x10\0\0\0\x61\x94\0\0\0\0\0\0\
+\x77\x04\0\0\x10\0\0\0\x57\x04\0\0\xff\xff\0\0\x4f\x41\0\0\0\0\0\0\xaf\x81\0\0\
+\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\x40\0\0\x15\x01\
+\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x11\0\0\0\x61\x94\0\0\0\0\0\0\
+\x77\x04\0\0\x0f\0\0\0\x57\x04\0\0\xff\xff\x01\0\x4f\x41\0\0\0\0\0\0\xaf\x81\0\
+\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\x20\0\0\x15\
+\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x12\0\0\0\x61\x94\0\0\0\0\0\
+\0\x77\x04\0\0\x0e\0\0\0\x57\x04\0\0\xff\xff\x03\0\x4f\x41\0\0\0\0\0\0\xaf\x81\
+\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\x10\0\0\x15\
+\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x13\0\0\0\x61\x94\0\0\0\0\0\
+\0\x77\x04\0\0\x0d\0\0\0\x57\x04\0\0\xff\xff\x07\0\x4f\x41\0\0\0\0\0\0\xaf\x81\
+\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\x08\0\0\x15\
+\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x14\0\0\0\x61\x94\0\0\0\0\0\
+\0\x77\x04\0\0\x0c\0\0\0\x57\x04\0\0\xff\xff\x0f\0\x4f\x41\0\0\0\0\0\0\xaf\x81\
+\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\x04\0\0\x15\
+\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x15\0\0\0\x61\x94\0\0\0\0\0\
+\0\x77\x04\0\0\x0b\0\0\0\x57\x04\0\0\xff\xff\x1f\0\x4f\x41\0\0\0\0\0\0\xaf\x81\
+\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\x02\0\0\x15\
+\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x16\0\0\0\x61\x94\0\0\0\0\0\
+\0\x77\x04\0\0\x0a\0\0\0\x57\x04\0\0\xff\xff\x3f\0\x4f\x41\0\0\0\0\0\0\xaf\x81\
+\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\0\x01\0\0\x15\
+\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x17\0\0\0\x61\x94\0\0\0\0\0\
+\0\x77\x04\0\0\x09\0\0\0\x57\x04\0\0\xff\xff\x7f\0\x4f\x41\0\0\0\0\0\0\xaf\x81\
+\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\x80\0\0\0\x15\
+\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x18\0\0\0\x61\x94\0\0\0\0\0\
+\0\x77\x04\0\0\x08\0\0\0\x57\x04\0\0\xff\xff\xff\0\x4f\x41\0\0\0\0\0\0\xaf\x81\
+\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\x40\0\0\0\x15\
+\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x19\0\0\0\x61\x94\0\0\0\0\0\
+\0\x77\x04\0\0\x07\0\0\0\x57\x04\0\0\xff\xff\xff\x01\x4f\x41\0\0\0\0\0\0\xaf\
+\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\x20\0\0\0\
+\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x1a\0\0\0\x61\x94\0\0\0\
+\0\0\0\x77\x04\0\0\x06\0\0\0\x57\x04\0\0\xff\xff\xff\x03\x4f\x41\0\0\0\0\0\0\
+\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\x10\0\
+\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x1b\0\0\0\x61\x94\0\
+\0\0\0\0\0\x77\x04\0\0\x05\0\0\0\x57\x04\0\0\xff\xff\xff\x07\x4f\x41\0\0\0\0\0\
+\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\x08\
+\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x1c\0\0\0\x61\x94\
+\0\0\0\0\0\0\x77\x04\0\0\x04\0\0\0\x57\x04\0\0\xff\xff\xff\x0f\x4f\x41\0\0\0\0\
+\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\0\
+\x04\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x1d\0\0\0\x61\
+\x94\0\0\0\0\0\0\x77\x04\0\0\x03\0\0\0\x57\x04\0\0\xff\xff\xff\x1f\x4f\x41\0\0\
+\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xbf\x31\0\0\0\0\0\0\x57\x01\0\
+\0\x02\0\0\0\x15\x01\x08\0\0\0\0\0\x61\x21\0\0\0\0\0\0\x67\x01\0\0\x1e\0\0\0\
+\x61\x94\0\0\0\0\0\0\x77\x04\0\0\x02\0\0\0\x57\x04\0\0\xff\xff\xff\x3f\x4f\x41\
+\0\0\0\0\0\0\xaf\x81\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\x7b\x8a\x90\xff\0\0\0\0\
+\xbf\x96\0\0\0\0\0\0\x57\x03\0\0\x01\0\0\0\x15\x03\x6e\0\0\0\0\0\x61\x21\0\0\0\
+\0\0\0\x67\x01\0\0\x1f\0\0\0\x61\x62\0\0\0\0\0\0\x05\0\xa0\xef\0\0\0\0\x15\x01\
+\x63\0\x2c\0\0\0\x55\x01\xc5\xf3\x3c\0\0\0\xbf\x08\0\0\0\0\0\0\xbf\xa3\0\0\0\0\
+\0\0\x07\x03\0\0\xd0\xff\xff\xff\xbf\x61\0\0\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\
+\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x55\0\x60\0\0\0\0\0\x71\xa3\xd1\xff\0\0\
+\0\0\x67\x03\0\0\x03\0\0\0\xbf\x32\0\0\0\0\0\0\x07\x02\0\0\x30\0\0\0\x71\xa1\
+\xd0\xff\0\0\0\0\x65\x01\x04\0\x2b\0\0\0\xbf\x80\0\0\0\0\0\0\x15\x01\x05\0\0\0\
+\0\0\x15\x01\x04\0\x2b\0\0\0\x05\0\xb3\xf3\0\0\0\0\xbf\x80\0\0\0\0\0\0\x15\x01\
+\x4e\0\x2c\0\0\0\x55\x01\xb0\xf3\x3c\0\0\0\x7b\x3a\x50\xff\0\0\0\0\xbf\xa3\0\0\
+\0\0\0\0\x07\x03\0\0\xd0\xff\xff\xff\xbf\x61\0\0\0\0\0\0\xb7\x04\0\0\x02\0\0\0\
+\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x55\0\x4b\0\0\0\0\0\x71\xa1\xd1\xff\
+\0\0\0\0\x67\x01\0\0\x03\0\0\0\x79\xa4\x50\xff\0\0\0\0\x0f\x14\0\0\0\0\0\0\x07\
+\x04\0\0\x38\0\0\0\x71\xa1\xd0\xff\0\0\0\0\x65\x01\x05\0\x2b\0\0\0\xbf\x80\0\0\
+\0\0\0\0\x15\x01\x08\0\0\0\0\0\xbf\x42\0\0\0\0\0\0\x15\x01\x06\0\x2b\0\0\0\x05\
+\0\x9c\xf3\0\0\0\0\xbf\x42\0\0\0\0\0\0\xbf\x80\0\0\0\0\0\0\x15\x01\x36\0\x2c\0\
+\0\0\xbf\x42\0\0\0\0\0\0\x55\x01\x97\xf3\x3c\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\
+\0\0\xd0\xff\xff\xff\xbf\x61\0\0\0\0\0\0\x7b\x4a\x50\xff\0\0\0\0\xbf\x42\0\0\0\
+\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x55\0\
+\x31\0\0\0\0\0\x71\xa1\xd1\xff\0\0\0\0\x67\x01\0\0\x03\0\0\0\x79\xa4\x50\xff\0\
+\0\0\0\x0f\x14\0\0\0\0\0\0\x07\x04\0\0\x08\0\0\0\x71\xa1\xd0\xff\0\0\0\0\x65\
+\x01\x05\0\x2b\0\0\0\xbf\x80\0\0\0\0\0\0\x15\x01\x08\0\0\0\0\0\xbf\x42\0\0\0\0\
+\0\0\x15\x01\x06\0\x2b\0\0\0\x05\0\x82\xf3\0\0\0\0\xbf\x42\0\0\0\0\0\0\xbf\x80\
+\0\0\0\0\0\0\x15\x01\x1c\0\x2c\0\0\0\xbf\x42\0\0\0\0\0\0\x55\x01\x7d\xf3\x3c\0\
+\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xd0\xff\xff\xff\xbf\x61\0\0\0\0\0\0\x7b\
+\x4a\x50\xff\0\0\0\0\xbf\x42\0\0\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\x01\
+\0\0\0\x85\0\0\0\x44\0\0\0\x55\0\x17\0\0\0\0\0\x71\xa1\xd1\xff\0\0\0\0\x67\x01\
+\0\0\x03\0\0\0\x79\xa4\x50\xff\0\0\0\0\x0f\x14\0\0\0\0\0\0\x07\x04\0\0\x08\0\0\
+\0\x71\xa1\xd0\xff\0\0\0\0\xbf\x42\0\0\0\0\0\0\xbf\x80\0\0\0\0\0\0\x25\x01\x6b\
+\xf3\x3c\0\0\0\xb7\x03\0\0\x01\0\0\0\x6f\x13\0\0\0\0\0\0\x18\x02\0\0\x01\0\0\0\
+\0\0\0\0\0\x18\0\x10\x5f\x23\0\0\0\0\0\0\xbf\x42\0\0\0\0\0\0\x55\x03\x01\0\0\0\
+\0\0\x05\0\x63\xf3\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xd0\xff\xff\xff\xbf\
+\x61\0\0\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\
+\0\x18\x01\0\0\x1b\0\0\0\0\0\0\0\0\0\0\0\xb7\x02\0\0\x09\0\0\0\x79\xa6\x90\xff\
+\0\0\0\0\xbf\x63\0\0\0\0\0\0\x85\0\0\0\x06\0\0\0\xb7\x07\0\0\0\0\0\0\x67\x06\0\
+\0\x20\0\0\0\x77\x06\0\0\x20\0\0\0\x15\x06\x14\0\0\0\0\0\x79\xa3\x80\xff\0\0\0\
+\0\x71\x31\x2d\0\0\0\0\0\x67\x01\0\0\x08\0\0\0\x71\x32\x2c\0\0\0\0\0\x4f\x21\0\
+\0\0\0\0\0\x71\x32\x2e\0\0\0\0\0\x67\x02\0\0\x10\0\0\0\x71\x33\x2f\0\0\0\0\0\
+\x67\x03\0\0\x18\0\0\0\x4f\x23\0\0\0\0\0\0\x4f\x13\0\0\0\0\0\0\x2f\x63\0\0\0\0\
+\0\0\x77\x03\0\0\x20\0\0\0\x79\xa1\x88\xff\0\0\0\0\x63\x31\x0c\0\0\0\0\0\x18\
+\x01\0\0\x24\0\0\0\0\0\0\0\0\0\0\0\xb7\x02\0\0\x0a\0\0\0\x85\0\0\0\x06\0\0\0\
+\xb7\x07\0\0\x03\0\0\0\xbf\x70\0\0\0\0\0\0\x95\0\0\0\0\0\0\0\x72\x73\x73\x5f\
+\x66\x6c\x6f\x77\x5f\x61\x63\x74\x69\x6f\x6e\x20\x63\x6c\x61\x73\x73\x69\x64\
+\x3a\x25\x75\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x68\x61\x73\x68\x28\x29\x3a\x20\x72\x73\x73\x20\x6e\x6f\x74\x20\
+\x63\x6f\x6e\x66\x69\x67\x75\x72\x65\x64\0\x68\x61\x73\x68\x20\x25\x75\x0a\0\
+\x71\x75\x65\x75\x65\x20\x25\x75\x0a\0\x44\x75\x61\x6c\x20\x42\x53\x44\x2f\x47\
+\x50\x4c\0\x31\x4f\0\0\x05\0\x08\0\x22\0\0\0\x88\0\0\0\xa9\0\0\0\xb4\0\0\0\xd1\
+\0\0\0\xe7\0\0\0\xfd\0\0\0\x13\x01\0\0\x30\x01\0\0\x43\x01\0\0\x58\x01\0\0\x6b\
+\x01\0\0\xec\x01\0\0\xe5\x03\0\0\xf6\x03\0\0\x57\x07\0\0\x80\x07\0\0\x87\x0b\0\
+\0\x9d\x0b\0\0\xb1\x0b\0\0\xe5\x0b\0\0\xfb\x14\0\0\x45\x15\0\0\xfd\x24\0\0\xb4\
+\x28\0\0\xd3\x28\0\0\x5f\x2f\0\0\x74\x2f\0\0\x8a\x2f\0\0\xc7\x2f\0\0\xdc\x2f\0\
+\0\xf2\x2f\0\0\xfe\x2f\0\0\x35\x3b\0\0\x90\x3b\0\0\x04\0\x08\x01\x51\x04\x08\
+\xe8\x01\x01\x57\x04\xf0\x01\xa8\x02\x01\x57\x04\xd8\x02\x98\x03\x01\x57\x04\
+\xf8\x30\xa0\x31\x01\x57\0\x04\x90\x01\xc8\xed\x03\x03\x7a\xde\0\0\x04\xb8\x01\
+\xe0\x01\x01\x50\x04\xf0\x01\xd0\x02\x01\x50\x04\xd8\x02\xd8\x03\x01\x50\x04\
+\xf8\x30\xf8\x31\x01\x50\0\x04\xf8\x01\xa0\x02\x01\x52\x04\xd8\x02\xa0\x03\x01\
+\x52\x04\xf8\x30\xc0\x31\x01\x52\0\x04\xf8\x01\xa0\x02\x01\x57\x04\xd8\x02\x98\
+\x03\x01\x57\x04\xf8\x30\xa0\x31\x01\x57\0\x04\x88\x02\xa0\x02\x01\x53\x04\xd8\
+\x02\xb0\x03\x01\x53\x04\xf8\x30\xd0\x31\x01\x53\0\x04\xa0\x02\xd8\x02\x02\x30\
+\x9f\x04\xc8\xeb\x03\xe8\xeb\x03\x03\x7a\xc0\0\x04\xe8\xeb\x03\x88\xec\x03\x01\
+\x56\0\x04\x98\x03\xf8\x30\x02\x30\x9f\x04\xb0\xdf\x01\xe8\xdf\x01\x02\x30\x9f\
+\0\x04\x98\x03\xf8\x30\x03\x7a\xc8\0\x04\xb0\xdf\x01\xf0\xa0\x02\x03\x7a\xc8\0\
+\0\x04\xc0\x03\xf8\x30\x02\x7a\x38\x04\xb0\xdf\x01\xf0\xa0\x02\x02\x7a\x38\0\
+\x04\xa0\x04\xb0\x04\x05\x93\x04\x58\x93\x04\x04\xb0\x04\x98\x1b\x0a\x59\x93\
+\x04\x58\x93\x04\x30\x9f\x93\x04\x04\x98\x1b\xd0\x30\x09\x93\x04\x58\x93\x04\
+\x30\x9f\x93\x04\x04\xd0\x30\xf8\x30\x06\x93\x08\x30\x9f\x93\x04\x04\xb0\xdf\
+\x01\xb8\xe0\x01\x0a\x59\x93\x04\x58\x93\x04\x30\x9f\x93\x04\x04\xb8\xe0\x01\
+\xa8\xf5\x01\x06\x59\x93\x04\x58\x93\x04\x04\xa8\xf5\x01\xf8\x8a\x02\x05\x93\
+\x04\x58\x93\x04\x04\xf8\x8a\x02\x80\x8b\x02\x08\x93\x04\x58\x93\x04\x53\x93\
+\x04\x04\x80\x8b\x02\xa8\xa0\x02\x05\x93\x08\x53\x93\x04\0\x04\xe0\x04\xb0\x05\
+\x02\x31\x9f\x04\xb0\x05\x90\x06\x02\x32\x9f\x04\x90\x06\xf0\x06\x02\x33\x9f\
+\x04\xf0\x06\xd0\x07\x02\x34\x9f\x04\xd0\x07\xb0\x08\x02\x35\x9f\x04\xb0\x08\
+\x90\x09\x02\x36\x9f\x04\x90\x09\xf0\x09\x02\x37\x9f\x04\xf0\x09\xd0\x0a\x02\
+\x38\x9f\x04\xd0\x0a\xb0\x0b\x02\x39\x9f\x04\xb0\x0b\x90\x0c\x02\x3a\x9f\x04\
+\x90\x0c\xf0\x0c\x02\x3b\x9f\x04\xf0\x0c\xd0\x0d\x02\x3c\x9f\x04\xd0\x0d\xb0\
+\x0e\x02\x3d\x9f\x04\xb0\x0e\x90\x0f\x02\x3e\x9f\x04\x90\x0f\xf0\x0f\x02\x3f\
+\x9f\x04\xf0\x0f\xd0\x10\x02\x40\x9f\x04\xd0\x10\xb0\x11\x02\x41\x9f\x04\xb0\
+\x11\x90\x12\x02\x42\x9f\x04\x90\x12\xf0\x12\x02\x43\x9f\x04\xf0\x12\xd0\x13\
+\x02\x44\x9f\x04\xd0\x13\xb0\x14\x02\x45\x9f\x04\xb0\x14\x90\x15\x02\x46\x9f\
+\x04\x90\x15\xf0\x15\x02\x47\x9f\x04\xf0\x15\xd0\x16\x02\x48\x9f\x04\xd0\x16\
+\xb0\x17\x02\x49\x9f\x04\xb0\x17\x90\x18\x02\x4a\x9f\x04\x90\x18\xf0\x18\x02\
+\x4b\x9f\x04\xf0\x18\xd0\x19\x02\x4c\x9f\x04\xd0\x19\xb0\x1a\x02\x4d\x9f\x04\
+\xb0\x1a\x90\x1b\x02\x4e\x9f\x04\x90\x1b\xe8\x1b\x02\x4f\x9f\x04\xe8\x1b\xf0\
+\x1b\x02\x30\x9f\x04\xf0\x1b\xc8\x1c\x02\x31\x9f\x04\xc8\x1c\xa0\x1d\x02\x32\
+\x9f\x04\xa0\x1d\xf8\x1d\x02\x33\x9f\x04\xf8\x1d\xd0\x1e\x02\x34\x9f\x04\xd0\
+\x1e\xa8\x1f\x02\x35\x9f\x04\xa8\x1f\x80\x20\x02\x36\x9f\x04\x80\x20\xd8\x20\
+\x02\x37\x9f\x04\xd8\x20\xb0\x21\x02\x38\x9f\x04\xb0\x21\x88\x22\x02\x39\x9f\
+\x04\x88\x22\xe0\x22\x02\x3a\x9f\x04\xe0\x22\xb8\x23\x02\x3b\x9f\x04\xb8\x23\
+\x90\x24\x02\x3c\x9f\x04\x90\x24\xe8\x24\x02\x3d\x9f\x04\xe8\x24\xc0\x25\x02\
+\x3e\x9f\x04\xc0\x25\x98\x26\x02\x3f\x9f\x04\x98\x26\xf0\x26\x02\x40\x9f\x04\
+\xf0\x26\xc8\x27\x02\x41\x9f\x04\xc8\x27\xa0\x28\x02\x42\x9f\x04\xa0\x28\xf8\
+\x28\x02\x43\x9f\x04\xf8\x28\xd0\x29\x02\x44\x9f\x04\xd0\x29\xa8\x2a\x02\x45\
+\x9f\x04\xa8\x2a\x80\x2b\x02\x46\x9f\x04\x80\x2b\xd8\x2b\x02\x47\x9f\x04\xd8\
+\x2b\xb0\x2c\x02\x48\x9f\x04\xb0\x2c\x88\x2d\x02\x49\x9f\x04\x88\x2d\xe0\x2d\
+\x02\x4a\x9f\x04\xe0\x2d\xb8\x2e\x02\x4b\x9f\x04\xb8\x2e\x90\x2f\x02\x4c\x9f\
+\x04\x90\x2f\xe8\x2f\x02\x4d\x9f\x04\xe8\x2f\xc0\x30\x02\x4e\x9f\x04\xc0\x30\
+\xf8\x30\x02\x4f\x9f\0\x04\xe0\x04\xe8\x1b\x02\x30\x9f\x04\xe8\x1b\xf8\x30\x02\
+\x31\x9f\0\x04\xe0\x04\xb0\x05\x02\x30\x9f\x04\xb0\x05\x88\x06\x01\x55\x04\x88\
+\x06\x90\x06\x01\x52\x04\x90\x06\xe8\x06\x01\x55\x04\xe8\x06\xf0\x06\x01\x52\
+\x04\xf0\x06\xc8\x07\x01\x55\x04\xc8\x07\xd0\x07\x01\x52\x04\xd0\x07\xa8\x08\
+\x01\x55\x04\xa8\x08\xb0\x08\x01\x52\x04\xb0\x08\x88\x09\x01\x55\x04\x88\x09\
+\x90\x09\x01\x52\x04\x90\x09\xe8\x09\x01\x55\x04\xe8\x09\xf0\x09\x01\x52\x04\
+\xf0\x09\xc8\x0a\x01\x55\x04\xc8\x0a\xd0\x0a\x01\x52\x04\xd0\x0a\xa8\x0b\x01\
+\x55\x04\xa8\x0b\xb0\x0b\x01\x52\x04\xb0\x0b\x88\x0c\x01\x55\x04\x88\x0c\x90\
+\x0c\x01\x52\x04\x90\x0c\xe8\x0c\x01\x55\x04\xe8\x0c\xf0\x0c\x01\x52\x04\xf0\
+\x0c\xc8\x0d\x01\x55\x04\xc8\x0d\xd0\x0d\x01\x52\x04\xd0\x0d\xa8\x0e\x01\x55\
+\x04\xa8\x0e\xb0\x0e\x01\x52\x04\xb0\x0e\x88\x0f\x01\x55\x04\x88\x0f\x90\x0f\
+\x01\x52\x04\x90\x0f\xe8\x0f\x01\x55\x04\xe8\x0f\xf0\x0f\x01\x52\x04\xf0\x0f\
+\xc8\x10\x01\x55\x04\xc8\x10\xd0\x10\x01\x52\x04\xd0\x10\xa8\x11\x01\x55\x04\
+\xa8\x11\xb0\x11\x01\x52\x04\xb0\x11\x88\x12\x01\x55\x04\x88\x12\x90\x12\x01\
+\x52\x04\x90\x12\xe8\x12\x01\x55\x04\xe8\x12\xf0\x12\x01\x52\x04\xf0\x12\xc8\
+\x13\x01\x55\x04\xc8\x13\xd0\x13\x01\x52\x04\xd0\x13\xa8\x14\x01\x55\x04\xa8\
+\x14\xb0\x14\x01\x52\x04\xb0\x14\x88\x15\x01\x55\x04\x88\x15\x90\x15\x01\x52\
+\x04\x90\x15\xe8\x15\x01\x55\x04\xe8\x15\xf0\x15\x01\x52\x04\xf0\x15\xc8\x16\
+\x01\x55\x04\xc8\x16\xd0\x16\x01\x52\x04\xd0\x16\xa8\x17\x01\x55\x04\xa8\x17\
+\xb0\x17\x01\x52\x04\xb0\x17\x88\x18\x01\x55\x04\x88\x18\x90\x18\x01\x52\x04\
+\x90\x18\xe8\x18\x01\x55\x04\xe8\x18\xf0\x18\x01\x52\x04\xf0\x18\xc8\x19\x01\
+\x55\x04\xc8\x19\xd0\x19\x01\x52\x04\xd0\x19\xa8\x1a\x01\x55\x04\xa8\x1a\xb0\
+\x1a\x01\x52\x04\xb0\x1a\x88\x1b\x01\x55\x04\x88\x1b\x90\x1b\x01\x52\x04\x90\
+\x1b\xe0\x1b\x01\x55\x04\xe0\x1b\xe8\x1b\x01\x52\x04\xe8\x1b\xc0\x1c\x01\x55\
+\x04\xc0\x1c\xc8\x1c\x01\x52\x04\xc8\x1c\x98\x1d\x01\x55\x04\x98\x1d\xa0\x1d\
+\x01\x52\x04\xa0\x1d\xf0\x1d\x01\x55\x04\xf0\x1d\xf8\x1d\x01\x52\x04\xf8\x1d\
+\xc8\x1e\x01\x55\x04\xc8\x1e\xd0\x1e\x01\x52\x04\xd0\x1e\xa0\x1f\x01\x55\x04\
+\xa0\x1f\xa8\x1f\x01\x52\x04\xa8\x1f\xf8\x1f\x01\x55\x04\xf8\x1f\x80\x20\x01\
+\x52\x04\x80\x20\xd0\x20\x01\x55\x04\xd0\x20\xd8\x20\x01\x52\x04\xd8\x20\xa8\
+\x21\x01\x55\x04\xa8\x21\xb0\x21\x01\x52\x04\xb0\x21\x80\x22\x01\x55\x04\x80\
+\x22\x88\x22\x01\x52\x04\x88\x22\xd8\x22\x01\x55\x04\xd8\x22\xe0\x22\x01\x52\
+\x04\xe0\x22\xb0\x23\x01\x55\x04\xb0\x23\xb8\x23\x01\x52\x04\xb8\x23\x88\x24\
+\x01\x55\x04\x88\x24\x90\x24\x01\x52\x04\x90\x24\xe0\x24\x01\x55\x04\xe0\x24\
+\xe8\x24\x01\x52\x04\xe8\x24\xb8\x25\x01\x55\x04\xb8\x25\xc0\x25\x01\x52\x04\
+\xc0\x25\x90\x26\x01\x55\x04\x90\x26\x98\x26\x01\x52\x04\x98\x26\xe8\x26\x01\
+\x55\x04\xe8\x26\xf0\x26\x01\x52\x04\xf0\x26\xc0\x27\x01\x55\x04\xc0\x27\xc8\
+\x27\x01\x52\x04\xc8\x27\x98\x28\x01\x55\x04\x98\x28\xa0\x28\x01\x52\x04\xa0\
+\x28\xf0\x28\x01\x55\x04\xf0\x28\xf8\x28\x01\x52\x04\xf8\x28\xc8\x29\x01\x55\
+\x04\xc8\x29\xd0\x29\x01\x52\x04\xd0\x29\xa0\x2a\x01\x55\x04\xa0\x2a\xa8\x2a\
+\x01\x52\x04\xa8\x2a\xf8\x2a\x01\x55\x04\xf8\x2a\x80\x2b\x01\x52\x04\x80\x2b\
+\xd0\x2b\x01\x55\x04\xd0\x2b\xd8\x2b\x01\x52\x04\xd8\x2b\xa8\x2c\x01\x55\x04\
+\xa8\x2c\xb0\x2c\x01\x52\x04\xb0\x2c\x80\x2d\x01\x55\x04\x80\x2d\x88\x2d\x01\
+\x52\x04\x88\x2d\xd8\x2d\x01\x55\x04\xd8\x2d\xe0\x2d\x01\x52\x04\xe0\x2d\xb0\
+\x2e\x01\x55\x04\xb0\x2e\xb8\x2e\x01\x52\x04\xb8\x2e\x88\x2f\x01\x55\x04\x88\
+\x2f\x90\x2f\x01\x52\x04\x90\x2f\xe0\x2f\x01\x55\x04\xe0\x2f\xe8\x2f\x01\x52\
+\x04\xe8\x2f\xb8\x30\x01\x55\x04\xb8\x30\xc0\x30\x01\x52\x04\xc0\x30\xc8\x30\
+\x01\x55\x04\xc8\x30\xf8\x30\x03\x7a\xc0\0\0\x04\xb8\x31\xf8\xde\x01\x02\x30\
+\x9f\x04\x80\xa1\x02\xc0\xa1\x02\x03\x10\x28\x9f\x04\xc0\xa1\x02\xf8\xa1\x02\
+\x01\x52\x04\xf8\xe4\x03\xc8\xeb\x03\x03\x10\x28\x9f\0\x04\xb8\x31\xc0\x32\x24\
+\x30\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\
+\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x04\xc0\
+\x32\xc8\x32\x23\x30\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\
+\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x51\x93\x04\x30\x9f\x93\
+\x04\x04\xc8\x32\xd8\x32\x24\x30\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\
+\x30\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x7a\x18\x93\
+\x04\x30\x9f\x93\x04\x04\xd8\x32\xe0\x32\x23\x30\x9f\x93\x04\x30\x9f\x93\x04\
+\x30\x9f\x93\x04\x51\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\
+\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\xe0\x32\xf0\x32\x24\x30\x9f\x93\x04\x30\
+\x9f\x93\x04\x30\x9f\x93\x04\x7a\x20\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\
+\x30\x9f\x93\x04\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\xf0\x32\x80\x33\x23\x30\
+\x9f\x93\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x7a\x20\x93\x04\x30\x9f\x93\x04\
+\x30\x9f\x93\x04\x50\x93\x04\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\x80\x33\x88\
+\x33\x22\x30\x9f\x93\x04\x30\x9f\x93\x04\x51\x93\x04\x7a\x20\x93\x04\x30\x9f\
+\x93\x04\x30\x9f\x93\x04\x50\x93\x04\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\x88\
+\x33\x98\x33\x24\x30\x9f\x93\x04\x30\x9f\x93\x04\x7a\xd0\0\x93\x04\x7a\x20\x93\
+\x04\x30\x9f\x93\x04\x30\x9f\x93\x04\x50\x93\x04\x7a\x18\x93\x04\x30\x9f\x93\
+\x04\x04\x98\x33\xa0\x33\x23\x30\x9f\x93\x04\x30\x9f\x93\x04\x7a\xd0\0\x93\x04\
+\x7a\x20\x93\x04\x30\x9f\x93\x04\x51\x93\x04\x50\x93\x04\x7a\x18\x93\x04\x30\
+\x9f\x93\x04\x04\xa0\x33\xb0\x33\x24\x30\x9f\x93\x04\x30\x9f\x93\x04\x7a\xd0\0\
+\x93\x04\x7a\x20\x93\x04\x30\x9f\x93\x04\x7a\x08\x93\x04\x50\x93\x04\x7a\x18\
+\x93\x04\x30\x9f\x93\x04\x04\xb0\x33\xc0\x33\x23\x30\x9f\x93\x04\x57\x93\x04\
+\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x30\x9f\x93\x04\x7a\x08\x93\x04\x50\x93\x04\
+\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\xc0\x33\xc8\x33\x22\x30\x9f\x93\x04\x57\
+\x93\x04\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x51\x93\x04\x7a\x08\x93\x04\x50\x93\
+\x04\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\xc8\x33\xd8\x33\x23\x30\x9f\x93\x04\
+\x57\x93\x04\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\x10\x93\x04\x7a\x08\x93\x04\
+\x50\x93\x04\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\xd8\x33\xe0\x48\x22\x59\x93\
+\x04\x57\x93\x04\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\x10\x93\x04\x7a\x08\x93\
+\x04\x50\x93\x04\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\xe0\x48\x98\x5e\x21\x93\
+\x04\x57\x93\x04\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\x10\x93\x04\x7a\x08\x93\
+\x04\x50\x93\x04\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\x98\x5e\xa0\xc9\x01\x1e\
+\x93\x08\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\x10\x93\x04\x7a\x08\x93\x04\x50\
+\x93\x04\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\xa0\xc9\x01\xf8\xde\x01\x1d\x93\
+\x08\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\x10\x93\x04\x7a\x08\x93\x04\x93\x04\
+\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\x80\xa1\x02\xb0\xa1\x02\x22\x59\x93\x04\
+\x57\x93\x04\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\x10\x93\x04\x7a\x08\x93\x04\
+\x50\x93\x04\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\xb0\xa1\x02\x80\xa2\x02\x21\
+\x59\x93\x04\x57\x93\x04\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\x10\x93\x04\x7a\
+\x08\x93\x04\x93\x04\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\x80\xa2\x02\xf8\xb8\
+\x02\x1d\x59\x93\x04\x57\x93\x04\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\x10\x93\
+\x04\x7a\x08\x93\x04\x93\x04\x7a\x18\x93\x04\x04\xf8\xb8\x02\xb8\xce\x02\x1c\
+\x93\x04\x57\x93\x04\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\x10\x93\x04\x7a\x08\
+\x93\x04\x93\x04\x7a\x18\x93\x04\x04\xb8\xce\x02\x90\xcf\x03\x19\x93\x08\x7a\
+\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\x10\x93\x04\x7a\x08\x93\x04\x93\x04\x7a\x18\
+\x93\x04\x04\x90\xcf\x03\xd0\xe4\x03\x1c\x93\x08\x7a\xd0\0\x93\x04\x7a\x20\x93\
+\x04\x7a\x10\x93\x04\x7a\x08\x93\x04\x93\x04\x7a\x18\x93\x04\x53\x93\x04\x04\
+\xd0\xe4\x03\xf8\xe4\x03\x19\x93\x08\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\x10\
+\x93\x04\x7a\x08\x93\x04\x93\x04\x7a\x18\x93\x04\x04\xf8\xe4\x03\xc0\xe5\x03\
+\x22\x59\x93\x04\x57\x93\x04\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\x10\x93\x04\
+\x7a\x08\x93\x04\x50\x93\x04\x7a\x18\x93\x04\x30\x9f\x93\x04\x04\xc0\xe5\x03\
+\xc8\xeb\x03\x21\x59\x93\x04\x57\x93\x04\x7a\xd0\0\x93\x04\x7a\x20\x93\x04\x7a\
+\x10\x93\x04\x7a\x08\x93\x04\x93\x04\x7a\x18\x93\x04\x30\x9f\x93\x04\0\x04\xb8\
+\x31\xf8\xde\x01\x03\x7a\xc8\0\x04\x80\xa1\x02\xc8\xeb\x03\x03\x7a\xc8\0\0\x04\
+\xe0\x31\xf8\xde\x01\x02\x7a\x38\x04\x80\xa1\x02\xc8\xeb\x03\x02\x7a\x38\0\x04\
+\xb0\x32\xc0\x32\x02\x30\x9f\x04\xc0\x32\xf0\x32\x02\x33\x9f\x04\xf0\x32\x98\
+\x33\x02\x32\x9f\x04\x98\x33\xd8\x33\x02\x31\x9f\x04\xd8\x33\xf8\xde\x01\x02\
+\x34\x9f\x04\x80\xa1\x02\xc8\xeb\x03\x02\x34\x9f\0\x04\xf8\x33\xd0\x34\x02\x31\
+\x9f\x04\xd0\x34\xb0\x35\x02\x32\x9f\x04\xb0\x35\x90\x36\x02\x33\x9f\x04\x90\
+\x36\xe8\x36\x02\x34\x9f\x04\xe8\x36\xc0\x37\x02\x35\x9f\x04\xc0\x37\x98\x38\
+\x02\x36\x9f\x04\x98\x38\xf0\x38\x02\x37\x9f\x04\xf0\x38\xc8\x39\x02\x38\x9f\
+\x04\xc8\x39\xa0\x3a\x02\x39\x9f\x04\xa0\x3a\xf8\x3a\x02\x3a\x9f\x04\xf8\x3a\
+\xd0\x3b\x02\x3b\x9f\x04\xd0\x3b\xa8\x3c\x02\x3c\x9f\x04\xa8\x3c\x80\x3d\x02\
+\x3d\x9f\x04\x80\x3d\xd8\x3d\x02\x3e\x9f\x04\xd8\x3d\xb0\x3e\x02\x3f\x9f\x04\
+\xb0\x3e\x88\x3f\x02\x40\x9f\x04\x88\x3f\xe0\x3f\x02\x41\x9f\x04\xe0\x3f\xb8\
+\x40\x02\x42\x9f\x04\xb8\x40\x90\x41\x02\x43\x9f\x04\x90\x41\xe8\x41\x02\x44\
+\x9f\x04\xe8\x41\xc0\x42\x02\x45\x9f\x04\xc0\x42\x98\x43\x02\x46\x9f\x04\x98\
+\x43\xf0\x43\x02\x47\x9f\x04\xf0\x43\xc8\x44\x02\x48\x9f\x04\xc8\x44\xa0\x45\
+\x02\x49\x9f\x04\xa0\x45\xf8\x45\x02\x4a\x9f\x04\xf8\x45\xd0\x46\x02\x4b\x9f\
+\x04\xd0\x46\xa8\x47\x02\x4c\x9f\x04\xa8\x47\x80\x48\x02\x4d\x9f\x04\x80\x48\
+\xd8\x48\x02\x4e\x9f\x04\xd8\x48\xa8\x49\x02\x4f\x9f\x04\xa8\x49\xb8\x49\x02\
+\x30\x9f\x04\xb8\x49\x90\x4a\x02\x31\x9f\x04\x90\x4a\xf0\x4a\x02\x32\x9f\x04\
+\xf0\x4a\xc8\x4b\x02\x33\x9f\x04\xc8\x4b\xa0\x4c\x02\x34\x9f\x04\xa0\x4c\xf8\
+\x4c\x02\x35\x9f\x04\xf8\x4c\xd0\x4d\x02\x36\x9f\x04\xd0\x4d\xa8\x4e\x02\x37\
+\x9f\x04\xa8\x4e\x80\x4f\x02\x38\x9f\x04\x80\x4f\xd8\x4f\x02\x39\x9f\x04\xd8\
+\x4f\xb0\x50\x02\x3a\x9f\x04\xb0\x50\x88\x51\x02\x3b\x9f\x04\x88\x51\xe0\x51\
+\x02\x3c\x9f\x04\xe0\x51\xb8\x52\x02\x3d\x9f\x04\xb8\x52\x90\x53\x02\x3e\x9f\
+\x04\x90\x53\xe8\x53\x02\x3f\x9f\x04\xe8\x53\xc0\x54\x02\x40\x9f\x04\xc0\x54\
+\x98\x55\x02\x41\x9f\x04\x98\x55\xf0\x55\x02\x42\x9f\x04\xf0\x55\xc8\x56\x02\
+\x43\x9f\x04\xc8\x56\xa0\x57\x02\x44\x9f\x04\xa0\x57\xf8\x57\x02\x45\x9f\x04\
+\xf8\x57\xd0\x58\x02\x46\x9f\x04\xd0\x58\xa8\x59\x02\x47\x9f\x04\xa8\x59\x80\
+\x5a\x02\x48\x9f\x04\x80\x5a\xd8\x5a\x02\x49\x9f\x04\xd8\x5a\xb0\x5b\x02\x4a\
+\x9f\x04\xb0\x5b\x88\x5c\x02\x4b\x9f\x04\x88\x5c\xe0\x5c\x02\x4c\x9f\x04\xe0\
+\x5c\xb8\x5d\x02\x4d\x9f\x04\xb8\x5d\x90\x5e\x02\x4e\x9f\x04\x90\x5e\xe0\x5e\
+\x02\x4f\x9f\x04\xe0\x5e\xf8\x5e\x02\x30\x9f\x04\xf8\x5e\xd0\x5f\x02\x31\x9f\
+\x04\xd0\x5f\xa8\x60\x02\x32\x9f\x04\xa8\x60\x80\x61\x02\x33\x9f\x04\x80\x61\
+\xd8\x61\x02\x34\x9f\x04\xd8\x61\xb0\x62\x02\x35\x9f\x04\xb0\x62\x88\x63\x02\
+\x36\x9f\x04\x88\x63\xe0\x63\x02\x37\x9f\x04\xe0\x63\xb8\x64\x02\x38\x9f\x04\
+\xb8\x64\x90\x65\x02\x39\x9f\x04\x90\x65\xe8\x65\x02\x3a\x9f\x04\xe8\x65\xc0\
+\x66\x02\x3b\x9f\x04\xc0\x66\x98\x67\x02\x3c\x9f\x04\x98\x67\xf0\x67\x02\x3d\
+\x9f\x04\xf0\x67\xc8\x68\x02\x3e\x9f\x04\xc8\x68\xa0\x69\x02\x3f\x9f\x04\xa0\
+\x69\xf8\x69\x02\x40\x9f\x04\xf8\x69\xd0\x6a\x02\x41\x9f\x04\xd0\x6a\xa8\x6b\
+\x02\x42\x9f\x04\xa8\x6b\x80\x6c\x02\x43\x9f\x04\x80\x6c\xd8\x6c\x02\x44\x9f\
+\x04\xd8\x6c\xb0\x6d\x02\x45\x9f\x04\xb0\x6d\x88\x6e\x02\x46\x9f\x04\x88\x6e\
+\xe0\x6e\x02\x47\x9f\x04\xe0\x6e\xb8\x6f\x02\x48\x9f\x04\xb8\x6f\x90\x70\x02\
+\x49\x9f\x04\x90\x70\xe8\x70\x02\x4a\x9f\x04\xe8\x70\xc0\x71\x02\x4b\x9f\x04\
+\xc0\x71\x98\x72\x02\x4c\x9f\x04\x98\x72\xf0\x72\x02\x4d\x9f\x04\xf0\x72\xc8\
+\x73\x02\x4e\x9f\x04\xc8\x73\xa0\x74\x02\x4f\x9f\x04\xa0\x74\xb0\x74\x02\x30\
+\x9f\x04\xb0\x74\x88\x75\x02\x31\x9f\x04\x88\x75\xe0\x75\x02\x32\x9f\x04\xe0\
+\x75\xb8\x76\x02\x33\x9f\x04\xb8\x76\x90\x77\x02\x34\x9f\x04\x90\x77\xe8\x77\
+\x02\x35\x9f\x04\xe8\x77\xc0\x78\x02\x36\x9f\x04\xc0\x78\x98\x79\x02\x37\x9f\
+\x04\x98\x79\xf0\x79\x02\x38\x9f\x04\xf0\x79\xc8\x7a\x02\x39\x9f\x04\xc8\x7a\
+\xa0\x7b\x02\x3a\x9f\x04\xa0\x7b\xf8\x7b\x02\x3b\x9f\x04\xf8\x7b\xd0\x7c\x02\
+\x3c\x9f\x04\xd0\x7c\xa8\x7d\x02\x3d\x9f\x04\xa8\x7d\x80\x7e\x02\x3e\x9f\x04\
+\x80\x7e\xd8\x7e\x02\x3f\x9f\x04\xd8\x7e\xb0\x7f\x02\x40\x9f\x04\xb0\x7f\x88\
+\x80\x01\x02\x41\x9f\x04\x88\x80\x01\xe0\x80\x01\x02\x42\x9f\x04\xe0\x80\x01\
+\xb8\x81\x01\x02\x43\x9f\x04\xb8\x81\x01\x90\x82\x01\x02\x44\x9f\x04\x90\x82\
+\x01\xe8\x82\x01\x02\x45\x9f\x04\xe8\x82\x01\xc0\x83\x01\x02\x46\x9f\x04\xc0\
+\x83\x01\x98\x84\x01\x02\x47\x9f\x04\x98\x84\x01\xf0\x84\x01\x02\x48\x9f\x04\
+\xf0\x84\x01\xc8\x85\x01\x02\x49\x9f\x04\xc8\x85\x01\xa0\x86\x01\x02\x4a\x9f\
+\x04\xa0\x86\x01\xf8\x86\x01\x02\x4b\x9f\x04\xf8\x86\x01\xd0\x87\x01\x02\x4c\
+\x9f\x04\xd0\x87\x01\xa8\x88\x01\x02\x4d\x9f\x04\xa8\x88\x01\x80\x89\x01\x02\
+\x4e\x9f\x04\x80\x89\x01\xd0\x89\x01\x02\x4f\x9f\x04\xd0\x89\x01\xe0\x89\x01\
+\x02\x30\x9f\x04\xe0\x89\x01\xb8\x8a\x01\x02\x31\x9f\x04\xb8\x8a\x01\x90\x8b\
+\x01\x02\x32\x9f\x04\x90\x8b\x01\xe8\x8b\x01\x02\x33\x9f\x04\xe8\x8b\x01\xc0\
+\x8c\x01\x02\x34\x9f\x04\xc0\x8c\x01\x98\x8d\x01\x02\x35\x9f\x04\x98\x8d\x01\
+\xf0\x8d\x01\x02\x36\x9f\x04\xf0\x8d\x01\xc8\x8e\x01\x02\x37\x9f\x04\xc8\x8e\
+\x01\xa0\x8f\x01\x02\x38\x9f\x04\xa0\x8f\x01\xf8\x8f\x01\x02\x39\x9f\x04\xf8\
+\x8f\x01\xd0\x90\x01\x02\x3a\x9f\x04\xd0\x90\x01\xa8\x91\x01\x02\x3b\x9f\x04\
+\xa8\x91\x01\x80\x92\x01\x02\x3c\x9f\x04\x80\x92\x01\xd8\x92\x01\x02\x3d\x9f\
+\x04\xd8\x92\x01\xb0\x93\x01\x02\x3e\x9f\x04\xb0\x93\x01\x88\x94\x01\x02\x3f\
+\x9f\x04\x88\x94\x01\xe0\x94\x01\x02\x40\x9f\x04\xe0\x94\x01\xb8\x95\x01\x02\
+\x41\x9f\x04\xb8\x95\x01\x90\x96\x01\x02\x42\x9f\x04\x90\x96\x01\xe8\x96\x01\
+\x02\x43\x9f\x04\xe8\x96\x01\xc0\x97\x01\x02\x44\x9f\x04\xc0\x97\x01\x98\x98\
+\x01\x02\x45\x9f\x04\x98\x98\x01\xf0\x98\x01\x02\x46\x9f\x04\xf0\x98\x01\xc8\
+\x99\x01\x02\x47\x9f\x04\xc8\x99\x01\xa0\x9a\x01\x02\x48\x9f\x04\xa0\x9a\x01\
+\xf8\x9a\x01\x02\x49\x9f\x04\xf8\x9a\x01\xd0\x9b\x01\x02\x4a\x9f\x04\xd0\x9b\
+\x01\xa8\x9c\x01\x02\x4b\x9f\x04\xa8\x9c\x01\x80\x9d\x01\x02\x4c\x9f\x04\x80\
+\x9d\x01\xd8\x9d\x01\x02\x4d\x9f\x04\xd8\x9d\x01\xb0\x9e\x01\x02\x4e\x9f\x04\
+\xb0\x9e\x01\x80\x9f\x01\x02\x4f\x9f\x04\x80\x9f\x01\x90\x9f\x01\x02\x30\x9f\
+\x04\x90\x9f\x01\xe8\x9f\x01\x02\x31\x9f\x04\xe8\x9f\x01\xc0\xa0\x01\x02\x32\
+\x9f\x04\xc0\xa0\x01\x98\xa1\x01\x02\x33\x9f\x04\x98\xa1\x01\xf0\xa1\x01\x02\
+\x34\x9f\x04\xf0\xa1\x01\xc8\xa2\x01\x02\x35\x9f\x04\xc8\xa2\x01\xa0\xa3\x01\
+\x02\x36\x9f\x04\xa0\xa3\x01\xf8\xa3\x01\x02\x37\x9f\x04\xf8\xa3\x01\xd0\xa4\
+\x01\x02\x38\x9f\x04\xd0\xa4\x01\xa8\xa5\x01\x02\x39\x9f\x04\xa8\xa5\x01\x80\
+\xa6\x01\x02\x3a\x9f\x04\x80\xa6\x01\xd8\xa6\x01\x02\x3b\x9f\x04\xd8\xa6\x01\
+\xb0\xa7\x01\x02\x3c\x9f\x04\xb0\xa7\x01\x88\xa8\x01\x02\x3d\x9f\x04\x88\xa8\
+\x01\xe0\xa8\x01\x02\x3e\x9f\x04\xe0\xa8\x01\xb8\xa9\x01\x02\x3f\x9f\x04\xb8\
+\xa9\x01\x90\xaa\x01\x02\x40\x9f\x04\x90\xaa\x01\xe8\xaa\x01\x02\x41\x9f\x04\
+\xe8\xaa\x01\xc0\xab\x01\x02\x42\x9f\x04\xc0\xab\x01\x98\xac\x01\x02\x43\x9f\
+\x04\x98\xac\x01\xf0\xac\x01\x02\x44\x9f\x04\xf0\xac\x01\xc8\xad\x01\x02\x45\
+\x9f\x04\xc8\xad\x01\xa0\xae\x01\x02\x46\x9f\x04\xa0\xae\x01\xf8\xae\x01\x02\
+\x47\x9f\x04\xf8\xae\x01\xd0\xaf\x01\x02\x48\x9f\x04\xd0\xaf\x01\xa8\xb0\x01\
+\x02\x49\x9f\x04\xa8\xb0\x01\x80\xb1\x01\x02\x4a\x9f\x04\x80\xb1\x01\xd8\xb1\
+\x01\x02\x4b\x9f\x04\xd8\xb1\x01\xb0\xb2\x01\x02\x4c\x9f\x04\xb0\xb2\x01\x88\
+\xb3\x01\x02\x4d\x9f\x04\x88\xb3\x01\xe0\xb3\x01\x02\x4e\x9f\x04\xe0\xb3\x01\
+\xb0\xb4\x01\x02\x4f\x9f\x04\xb0\xb4\x01\xc0\xb4\x01\x02\x30\x9f\x04\xc0\xb4\
+\x01\x98\xb5\x01\x02\x31\x9f\x04\x98\xb5\x01\xf8\xb5\x01\x02\x32\x9f\x04\xf8\
+\xb5\x01\xd0\xb6\x01\x02\x33\x9f\x04\xd0\xb6\x01\xa8\xb7\x01\x02\x34\x9f\x04\
+\xa8\xb7\x01\x80\xb8\x01\x02\x35\x9f\x04\x80\xb8\x01\xd8\xb8\x01\x02\x36\x9f\
+\x04\xd8\xb8\x01\xb0\xb9\x01\x02\x37\x9f\x04\xb0\xb9\x01\x88\xba\x01\x02\x38\
+\x9f\x04\x88\xba\x01\xe0\xba\x01\x02\x39\x9f\x04\xe0\xba\x01\xb8\xbb\x01\x02\
+\x3a\x9f\x04\xb8\xbb\x01\x90\xbc\x01\x02\x3b\x9f\x04\x90\xbc\x01\xe8\xbc\x01\
+\x02\x3c\x9f\x04\xe8\xbc\x01\xc0\xbd\x01\x02\x3d\x9f\x04\xc0\xbd\x01\x98\xbe\
+\x01\x02\x3e\x9f\x04\x98\xbe\x01\xf0\xbe\x01\x02\x3f\x9f\x04\xf0\xbe\x01\xc8\
+\xbf\x01\x02\x40\x9f\x04\xc8\xbf\x01\xa0\xc0\x01\x02\x41\x9f\x04\xa0\xc0\x01\
+\xf8\xc0\x01\x02\x42\x9f\x04\xf8\xc0\x01\xd0\xc1\x01\x02\x43\x9f\x04\xd0\xc1\
+\x01\xa8\xc2\x01\x02\x44\x9f\x04\xa8\xc2\x01\x80\xc3\x01\x02\x45\x9f\x04\x80\
+\xc3\x01\xd8\xc3\x01\x02\x46\x9f\x04\xd8\xc3\x01\xb0\xc4\x01\x02\x47\x9f\x04\
+\xb0\xc4\x01\x88\xc5\x01\x02\x48\x9f\x04\x88\xc5\x01\xe0\xc5\x01\x02\x49\x9f\
+\x04\xe0\xc5\x01\xb8\xc6\x01\x02\x4a\x9f\x04\xb8\xc6\x01\x90\xc7\x01\x02\x4b\
+\x9f\x04\x90\xc7\x01\xe8\xc7\x01\x02\x4c\x9f\x04\xe8\xc7\x01\xc0\xc8\x01\x02\
+\x4d\x9f\x04\xc0\xc8\x01\x98\xc9\x01\x02\x4e\x9f\x04\x98\xc9\x01\xe8\xc9\x01\
+\x02\x4f\x9f\x04\xe8\xc9\x01\xf0\xc9\x01\x02\x30\x9f\x04\xf0\xc9\x01\xc8\xca\
+\x01\x02\x31\x9f\x04\xc8\xca\x01\xa0\xcb\x01\x02\x32\x9f\x04\xa0\xcb\x01\xf8\
+\xcb\x01\x02\x33\x9f\x04\xf8\xcb\x01\xd0\xcc\x01\x02\x34\x9f\x04\xd0\xcc\x01\
+\xa8\xcd\x01\x02\x35\x9f\x04\xa8\xcd\x01\x80\xce\x01\x02\x36\x9f\x04\x80\xce\
+\x01\xd8\xce\x01\x02\x37\x9f\x04\xd8\xce\x01\xb0\xcf\x01\x02\x38\x9f\x04\xb0\
+\xcf\x01\x88\xd0\x01\x02\x39\x9f\x04\x88\xd0\x01\xe0\xd0\x01\x02\x3a\x9f\x04\
+\xe0\xd0\x01\xb8\xd1\x01\x02\x3b\x9f\x04\xb8\xd1\x01\x90\xd2\x01\x02\x3c\x9f\
+\x04\x90\xd2\x01\xe8\xd2\x01\x02\x3d\x9f\x04\xe8\xd2\x01\xc0\xd3\x01\x02\x3e\
+\x9f\x04\xc0\xd3\x01\x98\xd4\x01\x02\x3f\x9f\x04\x98\xd4\x01\xf0\xd4\x01\x02\
+\x40\x9f\x04\xf0\xd4\x01\xc8\xd5\x01\x02\x41\x9f\x04\xc8\xd5\x01\xa0\xd6\x01\
+\x02\x42\x9f\x04\xa0\xd6\x01\xf8\xd6\x01\x02\x43\x9f\x04\xf8\xd6\x01\xd0\xd7\
+\x01\x02\x44\x9f\x04\xd0\xd7\x01\xa8\xd8\x01\x02\x45\x9f\x04\xa8\xd8\x01\x80\
+\xd9\x01\x02\x46\x9f\x04\x80\xd9\x01\xd8\xd9\x01\x02\x47\x9f\x04\xd8\xd9\x01\
+\xb0\xda\x01\x02\x48\x9f\x04\xb0\xda\x01\x88\xdb\x01\x02\x49\x9f\x04\x88\xdb\
+\x01\xe0\xdb\x01\x02\x4a\x9f\x04\xe0\xdb\x01\xb8\xdc\x01\x02\x4b\x9f\x04\xb8\
+\xdc\x01\x90\xdd\x01\x02\x4c\x9f\x04\x90\xdd\x01\xe8\xdd\x01\x02\x4d\x9f\x04\
+\xe8\xdd\x01\xc0\xde\x01\x02\x4e\x9f\x04\xc0\xde\x01\xf8\xde\x01\x02\x4f\x9f\0\
+\x04\xf8\x33\xa8\x49\x02\x30\x9f\x04\xa8\x49\xe0\x5e\x02\x31\x9f\x04\xe0\x5e\
+\xa0\x74\x02\x32\x9f\x04\xa0\x74\xd0\x89\x01\x02\x33\x9f\x04\xd0\x89\x01\x80\
+\x9f\x01\x02\x34\x9f\x04\x80\x9f\x01\xb0\xb4\x01\x02\x35\x9f\x04\xb0\xb4\x01\
+\xe8\xc9\x01\x02\x36\x9f\x04\xe8\xc9\x01\xf8\xde\x01\x02\x37\x9f\0\x04\xf8\x33\
+\xd0\x34\x02\x30\x9f\x04\xd0\x34\xa8\x35\x01\x58\x04\xa8\x35\xb0\x35\x01\x51\
+\x04\xb0\x35\x88\x36\x01\x58\x04\x88\x36\x90\x36\x01\x51\x04\x90\x36\xe0\x36\
+\x01\x58\x04\xe0\x36\xe8\x36\x01\x51\x04\xe8\x36\xb8\x37\x01\x58\x04\xb8\x37\
+\xc0\x37\x01\x51\x04\xc0\x37\x90\x38\x01\x58\x04\x90\x38\x98\x38\x01\x51\x04\
+\x98\x38\xe8\x38\x01\x58\x04\xe8\x38\xf0\x38\x01\x51\x04\xf0\x38\xc0\x39\x01\
+\x58\x04\xc0\x39\xc8\x39\x01\x51\x04\xc8\x39\x98\x3a\x01\x58\x04\x98\x3a\xa0\
+\x3a\x01\x51\x04\xa0\x3a\xf0\x3a\x01\x58\x04\xf0\x3a\xf8\x3a\x01\x51\x04\xf8\
+\x3a\xc8\x3b\x01\x58\x04\xc8\x3b\xd0\x3b\x01\x51\x04\xd0\x3b\xa0\x3c\x01\x58\
+\x04\xa0\x3c\xa8\x3c\x01\x51\x04\xa8\x3c\xf8\x3c\x01\x58\x04\xf8\x3c\x80\x3d\
+\x01\x51\x04\x80\x3d\xd0\x3d\x01\x58\x04\xd0\x3d\xd8\x3d\x01\x51\x04\xd8\x3d\
+\xa8\x3e\x01\x58\x04\xa8\x3e\xb0\x3e\x01\x51\x04\xb0\x3e\x80\x3f\x01\x58\x04\
+\x80\x3f\x88\x3f\x01\x51\x04\x88\x3f\xd8\x3f\x01\x58\x04\xd8\x3f\xe0\x3f\x01\
+\x51\x04\xe0\x3f\xb0\x40\x01\x58\x04\xb0\x40\xb8\x40\x01\x51\x04\xb8\x40\x88\
+\x41\x01\x58\x04\x88\x41\x90\x41\x01\x51\x04\x90\x41\xe0\x41\x01\x58\x04\xe0\
+\x41\xe8\x41\x01\x51\x04\xe8\x41\xb8\x42\x01\x58\x04\xb8\x42\xc0\x42\x01\x51\
+\x04\xc0\x42\x90\x43\x01\x58\x04\x90\x43\x98\x43\x01\x51\x04\x98\x43\xe8\x43\
+\x01\x58\x04\xe8\x43\xf0\x43\x01\x51\x04\xf0\x43\xc0\x44\x01\x58\x04\xc0\x44\
+\xc8\x44\x01\x51\x04\xc8\x44\x98\x45\x01\x58\x04\x98\x45\xa0\x45\x01\x51\x04\
+\xa0\x45\xf0\x45\x01\x58\x04\xf0\x45\xf8\x45\x01\x51\x04\xf8\x45\xc8\x46\x01\
+\x58\x04\xc8\x46\xd0\x46\x01\x51\x04\xd0\x46\xa0\x47\x01\x58\x04\xa0\x47\xa8\
+\x47\x01\x51\x04\xa8\x47\xf8\x47\x01\x58\x04\xf8\x47\x80\x48\x01\x51\x04\x80\
+\x48\xd0\x48\x01\x58\x04\xd0\x48\xd8\x48\x01\x51\x04\xd8\x48\xa0\x49\x01\x58\
+\x04\xa0\x49\xa8\x49\x01\x51\x04\xa8\x49\x88\x4a\x01\x58\x04\x88\x4a\x90\x4a\
+\x01\x53\x04\x90\x4a\xe8\x4a\x01\x58\x04\xe8\x4a\xf0\x4a\x01\x53\x04\xf0\x4a\
+\xc0\x4b\x01\x58\x04\xc0\x4b\xc8\x4b\x01\x53\x04\xc8\x4b\x98\x4c\x01\x58\x04\
+\x98\x4c\xa0\x4c\x01\x53\x04\xa0\x4c\xf0\x4c\x01\x58\x04\xf0\x4c\xf8\x4c\x01\
+\x53\x04\xf8\x4c\xc8\x4d\x01\x58\x04\xc8\x4d\xd0\x4d\x01\x53\x04\xd0\x4d\xa0\
+\x4e\x01\x58\x04\xa0\x4e\xa8\x4e\x01\x53\x04\xa8\x4e\xf8\x4e\x01\x58\x04\xf8\
+\x4e\x80\x4f\x01\x53\x04\x80\x4f\xd0\x4f\x01\x58\x04\xd0\x4f\xd8\x4f\x01\x53\
+\x04\xd8\x4f\xa8\x50\x01\x58\x04\xa8\x50\xb0\x50\x01\x53\x04\xb0\x50\x80\x51\
+\x01\x58\x04\x80\x51\x88\x51\x01\x53\x04\x88\x51\xd8\x51\x01\x58\x04\xd8\x51\
+\xe0\x51\x01\x53\x04\xe0\x51\xb0\x52\x01\x58\x04\xb0\x52\xb8\x52\x01\x53\x04\
+\xb8\x52\x88\x53\x01\x58\x04\x88\x53\x90\x53\x01\x53\x04\x90\x53\xe0\x53\x01\
+\x58\x04\xe0\x53\xe8\x53\x01\x53\x04\xe8\x53\xb8\x54\x01\x58\x04\xb8\x54\xc0\
+\x54\x01\x53\x04\xc0\x54\x90\x55\x01\x58\x04\x90\x55\x98\x55\x01\x53\x04\x98\
+\x55\xe8\x55\x01\x58\x04\xe8\x55\xf0\x55\x01\x53\x04\xf0\x55\xc0\x56\x01\x58\
+\x04\xc0\x56\xc8\x56\x01\x53\x04\xc8\x56\x98\x57\x01\x58\x04\x98\x57\xa0\x57\
+\x01\x53\x04\xa0\x57\xf0\x57\x01\x58\x04\xf0\x57\xf8\x57\x01\x53\x04\xf8\x57\
+\xc8\x58\x01\x58\x04\xc8\x58\xd0\x58\x01\x53\x04\xd0\x58\xa0\x59\x01\x58\x04\
+\xa0\x59\xa8\x59\x01\x53\x04\xa8\x59\xf8\x59\x01\x58\x04\xf8\x59\x80\x5a\x01\
+\x53\x04\x80\x5a\xd0\x5a\x01\x58\x04\xd0\x5a\xd8\x5a\x01\x53\x04\xd8\x5a\xa8\
+\x5b\x01\x58\x04\xa8\x5b\xb0\x5b\x01\x53\x04\xb0\x5b\x80\x5c\x01\x58\x04\x80\
+\x5c\x88\x5c\x01\x53\x04\x88\x5c\xd8\x5c\x01\x58\x04\xd8\x5c\xe0\x5c\x01\x53\
+\x04\xe0\x5c\xb0\x5d\x01\x58\x04\xb0\x5d\xb8\x5d\x01\x53\x04\xb8\x5d\x88\x5e\
+\x01\x58\x04\x88\x5e\x90\x5e\x01\x53\x04\x90\x5e\xd8\x5e\x01\x58\x04\xd8\x5e\
+\xe0\x5e\x01\x52\x04\xe0\x5e\xc8\x5f\x01\x58\x04\xc8\x5f\xd0\x5f\x01\x53\x04\
+\xd0\x5f\xa0\x60\x01\x58\x04\xa0\x60\xa8\x60\x01\x53\x04\xa8\x60\xf8\x60\x01\
+\x58\x04\xf8\x60\x80\x61\x01\x53\x04\x80\x61\xd0\x61\x01\x58\x04\xd0\x61\xd8\
+\x61\x01\x53\x04\xd8\x61\xa8\x62\x01\x58\x04\xa8\x62\xb0\x62\x01\x53\x04\xb0\
+\x62\x80\x63\x01\x58\x04\x80\x63\x88\x63\x01\x53\x04\x88\x63\xd8\x63\x01\x58\
+\x04\xd8\x63\xe0\x63\x01\x53\x04\xe0\x63\xb0\x64\x01\x58\x04\xb0\x64\xb8\x64\
+\x01\x53\x04\xb8\x64\x88\x65\x01\x58\x04\x88\x65\x90\x65\x01\x53\x04\x90\x65\
+\xe0\x65\x01\x58\x04\xe0\x65\xe8\x65\x01\x53\x04\xe8\x65\xb8\x66\x01\x58\x04\
+\xb8\x66\xc0\x66\x01\x53\x04\xc0\x66\x90\x67\x01\x58\x04\x90\x67\x98\x67\x01\
+\x53\x04\x98\x67\xe8\x67\x01\x58\x04\xe8\x67\xf0\x67\x01\x53\x04\xf0\x67\xc0\
+\x68\x01\x58\x04\xc0\x68\xc8\x68\x01\x53\x04\xc8\x68\x98\x69\x01\x58\x04\x98\
+\x69\xa0\x69\x01\x53\x04\xa0\x69\xf0\x69\x01\x58\x04\xf0\x69\xf8\x69\x01\x53\
+\x04\xf8\x69\xc8\x6a\x01\x58\x04\xc8\x6a\xd0\x6a\x01\x53\x04\xd0\x6a\xa0\x6b\
+\x01\x58\x04\xa0\x6b\xa8\x6b\x01\x53\x04\xa8\x6b\xf8\x6b\x01\x58\x04\xf8\x6b\
+\x80\x6c\x01\x53\x04\x80\x6c\xd0\x6c\x01\x58\x04\xd0\x6c\xd8\x6c\x01\x53\x04\
+\xd8\x6c\xa8\x6d\x01\x58\x04\xa8\x6d\xb0\x6d\x01\x53\x04\xb0\x6d\x80\x6e\x01\
+\x58\x04\x80\x6e\x88\x6e\x01\x53\x04\x88\x6e\xd8\x6e\x01\x58\x04\xd8\x6e\xe0\
+\x6e\x01\x53\x04\xe0\x6e\xb0\x6f\x01\x58\x04\xb0\x6f\xb8\x6f\x01\x53\x04\xb8\
+\x6f\x88\x70\x01\x58\x04\x88\x70\x90\x70\x01\x53\x04\x90\x70\xe0\x70\x01\x58\
+\x04\xe0\x70\xe8\x70\x01\x53\x04\xe8\x70\xb8\x71\x01\x58\x04\xb8\x71\xc0\x71\
+\x01\x53\x04\xc0\x71\x90\x72\x01\x58\x04\x90\x72\x98\x72\x01\x53\x04\x98\x72\
+\xe8\x72\x01\x58\x04\xe8\x72\xf0\x72\x01\x53\x04\xf0\x72\xc0\x73\x01\x58\x04\
+\xc0\x73\xc8\x73\x01\x53\x04\xc8\x73\x98\x74\x01\x58\x04\x98\x74\xa0\x74\x01\
+\x51\x04\xa0\x74\x80\x75\x01\x58\x04\x80\x75\x88\x75\x01\x53\x04\x88\x75\xd8\
+\x75\x01\x58\x04\xd8\x75\xe0\x75\x01\x53\x04\xe0\x75\xb0\x76\x01\x58\x04\xb0\
+\x76\xb8\x76\x01\x53\x04\xb8\x76\x88\x77\x01\x58\x04\x88\x77\x90\x77\x01\x53\
+\x04\x90\x77\xe0\x77\x01\x58\x04\xe0\x77\xe8\x77\x01\x53\x04\xe8\x77\xb8\x78\
+\x01\x58\x04\xb8\x78\xc0\x78\x01\x53\x04\xc0\x78\x90\x79\x01\x58\x04\x90\x79\
+\x98\x79\x01\x53\x04\x98\x79\xe8\x79\x01\x58\x04\xe8\x79\xf0\x79\x01\x53\x04\
+\xf0\x79\xc0\x7a\x01\x58\x04\xc0\x7a\xc8\x7a\x01\x53\x04\xc8\x7a\x98\x7b\x01\
+\x58\x04\x98\x7b\xa0\x7b\x01\x53\x04\xa0\x7b\xf0\x7b\x01\x58\x04\xf0\x7b\xf8\
+\x7b\x01\x53\x04\xf8\x7b\xc8\x7c\x01\x58\x04\xc8\x7c\xd0\x7c\x01\x53\x04\xd0\
+\x7c\xa0\x7d\x01\x58\x04\xa0\x7d\xa8\x7d\x01\x53\x04\xa8\x7d\xf8\x7d\x01\x58\
+\x04\xf8\x7d\x80\x7e\x01\x53\x04\x80\x7e\xd0\x7e\x01\x58\x04\xd0\x7e\xd8\x7e\
+\x01\x53\x04\xd8\x7e\xa8\x7f\x01\x58\x04\xa8\x7f\xb0\x7f\x01\x53\x04\xb0\x7f\
+\x80\x80\x01\x01\x58\x04\x80\x80\x01\x88\x80\x01\x01\x53\x04\x88\x80\x01\xd8\
+\x80\x01\x01\x58\x04\xd8\x80\x01\xe0\x80\x01\x01\x53\x04\xe0\x80\x01\xb0\x81\
+\x01\x01\x58\x04\xb0\x81\x01\xb8\x81\x01\x01\x53\x04\xb8\x81\x01\x88\x82\x01\
+\x01\x58\x04\x88\x82\x01\x90\x82\x01\x01\x53\x04\x90\x82\x01\xe0\x82\x01\x01\
+\x58\x04\xe0\x82\x01\xe8\x82\x01\x01\x53\x04\xe8\x82\x01\xb8\x83\x01\x01\x58\
+\x04\xb8\x83\x01\xc0\x83\x01\x01\x53\x04\xc0\x83\x01\x90\x84\x01\x01\x58\x04\
+\x90\x84\x01\x98\x84\x01\x01\x53\x04\x98\x84\x01\xe8\x84\x01\x01\x58\x04\xe8\
+\x84\x01\xf0\x84\x01\x01\x53\x04\xf0\x84\x01\xc0\x85\x01\x01\x58\x04\xc0\x85\
+\x01\xc8\x85\x01\x01\x53\x04\xc8\x85\x01\x98\x86\x01\x01\x58\x04\x98\x86\x01\
+\xa0\x86\x01\x01\x53\x04\xa0\x86\x01\xf0\x86\x01\x01\x58\x04\xf0\x86\x01\xf8\
+\x86\x01\x01\x53\x04\xf8\x86\x01\xc8\x87\x01\x01\x58\x04\xc8\x87\x01\xd0\x87\
+\x01\x01\x53\x04\xd0\x87\x01\xa0\x88\x01\x01\x58\x04\xa0\x88\x01\xa8\x88\x01\
+\x01\x53\x04\xa8\x88\x01\xf8\x88\x01\x01\x58\x04\xf8\x88\x01\x80\x89\x01\x01\
+\x53\x04\x80\x89\x01\xc8\x89\x01\x01\x58\x04\xc8\x89\x01\xd0\x89\x01\x01\x52\
+\x04\xd0\x89\x01\xb0\x8a\x01\x01\x58\x04\xb0\x8a\x01\xb8\x8a\x01\x01\x53\x04\
+\xb8\x8a\x01\x88\x8b\x01\x01\x58\x04\x88\x8b\x01\x90\x8b\x01\x01\x53\x04\x90\
+\x8b\x01\xe0\x8b\x01\x01\x58\x04\xe0\x8b\x01\xe8\x8b\x01\x01\x53\x04\xe8\x8b\
+\x01\xb8\x8c\x01\x01\x58\x04\xb8\x8c\x01\xc0\x8c\x01\x01\x53\x04\xc0\x8c\x01\
+\x90\x8d\x01\x01\x58\x04\x90\x8d\x01\x98\x8d\x01\x01\x53\x04\x98\x8d\x01\xe8\
+\x8d\x01\x01\x58\x04\xe8\x8d\x01\xf0\x8d\x01\x01\x53\x04\xf0\x8d\x01\xc0\x8e\
+\x01\x01\x58\x04\xc0\x8e\x01\xc8\x8e\x01\x01\x53\x04\xc8\x8e\x01\x98\x8f\x01\
+\x01\x58\x04\x98\x8f\x01\xa0\x8f\x01\x01\x53\x04\xa0\x8f\x01\xf0\x8f\x01\x01\
+\x58\x04\xf0\x8f\x01\xf8\x8f\x01\x01\x53\x04\xf8\x8f\x01\xc8\x90\x01\x01\x58\
+\x04\xc8\x90\x01\xd0\x90\x01\x01\x53\x04\xd0\x90\x01\xa0\x91\x01\x01\x58\x04\
+\xa0\x91\x01\xa8\x91\x01\x01\x53\x04\xa8\x91\x01\xf8\x91\x01\x01\x58\x04\xf8\
+\x91\x01\x80\x92\x01\x01\x53\x04\x80\x92\x01\xd0\x92\x01\x01\x58\x04\xd0\x92\
+\x01\xd8\x92\x01\x01\x53\x04\xd8\x92\x01\xa8\x93\x01\x01\x58\x04\xa8\x93\x01\
+\xb0\x93\x01\x01\x53\x04\xb0\x93\x01\x80\x94\x01\x01\x58\x04\x80\x94\x01\x88\
+\x94\x01\x01\x53\x04\x88\x94\x01\xd8\x94\x01\x01\x58\x04\xd8\x94\x01\xe0\x94\
+\x01\x01\x53\x04\xe0\x94\x01\xb0\x95\x01\x01\x58\x04\xb0\x95\x01\xb8\x95\x01\
+\x01\x53\x04\xb8\x95\x01\x88\x96\x01\x01\x58\x04\x88\x96\x01\x90\x96\x01\x01\
+\x53\x04\x90\x96\x01\xe0\x96\x01\x01\x58\x04\xe0\x96\x01\xe8\x96\x01\x01\x53\
+\x04\xe8\x96\x01\xb8\x97\x01\x01\x58\x04\xb8\x97\x01\xc0\x97\x01\x01\x53\x04\
+\xc0\x97\x01\x90\x98\x01\x01\x58\x04\x90\x98\x01\x98\x98\x01\x01\x53\x04\x98\
+\x98\x01\xe8\x98\x01\x01\x58\x04\xe8\x98\x01\xf0\x98\x01\x01\x53\x04\xf0\x98\
+\x01\xc0\x99\x01\x01\x58\x04\xc0\x99\x01\xc8\x99\x01\x01\x53\x04\xc8\x99\x01\
+\x98\x9a\x01\x01\x58\x04\x98\x9a\x01\xa0\x9a\x01\x01\x53\x04\xa0\x9a\x01\xf0\
+\x9a\x01\x01\x58\x04\xf0\x9a\x01\xf8\x9a\x01\x01\x53\x04\xf8\x9a\x01\xc8\x9b\
+\x01\x01\x58\x04\xc8\x9b\x01\xd0\x9b\x01\x01\x53\x04\xd0\x9b\x01\xa0\x9c\x01\
+\x01\x58\x04\xa0\x9c\x01\xa8\x9c\x01\x01\x53\x04\xa8\x9c\x01\xf8\x9c\x01\x01\
+\x58\x04\xf8\x9c\x01\x80\x9d\x01\x01\x53\x04\x80\x9d\x01\xd0\x9d\x01\x01\x58\
+\x04\xd0\x9d\x01\xd8\x9d\x01\x01\x53\x04\xd8\x9d\x01\xa8\x9e\x01\x01\x58\x04\
+\xa8\x9e\x01\xb0\x9e\x01\x01\x53\x04\xb0\x9e\x01\xf8\x9e\x01\x01\x58\x04\xf8\
+\x9e\x01\x80\x9f\x01\x01\x51\x04\x80\x9f\x01\xe0\x9f\x01\x01\x58\x04\xe0\x9f\
+\x01\xe8\x9f\x01\x01\x53\x04\xe8\x9f\x01\xb8\xa0\x01\x01\x58\x04\xb8\xa0\x01\
+\xc0\xa0\x01\x01\x53\x04\xc0\xa0\x01\x90\xa1\x01\x01\x58\x04\x90\xa1\x01\x98\
+\xa1\x01\x01\x53\x04\x98\xa1\x01\xe8\xa1\x01\x01\x58\x04\xe8\xa1\x01\xf0\xa1\
+\x01\x01\x53\x04\xf0\xa1\x01\xc0\xa2\x01\x01\x58\x04\xc0\xa2\x01\xc8\xa2\x01\
+\x01\x53\x04\xc8\xa2\x01\x98\xa3\x01\x01\x58\x04\x98\xa3\x01\xa0\xa3\x01\x01\
+\x53\x04\xa0\xa3\x01\xf0\xa3\x01\x01\x58\x04\xf0\xa3\x01\xf8\xa3\x01\x01\x53\
+\x04\xf8\xa3\x01\xc8\xa4\x01\x01\x58\x04\xc8\xa4\x01\xd0\xa4\x01\x01\x53\x04\
+\xd0\xa4\x01\xa0\xa5\x01\x01\x58\x04\xa0\xa5\x01\xa8\xa5\x01\x01\x53\x04\xa8\
+\xa5\x01\xf8\xa5\x01\x01\x58\x04\xf8\xa5\x01\x80\xa6\x01\x01\x53\x04\x80\xa6\
+\x01\xd0\xa6\x01\x01\x58\x04\xd0\xa6\x01\xd8\xa6\x01\x01\x53\x04\xd8\xa6\x01\
+\xa8\xa7\x01\x01\x58\x04\xa8\xa7\x01\xb0\xa7\x01\x01\x53\x04\xb0\xa7\x01\x80\
+\xa8\x01\x01\x58\x04\x80\xa8\x01\x88\xa8\x01\x01\x53\x04\x88\xa8\x01\xd8\xa8\
+\x01\x01\x58\x04\xd8\xa8\x01\xe0\xa8\x01\x01\x53\x04\xe0\xa8\x01\xb0\xa9\x01\
+\x01\x58\x04\xb0\xa9\x01\xb8\xa9\x01\x01\x53\x04\xb8\xa9\x01\x88\xaa\x01\x01\
+\x58\x04\x88\xaa\x01\x90\xaa\x01\x01\x53\x04\x90\xaa\x01\xe0\xaa\x01\x01\x58\
+\x04\xe0\xaa\x01\xe8\xaa\x01\x01\x53\x04\xe8\xaa\x01\xb8\xab\x01\x01\x58\x04\
+\xb8\xab\x01\xc0\xab\x01\x01\x53\x04\xc0\xab\x01\x90\xac\x01\x01\x58\x04\x90\
+\xac\x01\x98\xac\x01\x01\x53\x04\x98\xac\x01\xe8\xac\x01\x01\x58\x04\xe8\xac\
+\x01\xf0\xac\x01\x01\x53\x04\xf0\xac\x01\xc0\xad\x01\x01\x58\x04\xc0\xad\x01\
+\xc8\xad\x01\x01\x53\x04\xc8\xad\x01\x98\xae\x01\x01\x58\x04\x98\xae\x01\xa0\
+\xae\x01\x01\x53\x04\xa0\xae\x01\xf0\xae\x01\x01\x58\x04\xf0\xae\x01\xf8\xae\
+\x01\x01\x53\x04\xf8\xae\x01\xc8\xaf\x01\x01\x58\x04\xc8\xaf\x01\xd0\xaf\x01\
+\x01\x53\x04\xd0\xaf\x01\xa0\xb0\x01\x01\x58\x04\xa0\xb0\x01\xa8\xb0\x01\x01\
+\x53\x04\xa8\xb0\x01\xf8\xb0\x01\x01\x58\x04\xf8\xb0\x01\x80\xb1\x01\x01\x53\
+\x04\x80\xb1\x01\xd0\xb1\x01\x01\x58\x04\xd0\xb1\x01\xd8\xb1\x01\x01\x53\x04\
+\xd8\xb1\x01\xa8\xb2\x01\x01\x58\x04\xa8\xb2\x01\xb0\xb2\x01\x01\x53\x04\xb0\
+\xb2\x01\x80\xb3\x01\x01\x58\x04\x80\xb3\x01\x88\xb3\x01\x01\x53\x04\x88\xb3\
+\x01\xd8\xb3\x01\x01\x58\x04\xd8\xb3\x01\xe0\xb3\x01\x01\x53\x04\xe0\xb3\x01\
+\xa8\xb4\x01\x01\x58\x04\xa8\xb4\x01\xb0\xb4\x01\x01\x52\x04\xb0\xb4\x01\x90\
+\xb5\x01\x01\x58\x04\x90\xb5\x01\x98\xb5\x01\x01\x53\x04\x98\xb5\x01\xf0\xb5\
+\x01\x01\x58\x04\xf0\xb5\x01\xf8\xb5\x01\x01\x53\x04\xf8\xb5\x01\xc8\xb6\x01\
+\x01\x58\x04\xc8\xb6\x01\xd0\xb6\x01\x01\x53\x04\xd0\xb6\x01\xa0\xb7\x01\x01\
+\x58\x04\xa0\xb7\x01\xa8\xb7\x01\x01\x53\x04\xa8\xb7\x01\xf8\xb7\x01\x01\x58\
+\x04\xf8\xb7\x01\x80\xb8\x01\x01\x53\x04\x80\xb8\x01\xd0\xb8\x01\x01\x58\x04\
+\xd0\xb8\x01\xd8\xb8\x01\x01\x53\x04\xd8\xb8\x01\xa8\xb9\x01\x01\x58\x04\xa8\
+\xb9\x01\xb0\xb9\x01\x01\x53\x04\xb0\xb9\x01\x80\xba\x01\x01\x58\x04\x80\xba\
+\x01\x88\xba\x01\x01\x53\x04\x88\xba\x01\xd8\xba\x01\x01\x58\x04\xd8\xba\x01\
+\xe0\xba\x01\x01\x53\x04\xe0\xba\x01\xb0\xbb\x01\x01\x58\x04\xb0\xbb\x01\xb8\
+\xbb\x01\x01\x53\x04\xb8\xbb\x01\x88\xbc\x01\x01\x58\x04\x88\xbc\x01\x90\xbc\
+\x01\x01\x53\x04\x90\xbc\x01\xe0\xbc\x01\x01\x58\x04\xe0\xbc\x01\xe8\xbc\x01\
+\x01\x53\x04\xe8\xbc\x01\xb8\xbd\x01\x01\x58\x04\xb8\xbd\x01\xc0\xbd\x01\x01\
+\x53\x04\xc0\xbd\x01\x90\xbe\x01\x01\x58\x04\x90\xbe\x01\x98\xbe\x01\x01\x53\
+\x04\x98\xbe\x01\xe8\xbe\x01\x01\x58\x04\xe8\xbe\x01\xf0\xbe\x01\x01\x53\x04\
+\xf0\xbe\x01\xc0\xbf\x01\x01\x58\x04\xc0\xbf\x01\xc8\xbf\x01\x01\x53\x04\xc8\
+\xbf\x01\x98\xc0\x01\x01\x58\x04\x98\xc0\x01\xa0\xc0\x01\x01\x53\x04\xa0\xc0\
+\x01\xf0\xc0\x01\x01\x58\x04\xf0\xc0\x01\xf8\xc0\x01\x01\x53\x04\xf8\xc0\x01\
+\xc8\xc1\x01\x01\x58\x04\xc8\xc1\x01\xd0\xc1\x01\x01\x53\x04\xd0\xc1\x01\xa0\
+\xc2\x01\x01\x58\x04\xa0\xc2\x01\xa8\xc2\x01\x01\x53\x04\xa8\xc2\x01\xf8\xc2\
+\x01\x01\x58\x04\xf8\xc2\x01\x80\xc3\x01\x01\x53\x04\x80\xc3\x01\xd0\xc3\x01\
+\x01\x58\x04\xd0\xc3\x01\xd8\xc3\x01\x01\x53\x04\xd8\xc3\x01\xa8\xc4\x01\x01\
+\x58\x04\xa8\xc4\x01\xb0\xc4\x01\x01\x53\x04\xb0\xc4\x01\x80\xc5\x01\x01\x58\
+\x04\x80\xc5\x01\x88\xc5\x01\x01\x53\x04\x88\xc5\x01\xd8\xc5\x01\x01\x58\x04\
+\xd8\xc5\x01\xe0\xc5\x01\x01\x53\x04\xe0\xc5\x01\xb0\xc6\x01\x01\x58\x04\xb0\
+\xc6\x01\xb8\xc6\x01\x01\x53\x04\xb8\xc6\x01\x88\xc7\x01\x01\x58\x04\x88\xc7\
+\x01\x90\xc7\x01\x01\x53\x04\x90\xc7\x01\xe0\xc7\x01\x01\x58\x04\xe0\xc7\x01\
+\xe8\xc7\x01\x01\x53\x04\xe8\xc7\x01\xb8\xc8\x01\x01\x58\x04\xb8\xc8\x01\xc0\
+\xc8\x01\x01\x53\x04\xc0\xc8\x01\x90\xc9\x01\x01\x58\x04\x90\xc9\x01\x98\xc9\
+\x01\x01\x53\x04\x98\xc9\x01\xe0\xc9\x01\x01\x58\x04\xe0\xc9\x01\xe8\xc9\x01\
+\x01\x51\x04\xe8\xc9\x01\xc0\xca\x01\x01\x58\x04\xc0\xca\x01\xc8\xca\x01\x01\
+\x51\x04\xc8\xca\x01\x98\xcb\x01\x01\x58\x04\x98\xcb\x01\xa0\xcb\x01\x01\x51\
+\x04\xa0\xcb\x01\xf0\xcb\x01\x01\x58\x04\xf0\xcb\x01\xf8\xcb\x01\x01\x51\x04\
+\xf8\xcb\x01\xc8\xcc\x01\x01\x58\x04\xc8\xcc\x01\xd0\xcc\x01\x01\x51\x04\xd0\
+\xcc\x01\xa0\xcd\x01\x01\x58\x04\xa0\xcd\x01\xa8\xcd\x01\x01\x51\x04\xa8\xcd\
+\x01\xf8\xcd\x01\x01\x58\x04\xf8\xcd\x01\x80\xce\x01\x01\x51\x04\x80\xce\x01\
+\xd0\xce\x01\x01\x58\x04\xd0\xce\x01\xd8\xce\x01\x01\x51\x04\xd8\xce\x01\xa8\
+\xcf\x01\x01\x58\x04\xa8\xcf\x01\xb0\xcf\x01\x01\x51\x04\xb0\xcf\x01\x80\xd0\
+\x01\x01\x58\x04\x80\xd0\x01\x88\xd0\x01\x01\x51\x04\x88\xd0\x01\xd8\xd0\x01\
+\x01\x58\x04\xd8\xd0\x01\xe0\xd0\x01\x01\x51\x04\xe0\xd0\x01\xb0\xd1\x01\x01\
+\x58\x04\xb0\xd1\x01\xb8\xd1\x01\x01\x51\x04\xb8\xd1\x01\x88\xd2\x01\x01\x58\
+\x04\x88\xd2\x01\x90\xd2\x01\x01\x51\x04\x90\xd2\x01\xe0\xd2\x01\x01\x58\x04\
+\xe0\xd2\x01\xe8\xd2\x01\x01\x51\x04\xe8\xd2\x01\xb8\xd3\x01\x01\x58\x04\xb8\
+\xd3\x01\xc0\xd3\x01\x01\x51\x04\xc0\xd3\x01\x90\xd4\x01\x01\x58\x04\x90\xd4\
+\x01\x98\xd4\x01\x01\x51\x04\x98\xd4\x01\xe8\xd4\x01\x01\x58\x04\xe8\xd4\x01\
+\xf0\xd4\x01\x01\x51\x04\xf0\xd4\x01\xc0\xd5\x01\x01\x58\x04\xc0\xd5\x01\xc8\
+\xd5\x01\x01\x51\x04\xc8\xd5\x01\x98\xd6\x01\x01\x58\x04\x98\xd6\x01\xa0\xd6\
+\x01\x01\x51\x04\xa0\xd6\x01\xf0\xd6\x01\x01\x58\x04\xf0\xd6\x01\xf8\xd6\x01\
+\x01\x51\x04\xf8\xd6\x01\xc8\xd7\x01\x01\x58\x04\xc8\xd7\x01\xd0\xd7\x01\x01\
+\x51\x04\xd0\xd7\x01\xa0\xd8\x01\x01\x58\x04\xa0\xd8\x01\xa8\xd8\x01\x01\x51\
+\x04\xa8\xd8\x01\xf8\xd8\x01\x01\x58\x04\xf8\xd8\x01\x80\xd9\x01\x01\x51\x04\
+\x80\xd9\x01\xd0\xd9\x01\x01\x58\x04\xd0\xd9\x01\xd8\xd9\x01\x01\x51\x04\xd8\
+\xd9\x01\xa8\xda\x01\x01\x58\x04\xa8\xda\x01\xb0\xda\x01\x01\x51\x04\xb0\xda\
+\x01\x80\xdb\x01\x01\x58\x04\x80\xdb\x01\x88\xdb\x01\x01\x51\x04\x88\xdb\x01\
+\xd8\xdb\x01\x01\x58\x04\xd8\xdb\x01\xe0\xdb\x01\x01\x51\x04\xe0\xdb\x01\xb0\
+\xdc\x01\x01\x58\x04\xb0\xdc\x01\xb8\xdc\x01\x01\x51\x04\xb8\xdc\x01\x88\xdd\
+\x01\x01\x58\x04\x88\xdd\x01\x90\xdd\x01\x01\x51\x04\x90\xdd\x01\xe0\xdd\x01\
+\x01\x58\x04\xe0\xdd\x01\xe8\xdd\x01\x01\x51\x04\xe8\xdd\x01\xb8\xde\x01\x01\
+\x58\x04\xb8\xde\x01\xc0\xde\x01\x01\x51\x04\xc0\xde\x01\xc8\xde\x01\x01\x58\
+\x04\xc8\xde\x01\xf8\xde\x01\x03\x7a\xc0\0\0\x04\xd0\xe0\x01\xa8\xe1\x01\x02\
+\x31\x9f\x04\xa8\xe1\x01\x80\xe2\x01\x02\x32\x9f\x04\x80\xe2\x01\xd8\xe2\x01\
+\x02\x33\x9f\x04\xd8\xe2\x01\xb0\xe3\x01\x02\x34\x9f\x04\xb0\xe3\x01\x88\xe4\
+\x01\x02\x35\x9f\x04\x88\xe4\x01\xe0\xe4\x01\x02\x36\x9f\x04\xe0\xe4\x01\xb8\
+\xe5\x01\x02\x37\x9f\x04\xb8\xe5\x01\x90\xe6\x01\x02\x38\x9f\x04\x90\xe6\x01\
+\xe8\xe6\x01\x02\x39\x9f\x04\xe8\xe6\x01\xc0\xe7\x01\x02\x3a\x9f\x04\xc0\xe7\
+\x01\x98\xe8\x01\x02\x3b\x9f\x04\x98\xe8\x01\xf0\xe8\x01\x02\x3c\x9f\x04\xf0\
+\xe8\x01\xc8\xe9\x01\x02\x3d\x9f\x04\xc8\xe9\x01\xa0\xea\x01\x02\x3e\x9f\x04\
+\xa0\xea\x01\xf8\xea\x01\x02\x3f\x9f\x04\xf8\xea\x01\xd0\xeb\x01\x02\x40\x9f\
+\x04\xd0\xeb\x01\xa8\xec\x01\x02\x41\x9f\x04\xa8\xec\x01\x80\xed\x01\x02\x42\
+\x9f\x04\x80\xed\x01\xd8\xed\x01\x02\x43\x9f\x04\xd8\xed\x01\xb0\xee\x01\x02\
+\x44\x9f\x04\xb0\xee\x01\x88\xef\x01\x02\x45\x9f\x04\x88\xef\x01\xe0\xef\x01\
+\x02\x46\x9f\x04\xe0\xef\x01\xb8\xf0\x01\x02\x47\x9f\x04\xb8\xf0\x01\x90\xf1\
+\x01\x02\x48\x9f\x04\x90\xf1\x01\xe8\xf1\x01\x02\x49\x9f\x04\xe8\xf1\x01\xc0\
+\xf2\x01\x02\x4a\x9f\x04\xc0\xf2\x01\x98\xf3\x01\x02\x4b\x9f\x04\x98\xf3\x01\
+\xf0\xf3\x01\x02\x4c\x9f\x04\xf0\xf3\x01\xc8\xf4\x01\x02\x4d\x9f\x04\xc8\xf4\
+\x01\xa0\xf5\x01\x02\x4e\x9f\x04\xa0\xf5\x01\xf0\xf5\x01\x02\x4f\x9f\x04\xf0\
+\xf5\x01\x80\xf6\x01\x02\x30\x9f\x04\x80\xf6\x01\xd8\xf6\x01\x02\x31\x9f\x04\
+\xd8\xf6\x01\xb0\xf7\x01\x02\x32\x9f\x04\xb0\xf7\x01\x88\xf8\x01\x02\x33\x9f\
+\x04\x88\xf8\x01\xe0\xf8\x01\x02\x34\x9f\x04\xe0\xf8\x01\xb8\xf9\x01\x02\x35\
+\x9f\x04\xb8\xf9\x01\x90\xfa\x01\x02\x36\x9f\x04\x90\xfa\x01\xe8\xfa\x01\x02\
+\x37\x9f\x04\xe8\xfa\x01\xc0\xfb\x01\x02\x38\x9f\x04\xc0\xfb\x01\x98\xfc\x01\
+\x02\x39\x9f\x04\x98\xfc\x01\xf0\xfc\x01\x02\x3a\x9f\x04\xf0\xfc\x01\xc8\xfd\
+\x01\x02\x3b\x9f\x04\xc8\xfd\x01\xa0\xfe\x01\x02\x3c\x9f\x04\xa0\xfe\x01\xf8\
+\xfe\x01\x02\x3d\x9f\x04\xf8\xfe\x01\xd0\xff\x01\x02\x3e\x9f\x04\xd0\xff\x01\
+\xa8\x80\x02\x02\x3f\x9f\x04\xa8\x80\x02\x80\x81\x02\x02\x40\x9f\x04\x80\x81\
+\x02\xd8\x81\x02\x02\x41\x9f\x04\xd8\x81\x02\xb0\x82\x02\x02\x42\x9f\x04\xb0\
+\x82\x02\x88\x83\x02\x02\x43\x9f\x04\x88\x83\x02\xe0\x83\x02\x02\x44\x9f\x04\
+\xe0\x83\x02\xb8\x84\x02\x02\x45\x9f\x04\xb8\x84\x02\x90\x85\x02\x02\x46\x9f\
+\x04\x90\x85\x02\xe8\x85\x02\x02\x47\x9f\x04\xe8\x85\x02\xc0\x86\x02\x02\x48\
+\x9f\x04\xc0\x86\x02\x98\x87\x02\x02\x49\x9f\x04\x98\x87\x02\xf0\x87\x02\x02\
+\x4a\x9f\x04\xf0\x87\x02\xc8\x88\x02\x02\x4b\x9f\x04\xd0\x88\x02\xa8\x89\x02\
+\x02\x4c\x9f\x04\xb8\x89\x02\x90\x8a\x02\x02\x4d\x9f\x04\x98\x8a\x02\xf0\x8a\
+\x02\x02\x4e\x9f\x04\xf8\x8a\x02\xc8\x8b\x02\x02\x4f\x9f\x04\xc8\x8b\x02\xd0\
+\x8b\x02\x02\x30\x9f\x04\xd0\x8b\x02\xa8\x8c\x02\x02\x31\x9f\x04\xa8\x8c\x02\
+\x80\x8d\x02\x02\x32\x9f\x04\x80\x8d\x02\xd8\x8d\x02\x02\x33\x9f\x04\xd8\x8d\
+\x02\xb0\x8e\x02\x02\x34\x9f\x04\xb0\x8e\x02\x88\x8f\x02\x02\x35\x9f\x04\x88\
+\x8f\x02\xe0\x8f\x02\x02\x36\x9f\x04\xe0\x8f\x02\xb8\x90\x02\x02\x37\x9f\x04\
+\xb8\x90\x02\x90\x91\x02\x02\x38\x9f\x04\x90\x91\x02\xe8\x91\x02\x02\x39\x9f\
+\x04\xe8\x91\x02\xc0\x92\x02\x02\x3a\x9f\x04\xc0\x92\x02\x98\x93\x02\x02\x3b\
+\x9f\x04\x98\x93\x02\xf0\x93\x02\x02\x3c\x9f\x04\xf0\x93\x02\xc8\x94\x02\x02\
+\x3d\x9f\x04\xc8\x94\x02\xa0\x95\x02\x02\x3e\x9f\x04\xa0\x95\x02\xf8\x95\x02\
+\x02\x3f\x9f\x04\xf8\x95\x02\xd0\x96\x02\x02\x40\x9f\x04\xd0\x96\x02\xa8\x97\
+\x02\x02\x41\x9f\x04\xa8\x97\x02\x80\x98\x02\x02\x42\x9f\x04\x80\x98\x02\xd8\
+\x98\x02\x02\x43\x9f\x04\xd8\x98\x02\xb0\x99\x02\x02\x44\x9f\x04\xb0\x99\x02\
+\x88\x9a\x02\x02\x45\x9f\x04\x88\x9a\x02\xe0\x9a\x02\x02\x46\x9f\x04\xe0\x9a\
+\x02\xb8\x9b\x02\x02\x47\x9f\x04\xb8\x9b\x02\x90\x9c\x02\x02\x48\x9f\x04\x90\
+\x9c\x02\xe8\x9c\x02\x02\x49\x9f\x04\xe8\x9c\x02\xc0\x9d\x02\x02\x4a\x9f\x04\
+\xc0\x9d\x02\x98\x9e\x02\x02\x4b\x9f\x04\x98\x9e\x02\xf0\x9e\x02\x02\x4c\x9f\
+\x04\xf0\x9e\x02\xc8\x9f\x02\x02\x4d\x9f\x04\xc8\x9f\x02\xa0\xa0\x02\x02\x4e\
+\x9f\x04\xa0\xa0\x02\xf0\xa0\x02\x02\x4f\x9f\0\x04\xd0\xe0\x01\xf0\xf5\x01\x02\
+\x30\x9f\x04\xf0\xf5\x01\xc8\x8b\x02\x02\x31\x9f\x04\xc8\x8b\x02\xf0\xa0\x02\
+\x02\x32\x9f\0\x04\xd0\xe0\x01\xa0\xe1\x01\x02\x30\x9f\x04\xa0\xe1\x01\xa8\xe1\
+\x01\x01\x51\x04\xa8\xe1\x01\xf8\xe1\x01\x01\x57\x04\xf8\xe1\x01\x80\xe2\x01\
+\x01\x51\x04\x80\xe2\x01\xd0\xe2\x01\x01\x57\x04\xd0\xe2\x01\xd8\xe2\x01\x01\
+\x51\x04\xd8\xe2\x01\xa8\xe3\x01\x01\x57\x04\xa8\xe3\x01\xb0\xe3\x01\x01\x51\
+\x04\xb0\xe3\x01\x80\xe4\x01\x01\x57\x04\x80\xe4\x01\x88\xe4\x01\x01\x51\x04\
+\x88\xe4\x01\xd8\xe4\x01\x01\x57\x04\xd8\xe4\x01\xe0\xe4\x01\x01\x51\x04\xe0\
+\xe4\x01\xb0\xe5\x01\x01\x57\x04\xb0\xe5\x01\xb8\xe5\x01\x01\x51\x04\xb8\xe5\
+\x01\x88\xe6\x01\x01\x57\x04\x88\xe6\x01\x90\xe6\x01\x01\x51\x04\x90\xe6\x01\
+\xe0\xe6\x01\x01\x57\x04\xe0\xe6\x01\xe8\xe6\x01\x01\x51\x04\xe8\xe6\x01\xb8\
+\xe7\x01\x01\x57\x04\xb8\xe7\x01\xc0\xe7\x01\x01\x51\x04\xc0\xe7\x01\x90\xe8\
+\x01\x01\x57\x04\x90\xe8\x01\x98\xe8\x01\x01\x51\x04\x98\xe8\x01\xe8\xe8\x01\
+\x01\x57\x04\xe8\xe8\x01\xf0\xe8\x01\x01\x51\x04\xf0\xe8\x01\xc0\xe9\x01\x01\
+\x57\x04\xc0\xe9\x01\xc8\xe9\x01\x01\x51\x04\xc8\xe9\x01\x98\xea\x01\x01\x57\
+\x04\x98\xea\x01\xa0\xea\x01\x01\x51\x04\xa0\xea\x01\xf0\xea\x01\x01\x57\x04\
+\xf0\xea\x01\xf8\xea\x01\x01\x51\x04\xf8\xea\x01\xc8\xeb\x01\x01\x57\x04\xc8\
+\xeb\x01\xd0\xeb\x01\x01\x51\x04\xd0\xeb\x01\xa0\xec\x01\x01\x57\x04\xa0\xec\
+\x01\xa8\xec\x01\x01\x51\x04\xa8\xec\x01\xf8\xec\x01\x01\x57\x04\xf8\xec\x01\
+\x80\xed\x01\x01\x51\x04\x80\xed\x01\xd0\xed\x01\x01\x57\x04\xd0\xed\x01\xd8\
+\xed\x01\x01\x51\x04\xd8\xed\x01\xa8\xee\x01\x01\x57\x04\xa8\xee\x01\xb0\xee\
+\x01\x01\x51\x04\xb0\xee\x01\x80\xef\x01\x01\x57\x04\x80\xef\x01\x88\xef\x01\
+\x01\x51\x04\x88\xef\x01\xd8\xef\x01\x01\x57\x04\xd8\xef\x01\xe0\xef\x01\x01\
+\x51\x04\xe0\xef\x01\xb0\xf0\x01\x01\x57\x04\xb0\xf0\x01\xb8\xf0\x01\x01\x51\
+\x04\xb8\xf0\x01\x88\xf1\x01\x01\x57\x04\x88\xf1\x01\x90\xf1\x01\x01\x51\x04\
+\x90\xf1\x01\xe0\xf1\x01\x01\x57\x04\xe0\xf1\x01\xe8\xf1\x01\x01\x51\x04\xe8\
+\xf1\x01\xb8\xf2\x01\x01\x57\x04\xb8\xf2\x01\xc0\xf2\x01\x01\x51\x04\xc0\xf2\
+\x01\x90\xf3\x01\x01\x57\x04\x90\xf3\x01\x98\xf3\x01\x01\x51\x04\x98\xf3\x01\
+\xe8\xf3\x01\x01\x57\x04\xe8\xf3\x01\xf0\xf3\x01\x01\x51\x04\xf0\xf3\x01\xc0\
+\xf4\x01\x01\x57\x04\xc0\xf4\x01\xc8\xf4\x01\x01\x51\x04\xc8\xf4\x01\x98\xf5\
+\x01\x01\x57\x04\x98\xf5\x01\xa0\xf5\x01\x01\x51\x04\xa0\xf5\x01\xe8\xf5\x01\
+\x01\x57\x04\xe8\xf5\x01\xf0\xf5\x01\x01\x51\x04\xf0\xf5\x01\xd0\xf6\x01\x01\
+\x57\x04\xd0\xf6\x01\xd8\xf6\x01\x01\x53\x04\xd8\xf6\x01\xa8\xf7\x01\x01\x57\
+\x04\xa8\xf7\x01\xb0\xf7\x01\x01\x53\x04\xb0\xf7\x01\x80\xf8\x01\x01\x57\x04\
+\x80\xf8\x01\x88\xf8\x01\x01\x53\x04\x88\xf8\x01\xd8\xf8\x01\x01\x57\x04\xd8\
+\xf8\x01\xe0\xf8\x01\x01\x53\x04\xe0\xf8\x01\xb0\xf9\x01\x01\x57\x04\xb0\xf9\
+\x01\xb8\xf9\x01\x01\x53\x04\xb8\xf9\x01\x88\xfa\x01\x01\x57\x04\x88\xfa\x01\
+\x90\xfa\x01\x01\x53\x04\x90\xfa\x01\xe0\xfa\x01\x01\x57\x04\xe0\xfa\x01\xe8\
+\xfa\x01\x01\x53\x04\xe8\xfa\x01\xb8\xfb\x01\x01\x57\x04\xb8\xfb\x01\xc0\xfb\
+\x01\x01\x53\x04\xc0\xfb\x01\x90\xfc\x01\x01\x57\x04\x90\xfc\x01\x98\xfc\x01\
+\x01\x53\x04\x98\xfc\x01\xe8\xfc\x01\x01\x57\x04\xe8\xfc\x01\xf0\xfc\x01\x01\
+\x53\x04\xf0\xfc\x01\xc0\xfd\x01\x01\x57\x04\xc0\xfd\x01\xc8\xfd\x01\x01\x53\
+\x04\xc8\xfd\x01\x98\xfe\x01\x01\x57\x04\x98\xfe\x01\xa0\xfe\x01\x01\x53\x04\
+\xa0\xfe\x01\xf0\xfe\x01\x01\x57\x04\xf0\xfe\x01\xf8\xfe\x01\x01\x53\x04\xf8\
+\xfe\x01\xc8\xff\x01\x01\x57\x04\xc8\xff\x01\xd0\xff\x01\x01\x53\x04\xd0\xff\
+\x01\xa0\x80\x02\x01\x57\x04\xa0\x80\x02\xa8\x80\x02\x01\x53\x04\xa8\x80\x02\
+\xf8\x80\x02\x01\x57\x04\xf8\x80\x02\x80\x81\x02\x01\x53\x04\x80\x81\x02\xd0\
+\x81\x02\x01\x57\x04\xd0\x81\x02\xd8\x81\x02\x01\x53\x04\xd8\x81\x02\xa8\x82\
+\x02\x01\x57\x04\xa8\x82\x02\xb0\x82\x02\x01\x53\x04\xb0\x82\x02\x80\x83\x02\
+\x01\x57\x04\x80\x83\x02\x88\x83\x02\x01\x53\x04\x88\x83\x02\xd8\x83\x02\x01\
+\x57\x04\xd8\x83\x02\xe0\x83\x02\x01\x53\x04\xe0\x83\x02\xb0\x84\x02\x01\x57\
+\x04\xb0\x84\x02\xb8\x84\x02\x01\x53\x04\xb8\x84\x02\x88\x85\x02\x01\x57\x04\
+\x88\x85\x02\x90\x85\x02\x01\x53\x04\x90\x85\x02\xe0\x85\x02\x01\x57\x04\xe0\
+\x85\x02\xe8\x85\x02\x01\x53\x04\xe8\x85\x02\xb8\x86\x02\x01\x57\x04\xb8\x86\
+\x02\xc0\x86\x02\x01\x53\x04\xc0\x86\x02\x90\x87\x02\x01\x57\x04\x90\x87\x02\
+\x98\x87\x02\x01\x53\x04\x98\x87\x02\xe8\x87\x02\x01\x57\x04\xe8\x87\x02\xf0\
+\x87\x02\x01\x53\x04\xf0\x87\x02\xc0\x88\x02\x01\x57\x04\xc0\x88\x02\xc8\x88\
+\x02\x01\x53\x04\xc8\x88\x02\xa0\x89\x02\x01\x57\x04\xa0\x89\x02\xa8\x89\x02\
+\x01\x54\x04\xa8\x89\x02\x88\x8a\x02\x01\x57\x04\x88\x8a\x02\x90\x8a\x02\x01\
+\x55\x04\x90\x8a\x02\xe8\x8a\x02\x01\x57\x04\xe8\x8a\x02\xf0\x8a\x02\x01\x54\
+\x04\xf0\x8a\x02\xc0\x8b\x02\x01\x57\x04\xc0\x8b\x02\xc8\x8b\x02\x01\x52\x04\
+\xc8\x8b\x02\xa0\x8c\x02\x01\x57\x04\xa0\x8c\x02\xa8\x8c\x02\x01\x52\x04\xa8\
+\x8c\x02\xf8\x8c\x02\x01\x57\x04\xf8\x8c\x02\x80\x8d\x02\x01\x52\x04\x80\x8d\
+\x02\xd0\x8d\x02\x01\x57\x04\xd0\x8d\x02\xd8\x8d\x02\x01\x52\x04\xd8\x8d\x02\
+\xa8\x8e\x02\x01\x57\x04\xa8\x8e\x02\xb0\x8e\x02\x01\x52\x04\xb0\x8e\x02\x80\
+\x8f\x02\x01\x57\x04\x80\x8f\x02\x88\x8f\x02\x01\x52\x04\x88\x8f\x02\xd8\x8f\
+\x02\x01\x57\x04\xd8\x8f\x02\xe0\x8f\x02\x01\x52\x04\xe0\x8f\x02\xb0\x90\x02\
+\x01\x57\x04\xb0\x90\x02\xb8\x90\x02\x01\x52\x04\xb8\x90\x02\x88\x91\x02\x01\
+\x57\x04\x88\x91\x02\x90\x91\x02\x01\x52\x04\x90\x91\x02\xe0\x91\x02\x01\x57\
+\x04\xe0\x91\x02\xe8\x91\x02\x01\x52\x04\xe8\x91\x02\xb8\x92\x02\x01\x57\x04\
+\xb8\x92\x02\xc0\x92\x02\x01\x52\x04\xc0\x92\x02\x90\x93\x02\x01\x57\x04\x90\
+\x93\x02\x98\x93\x02\x01\x52\x04\x98\x93\x02\xe8\x93\x02\x01\x57\x04\xe8\x93\
+\x02\xf0\x93\x02\x01\x52\x04\xf0\x93\x02\xc0\x94\x02\x01\x57\x04\xc0\x94\x02\
+\xc8\x94\x02\x01\x52\x04\xc8\x94\x02\x98\x95\x02\x01\x57\x04\x98\x95\x02\xa0\
+\x95\x02\x01\x52\x04\xa0\x95\x02\xf0\x95\x02\x01\x57\x04\xf0\x95\x02\xf8\x95\
+\x02\x01\x52\x04\xf8\x95\x02\xc8\x96\x02\x01\x57\x04\xc8\x96\x02\xd0\x96\x02\
+\x01\x52\x04\xd0\x96\x02\xa0\x97\x02\x01\x57\x04\xa0\x97\x02\xa8\x97\x02\x01\
+\x52\x04\xa8\x97\x02\xf8\x97\x02\x01\x57\x04\xf8\x97\x02\x80\x98\x02\x01\x52\
+\x04\x80\x98\x02\xd0\x98\x02\x01\x57\x04\xd0\x98\x02\xd8\x98\x02\x01\x52\x04\
+\xd8\x98\x02\xa8\x99\x02\x01\x57\x04\xa8\x99\x02\xb0\x99\x02\x01\x52\x04\xb0\
+\x99\x02\x80\x9a\x02\x01\x57\x04\x80\x9a\x02\x88\x9a\x02\x01\x52\x04\x88\x9a\
+\x02\xd8\x9a\x02\x01\x57\x04\xd8\x9a\x02\xe0\x9a\x02\x01\x52\x04\xe0\x9a\x02\
+\xb0\x9b\x02\x01\x57\x04\xb0\x9b\x02\xb8\x9b\x02\x01\x52\x04\xb8\x9b\x02\x88\
+\x9c\x02\x01\x57\x04\x88\x9c\x02\x90\x9c\x02\x01\x52\x04\x90\x9c\x02\xe0\x9c\
+\x02\x01\x57\x04\xe0\x9c\x02\xe8\x9c\x02\x01\x52\x04\xe8\x9c\x02\xb8\x9d\x02\
+\x01\x57\x04\xb8\x9d\x02\xc0\x9d\x02\x01\x52\x04\xc0\x9d\x02\x90\x9e\x02\x01\
+\x57\x04\x90\x9e\x02\x98\x9e\x02\x01\x52\x04\x98\x9e\x02\xe8\x9e\x02\x01\x57\
+\x04\xe8\x9e\x02\xf0\x9e\x02\x01\x52\x04\xf0\x9e\x02\xc0\x9f\x02\x01\x57\x04\
+\xc0\x9f\x02\xc8\x9f\x02\x01\x52\x04\xc8\x9f\x02\x98\xa0\x02\x01\x57\x04\x98\
+\xa0\x02\xa0\xa0\x02\x01\x52\x04\xa0\xa0\x02\xe8\xa0\x02\x01\x57\x04\xe8\xa0\
+\x02\xf0\xa0\x02\x01\x51\0\x04\xd0\xe0\x01\xe8\xe0\x01\x03\x7a\xc8\0\x04\xe8\
+\xe0\x01\xb0\xf6\x01\x01\x54\0\x04\xc0\xea\x03\x98\xeb\x03\x0d\x71\0\xa8\xab\
+\x80\x80\0\xa8\xaf\x80\x80\0\x9f\0\x04\x98\xa1\x02\xb0\xa1\x02\x02\x30\x9f\x04\
+\xf8\xe4\x03\xf0\xe5\x03\x02\x30\x9f\x04\xf0\xe5\x03\xa0\xe7\x03\x02\x31\x9f\
+\x04\xa0\xe7\x03\xf0\xe8\x03\x02\x32\x9f\x04\xf0\xe8\x03\xc0\xea\x03\x02\x33\
+\x9f\x04\xc0\xea\x03\x98\xeb\x03\x02\x34\x9f\0\x04\x98\xa1\x02\xb0\xa1\x02\x02\
+\x7a\x38\x04\xf8\xe4\x03\xc8\xeb\x03\x02\x7a\x38\0\x04\xb0\xa1\x02\xe0\xa1\x02\
+\x0d\x71\0\xa8\xab\x80\x80\0\xa8\xb3\x80\x80\0\x9f\0\x04\xb0\xa1\x02\xf8\xe4\
+\x03\x03\x11\0\x9f\0\x04\x98\xa2\x02\xf0\xa2\x02\x02\x31\x9f\x04\xf0\xa2\x02\
+\xd8\xa3\x02\x02\x32\x9f\x04\xd8\xa3\x02\xc8\xa4\x02\x02\x33\x9f\x04\xc8\xa4\
+\x02\xb0\xa5\x02\x02\x34\x9f\x04\xb0\xa5\x02\x90\xa6\x02\x02\x35\x9f\x04\x90\
+\xa6\x02\xf0\xa6\x02\x02\x36\x9f\x04\xf0\xa6\x02\xd0\xa7\x02\x02\x37\x9f\x04\
+\xd0\xa7\x02\xb0\xa8\x02\x02\x38\x9f\x04\xb0\xa8\x02\x90\xa9\x02\x02\x39\x9f\
+\x04\x90\xa9\x02\xf0\xa9\x02\x02\x3a\x9f\x04\xf0\xa9\x02\xd0\xaa\x02\x02\x3b\
+\x9f\x04\xd0\xaa\x02\xb0\xab\x02\x02\x3c\x9f\x04\xb0\xab\x02\x90\xac\x02\x02\
+\x3d\x9f\x04\x90\xac\x02\xf0\xac\x02\x02\x3e\x9f\x04\xf0\xac\x02\xd0\xad\x02\
+\x02\x3f\x9f\x04\xd0\xad\x02\xb0\xae\x02\x02\x40\x9f\x04\xb0\xae\x02\x90\xaf\
+\x02\x02\x41\x9f\x04\x90\xaf\x02\xf0\xaf\x02\x02\x42\x9f\x04\xf0\xaf\x02\xd0\
+\xb0\x02\x02\x43\x9f\x04\xd0\xb0\x02\xb0\xb1\x02\x02\x44\x9f\x04\xb0\xb1\x02\
+\x90\xb2\x02\x02\x45\x9f\x04\x90\xb2\x02\xf0\xb2\x02\x02\x46\x9f\x04\xf0\xb2\
+\x02\xd0\xb3\x02\x02\x47\x9f\x04\xd0\xb3\x02\xb0\xb4\x02\x02\x48\x9f\x04\xb0\
+\xb4\x02\x90\xb5\x02\x02\x49\x9f\x04\x90\xb5\x02\xf0\xb5\x02\x02\x4a\x9f\x04\
+\xf0\xb5\x02\xd0\xb6\x02\x02\x4b\x9f\x04\xd0\xb6\x02\xb0\xb7\x02\x02\x4c\x9f\
+\x04\xb0\xb7\x02\x90\xb8\x02\x02\x4d\x9f\x04\x90\xb8\x02\xf0\xb8\x02\x02\x4e\
+\x9f\x04\xf0\xb8\x02\xc8\xb9\x02\x02\x4f\x9f\x04\xc8\xb9\x02\xe0\xb9\x02\x02\
+\x30\x9f\x04\xe0\xb9\x02\xb8\xba\x02\x02\x31\x9f\x04\xb8\xba\x02\x90\xbb\x02\
+\x02\x32\x9f\x04\x90\xbb\x02\xe8\xbb\x02\x02\x33\x9f\x04\xe8\xbb\x02\xc0\xbc\
+\x02\x02\x34\x9f\x04\xc0\xbc\x02\x98\xbd\x02\x02\x35\x9f\x04\x98\xbd\x02\xf0\
+\xbd\x02\x02\x36\x9f\x04\xf0\xbd\x02\xc8\xbe\x02\x02\x37\x9f\x04\xc8\xbe\x02\
+\xa0\xbf\x02\x02\x38\x9f\x04\xa0\xbf\x02\xf8\xbf\x02\x02\x39\x9f\x04\xf8\xbf\
+\x02\xd0\xc0\x02\x02\x3a\x9f\x04\xd0\xc0\x02\xa8\xc1\x02\x02\x3b\x9f\x04\xa8\
+\xc1\x02\x80\xc2\x02\x02\x3c\x9f\x04\x80\xc2\x02\xd8\xc2\x02\x02\x3d\x9f\x04\
+\xd8\xc2\x02\xb0\xc3\x02\x02\x3e\x9f\x04\xb0\xc3\x02\x88\xc4\x02\x02\x3f\x9f\
+\x04\x88\xc4\x02\xe0\xc4\x02\x02\x40\x9f\x04\xe0\xc4\x02\xb8\xc5\x02\x02\x41\
+\x9f\x04\xb8\xc5\x02\x90\xc6\x02\x02\x42\x9f\x04\x90\xc6\x02\xe8\xc6\x02\x02\
+\x43\x9f\x04\xe8\xc6\x02\xc0\xc7\x02\x02\x44\x9f\x04\xc0\xc7\x02\x98\xc8\x02\
+\x02\x45\x9f\x04\x98\xc8\x02\xf0\xc8\x02\x02\x46\x9f\x04\xf0\xc8\x02\xc8\xc9\
+\x02\x02\x47\x9f\x04\xc8\xc9\x02\xa0\xca\x02\x02\x48\x9f\x04\xa0\xca\x02\xf8\
+\xca\x02\x02\x49\x9f\x04\xf8\xca\x02\xd0\xcb\x02\x02\x4a\x9f\x04\xd0\xcb\x02\
+\xa8\xcc\x02\x02\x4b\x9f\x04\xa8\xcc\x02\x80\xcd\x02\x02\x4c\x9f\x04\x80\xcd\
+\x02\xd8\xcd\x02\x02\x4d\x9f\x04\xd8\xcd\x02\xb0\xce\x02\x02\x4e\x9f\x04\xb0\
+\xce\x02\x80\xcf\x02\x02\x4f\x9f\x04\x80\xcf\x02\x90\xcf\x02\x02\x30\x9f\x04\
+\x90\xcf\x02\xe8\xcf\x02\x02\x31\x9f\x04\xe8\xcf\x02\xc0\xd0\x02\x02\x32\x9f\
+\x04\xc0\xd0\x02\x98\xd1\x02\x02\x33\x9f\x04\x98\xd1\x02\xf0\xd1\x02\x02\x34\
+\x9f\x04\xf0\xd1\x02\xc8\xd2\x02\x02\x35\x9f\x04\xc8\xd2\x02\xa0\xd3\x02\x02\
+\x36\x9f\x04\xa0\xd3\x02\xf8\xd3\x02\x02\x37\x9f\x04\xf8\xd3\x02\xd0\xd4\x02\
+\x02\x38\x9f\x04\xd0\xd4\x02\xa8\xd5\x02\x02\x39\x9f\x04\xa8\xd5\x02\x80\xd6\
+\x02\x02\x3a\x9f\x04\x80\xd6\x02\xd8\xd6\x02\x02\x3b\x9f\x04\xd8\xd6\x02\xb0\
+\xd7\x02\x02\x3c\x9f\x04\xb0\xd7\x02\x88\xd8\x02\x02\x3d\x9f\x04\x88\xd8\x02\
+\xe0\xd8\x02\x02\x3e\x9f\x04\xe0\xd8\x02\xb8\xd9\x02\x02\x3f\x9f\x04\xb8\xd9\
+\x02\x90\xda\x02\x02\x40\x9f\x04\x90\xda\x02\xe8\xda\x02\x02\x41\x9f\x04\xe8\
+\xda\x02\xc0\xdb\x02\x02\x42\x9f\x04\xc0\xdb\x02\x98\xdc\x02\x02\x43\x9f\x04\
+\x98\xdc\x02\xf0\xdc\x02\x02\x44\x9f\x04\xf0\xdc\x02\xc8\xdd\x02\x02\x45\x9f\
+\x04\xc8\xdd\x02\xa0\xde\x02\x02\x46\x9f\x04\xa0\xde\x02\xf8\xde\x02\x02\x47\
+\x9f\x04\xf8\xde\x02\xd0\xdf\x02\x02\x48\x9f\x04\xd0\xdf\x02\xa8\xe0\x02\x02\
+\x49\x9f\x04\xa8\xe0\x02\x80\xe1\x02\x02\x4a\x9f\x04\x80\xe1\x02\xd8\xe1\x02\
+\x02\x4b\x9f\x04\xd8\xe1\x02\xb0\xe2\x02\x02\x4c\x9f\x04\xb0\xe2\x02\x88\xe3\
+\x02\x02\x4d\x9f\x04\x88\xe3\x02\xe0\xe3\x02\x02\x4e\x9f\x04\xe0\xe3\x02\xb8\
+\xe4\x02\x02\x4f\x9f\x04\xb8\xe4\x02\xc8\xe4\x02\x02\x30\x9f\x04\xc8\xe4\x02\
+\xa0\xe5\x02\x02\x31\x9f\x04\xa0\xe5\x02\xf8\xe5\x02\x02\x32\x9f\x04\xf8\xe5\
+\x02\xd0\xe6\x02\x02\x33\x9f\x04\xd0\xe6\x02\xa8\xe7\x02\x02\x34\x9f\x04\xa8\
+\xe7\x02\x80\xe8\x02\x02\x35\x9f\x04\x80\xe8\x02\xd8\xe8\x02\x02\x36\x9f\x04\
+\xd8\xe8\x02\xb0\xe9\x02\x02\x37\x9f\x04\xb0\xe9\x02\x88\xea\x02\x02\x38\x9f\
+\x04\x88\xea\x02\xe0\xea\x02\x02\x39\x9f\x04\xe0\xea\x02\xb8\xeb\x02\x02\x3a\
+\x9f\x04\xb8\xeb\x02\x90\xec\x02\x02\x3b\x9f\x04\x90\xec\x02\xe8\xec\x02\x02\
+\x3c\x9f\x04\xe8\xec\x02\xc0\xed\x02\x02\x3d\x9f\x04\xc0\xed\x02\x98\xee\x02\
+\x02\x3e\x9f\x04\x98\xee\x02\xf0\xee\x02\x02\x3f\x9f\x04\xf0\xee\x02\xc8\xef\
+\x02\x02\x40\x9f\x04\xc8\xef\x02\xa0\xf0\x02\x02\x41\x9f\x04\xa0\xf0\x02\xf8\
+\xf0\x02\x02\x42\x9f\x04\xf8\xf0\x02\xd0\xf1\x02\x02\x43\x9f\x04\xd0\xf1\x02\
+\xa8\xf2\x02\x02\x44\x9f\x04\xa8\xf2\x02\x80\xf3\x02\x02\x45\x9f\x04\x80\xf3\
+\x02\xd8\xf3\x02\x02\x46\x9f\x04\xd8\xf3\x02\xb0\xf4\x02\x02\x47\x9f\x04\xb0\
+\xf4\x02\x88\xf5\x02\x02\x48\x9f\x04\x88\xf5\x02\xe0\xf5\x02\x02\x49\x9f\x04\
+\xe0\xf5\x02\xb8\xf6\x02\x02\x4a\x9f\x04\xb8\xf6\x02\x90\xf7\x02\x02\x4b\x9f\
+\x04\x90\xf7\x02\xe8\xf7\x02\x02\x4c\x9f\x04\xe8\xf7\x02\xc0\xf8\x02\x02\x4d\
+\x9f\x04\xc0\xf8\x02\x98\xf9\x02\x02\x4e\x9f\x04\x98\xf9\x02\xf0\xf9\x02\x02\
+\x4f\x9f\x04\xf0\xf9\x02\x80\xfa\x02\x02\x30\x9f\x04\x80\xfa\x02\xd8\xfa\x02\
+\x02\x31\x9f\x04\xd8\xfa\x02\xb0\xfb\x02\x02\x32\x9f\x04\xb0\xfb\x02\x88\xfc\
+\x02\x02\x33\x9f\x04\x88\xfc\x02\xe0\xfc\x02\x02\x34\x9f\x04\xe0\xfc\x02\xb8\
+\xfd\x02\x02\x35\x9f\x04\xb8\xfd\x02\x90\xfe\x02\x02\x36\x9f\x04\x90\xfe\x02\
+\xe8\xfe\x02\x02\x37\x9f\x04\xe8\xfe\x02\xc0\xff\x02\x02\x38\x9f\x04\xc0\xff\
+\x02\x98\x80\x03\x02\x39\x9f\x04\x98\x80\x03\xf0\x80\x03\x02\x3a\x9f\x04\xf0\
+\x80\x03\xc8\x81\x03\x02\x3b\x9f\x04\xc8\x81\x03\xa0\x82\x03\x02\x3c\x9f\x04\
+\xa0\x82\x03\xf8\x82\x03\x02\x3d\x9f\x04\xf8\x82\x03\xd0\x83\x03\x02\x3e\x9f\
+\x04\xd0\x83\x03\xa8\x84\x03\x02\x3f\x9f\x04\xa8\x84\x03\x80\x85\x03\x02\x40\
+\x9f\x04\x80\x85\x03\xd8\x85\x03\x02\x41\x9f\x04\xd8\x85\x03\xb0\x86\x03\x02\
+\x42\x9f\x04\xb0\x86\x03\x88\x87\x03\x02\x43\x9f\x04\x88\x87\x03\xe0\x87\x03\
+\x02\x44\x9f\x04\xe0\x87\x03\xb8\x88\x03\x02\x45\x9f\x04\xb8\x88\x03\x90\x89\
+\x03\x02\x46\x9f\x04\x90\x89\x03\xe8\x89\x03\x02\x47\x9f\x04\xe8\x89\x03\xc0\
+\x8a\x03\x02\x48\x9f\x04\xc0\x8a\x03\x98\x8b\x03\x02\x49\x9f\x04\x98\x8b\x03\
+\xf0\x8b\x03\x02\x4a\x9f\x04\xf0\x8b\x03\xc8\x8c\x03\x02\x4b\x9f\x04\xc8\x8c\
+\x03\xa0\x8d\x03\x02\x4c\x9f\x04\xa0\x8d\x03\xf8\x8d\x03\x02\x4d\x9f\x04\xf8\
+\x8d\x03\xd0\x8e\x03\x02\x4e\x9f\x04\xd0\x8e\x03\xa0\x8f\x03\x02\x4f\x9f\x04\
+\xa0\x8f\x03\xb0\x8f\x03\x02\x30\x9f\x04\xb0\x8f\x03\x88\x90\x03\x02\x31\x9f\
+\x04\x88\x90\x03\xe8\x90\x03\x02\x32\x9f\x04\xe8\x90\x03\xc0\x91\x03\x02\x33\
+\x9f\x04\xc0\x91\x03\x98\x92\x03\x02\x34\x9f\x04\x98\x92\x03\xf0\x92\x03\x02\
+\x35\x9f\x04\xf0\x92\x03\xc8\x93\x03\x02\x36\x9f\x04\xc8\x93\x03\xa0\x94\x03\
+\x02\x37\x9f\x04\xa0\x94\x03\xf8\x94\x03\x02\x38\x9f\x04\xf8\x94\x03\xd0\x95\
+\x03\x02\x39\x9f\x04\xd0\x95\x03\xa8\x96\x03\x02\x3a\x9f\x04\xa8\x96\x03\x80\
+\x97\x03\x02\x3b\x9f\x04\x80\x97\x03\xd8\x97\x03\x02\x3c\x9f\x04\xd8\x97\x03\
+\xb0\x98\x03\x02\x3d\x9f\x04\xb0\x98\x03\x88\x99\x03\x02\x3e\x9f\x04\x88\x99\
+\x03\xe0\x99\x03\x02\x3f\x9f\x04\xe0\x99\x03\xb8\x9a\x03\x02\x40\x9f\x04\xb8\
+\x9a\x03\x90\x9b\x03\x02\x41\x9f\x04\x90\x9b\x03\xe8\x9b\x03\x02\x42\x9f\x04\
+\xe8\x9b\x03\xc0\x9c\x03\x02\x43\x9f\x04\xc0\x9c\x03\x98\x9d\x03\x02\x44\x9f\
+\x04\x98\x9d\x03\xf0\x9d\x03\x02\x45\x9f\x04\xf0\x9d\x03\xc8\x9e\x03\x02\x46\
+\x9f\x04\xc8\x9e\x03\xa0\x9f\x03\x02\x47\x9f\x04\xa0\x9f\x03\xf8\x9f\x03\x02\
+\x48\x9f\x04\xf8\x9f\x03\xd0\xa0\x03\x02\x49\x9f\x04\xd0\xa0\x03\xa8\xa1\x03\
+\x02\x4a\x9f\x04\xa8\xa1\x03\x80\xa2\x03\x02\x4b\x9f\x04\x80\xa2\x03\xd8\xa2\
+\x03\x02\x4c\x9f\x04\xd8\xa2\x03\xb0\xa3\x03\x02\x4d\x9f\x04\xb0\xa3\x03\x88\
+\xa4\x03\x02\x4e\x9f\x04\x88\xa4\x03\xd8\xa4\x03\x02\x4f\x9f\x04\xd8\xa4\x03\
+\xe8\xa4\x03\x02\x30\x9f\x04\xe8\xa4\x03\xc0\xa5\x03\x02\x31\x9f\x04\xc0\xa5\
+\x03\x98\xa6\x03\x02\x32\x9f\x04\x98\xa6\x03\xf0\xa6\x03\x02\x33\x9f\x04\xf0\
+\xa6\x03\xc8\xa7\x03\x02\x34\x9f\x04\xc8\xa7\x03\xa0\xa8\x03\x02\x35\x9f\x04\
+\xa0\xa8\x03\xf8\xa8\x03\x02\x36\x9f\x04\xf8\xa8\x03\xd0\xa9\x03\x02\x37\x9f\
+\x04\xd0\xa9\x03\xa8\xaa\x03\x02\x38\x9f\x04\xa8\xaa\x03\x80\xab\x03\x02\x39\
+\x9f\x04\x80\xab\x03\xd8\xab\x03\x02\x3a\x9f\x04\xd8\xab\x03\xb0\xac\x03\x02\
+\x3b\x9f\x04\xb0\xac\x03\x88\xad\x03\x02\x3c\x9f\x04\x88\xad\x03\xe0\xad\x03\
+\x02\x3d\x9f\x04\xe0\xad\x03\xb8\xae\x03\x02\x3e\x9f\x04\xb8\xae\x03\x90\xaf\
+\x03\x02\x3f\x9f\x04\x90\xaf\x03\xe8\xaf\x03\x02\x40\x9f\x04\xe8\xaf\x03\xc0\
+\xb0\x03\x02\x41\x9f\x04\xc0\xb0\x03\x98\xb1\x03\x02\x42\x9f\x04\x98\xb1\x03\
+\xf0\xb1\x03\x02\x43\x9f\x04\xf0\xb1\x03\xc8\xb2\x03\x02\x44\x9f\x04\xc8\xb2\
+\x03\xa0\xb3\x03\x02\x45\x9f\x04\xa0\xb3\x03\xf8\xb3\x03\x02\x46\x9f\x04\xf8\
+\xb3\x03\xd0\xb4\x03\x02\x47\x9f\x04\xd0\xb4\x03\xa8\xb5\x03\x02\x48\x9f\x04\
+\xa8\xb5\x03\x80\xb6\x03\x02\x49\x9f\x04\x80\xb6\x03\xd8\xb6\x03\x02\x4a\x9f\
+\x04\xd8\xb6\x03\xb0\xb7\x03\x02\x4b\x9f\x04\xb0\xb7\x03\x88\xb8\x03\x02\x4c\
+\x9f\x04\x88\xb8\x03\xe0\xb8\x03\x02\x4d\x9f\x04\xe0\xb8\x03\xb8\xb9\x03\x02\
+\x4e\x9f\x04\xb8\xb9\x03\x88\xba\x03\x02\x4f\x9f\x04\x88\xba\x03\x98\xba\x03\
+\x02\x30\x9f\x04\x98\xba\x03\xf0\xba\x03\x02\x31\x9f\x04\xf0\xba\x03\xc8\xbb\
+\x03\x02\x32\x9f\x04\xc8\xbb\x03\xa0\xbc\x03\x02\x33\x9f\x04\xa0\xbc\x03\xf8\
+\xbc\x03\x02\x34\x9f\x04\xf8\xbc\x03\xd0\xbd\x03\x02\x35\x9f\x04\xd0\xbd\x03\
+\xa8\xbe\x03\x02\x36\x9f\x04\xa8\xbe\x03\x80\xbf\x03\x02\x37\x9f\x04\x80\xbf\
+\x03\xd8\xbf\x03\x02\x38\x9f\x04\xd8\xbf\x03\xb0\xc0\x03\x02\x39\x9f\x04\xb0\
+\xc0\x03\x88\xc1\x03\x02\x3a\x9f\x04\x88\xc1\x03\xe0\xc1\x03\x02\x3b\x9f\x04\
+\xe0\xc1\x03\xb8\xc2\x03\x02\x3c\x9f\x04\xb8\xc2\x03\x90\xc3\x03\x02\x3d\x9f\
+\x04\x90\xc3\x03\xe8\xc3\x03\x02\x3e\x9f\x04\xe8\xc3\x03\xc0\xc4\x03\x02\x3f\
+\x9f\x04\xc0\xc4\x03\x98\xc5\x03\x02\x40\x9f\x04\x98\xc5\x03\xf0\xc5\x03\x02\
+\x41\x9f\x04\xf0\xc5\x03\xc8\xc6\x03\x02\x42\x9f\x04\xc8\xc6\x03\xa0\xc7\x03\
+\x02\x43\x9f\x04\xa0\xc7\x03\xf8\xc7\x03\x02\x44\x9f\x04\xf8\xc7\x03\xd0\xc8\
+\x03\x02\x45\x9f\x04\xd0\xc8\x03\xa8\xc9\x03\x02\x46\x9f\x04\xa8\xc9\x03\x80\
+\xca\x03\x02\x47\x9f\x04\x80\xca\x03\xd8\xca\x03\x02\x48\x9f\x04\xd8\xca\x03\
+\xb0\xcb\x03\x02\x49\x9f\x04\xb0\xcb\x03\x88\xcc\x03\x02\x4a\x9f\x04\x88\xcc\
+\x03\xe0\xcc\x03\x02\x4b\x9f\x04\xe8\xcc\x03\xc0\xcd\x03\x02\x4c\x9f\x04\xd0\
+\xcd\x03\xa8\xce\x03\x02\x4d\x9f\x04\xb0\xce\x03\x88\xcf\x03\x02\x4e\x9f\x04\
+\x90\xcf\x03\xe0\xcf\x03\x02\x4f\x9f\x04\xe0\xcf\x03\xe8\xcf\x03\x02\x30\x9f\
+\x04\xe8\xcf\x03\xc0\xd0\x03\x02\x31\x9f\x04\xc0\xd0\x03\x98\xd1\x03\x02\x32\
+\x9f\x04\x98\xd1\x03\xf0\xd1\x03\x02\x33\x9f\x04\xf0\xd1\x03\xc8\xd2\x03\x02\
+\x34\x9f\x04\xc8\xd2\x03\xa0\xd3\x03\x02\x35\x9f\x04\xa0\xd3\x03\xf8\xd3\x03\
+\x02\x36\x9f\x04\xf8\xd3\x03\xd0\xd4\x03\x02\x37\x9f\x04\xd0\xd4\x03\xa8\xd5\
+\x03\x02\x38\x9f\x04\xa8\xd5\x03\x80\xd6\x03\x02\x39\x9f\x04\x80\xd6\x03\xd8\
+\xd6\x03\x02\x3a\x9f\x04\xd8\xd6\x03\xb0\xd7\x03\x02\x3b\x9f\x04\xb0\xd7\x03\
+\x88\xd8\x03\x02\x3c\x9f\x04\x88\xd8\x03\xe0\xd8\x03\x02\x3d\x9f\x04\xe0\xd8\
+\x03\xb8\xd9\x03\x02\x3e\x9f\x04\xb8\xd9\x03\x90\xda\x03\x02\x3f\x9f\x04\x90\
+\xda\x03\xe8\xda\x03\x02\x40\x9f\x04\xe8\xda\x03\xc0\xdb\x03\x02\x41\x9f\x04\
+\xc0\xdb\x03\x98\xdc\x03\x02\x42\x9f\x04\x98\xdc\x03\xf0\xdc\x03\x02\x43\x9f\
+\x04\xf0\xdc\x03\xc8\xdd\x03\x02\x44\x9f\x04\xc8\xdd\x03\xa0\xde\x03\x02\x45\
+\x9f\x04\xa0\xde\x03\xf8\xde\x03\x02\x46\x9f\x04\xf8\xde\x03\xd0\xdf\x03\x02\
+\x47\x9f\x04\xd0\xdf\x03\xa8\xe0\x03\x02\x48\x9f\x04\xa8\xe0\x03\x80\xe1\x03\
+\x02\x49\x9f\x04\x80\xe1\x03\xd8\xe1\x03\x02\x4a\x9f\x04\xd8\xe1\x03\xb0\xe2\
+\x03\x02\x4b\x9f\x04\xb0\xe2\x03\x88\xe3\x03\x02\x4c\x9f\x04\x88\xe3\x03\xe0\
+\xe3\x03\x02\x4d\x9f\x04\xe0\xe3\x03\xb8\xe4\x03\x02\x4e\x9f\x04\xb8\xe4\x03\
+\xf8\xe4\x03\x02\x4f\x9f\0\x04\x98\xa2\x02\xc8\xb9\x02\x02\x30\x9f\x04\xc8\xb9\
+\x02\x80\xcf\x02\x02\x31\x9f\x04\x80\xcf\x02\xb8\xe4\x02\x02\x32\x9f\x04\xb8\
+\xe4\x02\xf0\xf9\x02\x02\x33\x9f\x04\xf0\xf9\x02\xa0\x8f\x03\x02\x34\x9f\x04\
+\xa0\x8f\x03\xd8\xa4\x03\x02\x35\x9f\x04\xd8\xa4\x03\x88\xba\x03\x02\x36\x9f\
+\x04\x88\xba\x03\xe0\xcf\x03\x02\x37\x9f\x04\xe0\xcf\x03\xf8\xe4\x03\x02\x38\
+\x9f\0\x04\x98\xa2\x02\xf0\xa2\x02\x02\x30\x9f\x04\xf0\xa2\x02\xd0\xa3\x02\x01\
+\x58\x04\xd0\xa3\x02\xd8\xa3\x02\x01\x51\x04\xd8\xa3\x02\xc0\xa4\x02\x01\x58\
+\x04\xc0\xa4\x02\xc8\xa4\x02\x01\x51\x04\xc8\xa4\x02\xa8\xa5\x02\x01\x58\x04\
+\xa8\xa5\x02\xb0\xa5\x02\x01\x51\x04\xb0\xa5\x02\x88\xa6\x02\x01\x58\x04\x88\
+\xa6\x02\x90\xa6\x02\x01\x51\x04\x90\xa6\x02\xe8\xa6\x02\x01\x58\x04\xe8\xa6\
+\x02\xf0\xa6\x02\x01\x51\x04\xf0\xa6\x02\xc8\xa7\x02\x01\x58\x04\xc8\xa7\x02\
+\xd0\xa7\x02\x01\x51\x04\xd0\xa7\x02\xa8\xa8\x02\x01\x58\x04\xa8\xa8\x02\xb0\
+\xa8\x02\x01\x51\x04\xb0\xa8\x02\x88\xa9\x02\x01\x58\x04\x88\xa9\x02\x90\xa9\
+\x02\x01\x51\x04\x90\xa9\x02\xe8\xa9\x02\x01\x58\x04\xe8\xa9\x02\xf0\xa9\x02\
+\x01\x51\x04\xf0\xa9\x02\xc8\xaa\x02\x01\x58\x04\xc8\xaa\x02\xd0\xaa\x02\x01\
+\x51\x04\xd0\xaa\x02\xa8\xab\x02\x01\x58\x04\xa8\xab\x02\xb0\xab\x02\x01\x51\
+\x04\xb0\xab\x02\x88\xac\x02\x01\x58\x04\x88\xac\x02\x90\xac\x02\x01\x51\x04\
+\x90\xac\x02\xe8\xac\x02\x01\x58\x04\xe8\xac\x02\xf0\xac\x02\x01\x51\x04\xf0\
+\xac\x02\xc8\xad\x02\x01\x58\x04\xc8\xad\x02\xd0\xad\x02\x01\x51\x04\xd0\xad\
+\x02\xa8\xae\x02\x01\x58\x04\xa8\xae\x02\xb0\xae\x02\x01\x51\x04\xb0\xae\x02\
+\x88\xaf\x02\x01\x58\x04\x88\xaf\x02\x90\xaf\x02\x01\x51\x04\x90\xaf\x02\xe8\
+\xaf\x02\x01\x58\x04\xe8\xaf\x02\xf0\xaf\x02\x01\x51\x04\xf0\xaf\x02\xc8\xb0\
+\x02\x01\x58\x04\xc8\xb0\x02\xd0\xb0\x02\x01\x51\x04\xd0\xb0\x02\xa8\xb1\x02\
+\x01\x58\x04\xa8\xb1\x02\xb0\xb1\x02\x01\x51\x04\xb0\xb1\x02\x88\xb2\x02\x01\
+\x58\x04\x88\xb2\x02\x90\xb2\x02\x01\x51\x04\x90\xb2\x02\xe8\xb2\x02\x01\x58\
+\x04\xe8\xb2\x02\xf0\xb2\x02\x01\x51\x04\xf0\xb2\x02\xc8\xb3\x02\x01\x58\x04\
+\xc8\xb3\x02\xd0\xb3\x02\x01\x51\x04\xd0\xb3\x02\xa8\xb4\x02\x01\x58\x04\xa8\
+\xb4\x02\xb0\xb4\x02\x01\x51\x04\xb0\xb4\x02\x88\xb5\x02\x01\x58\x04\x88\xb5\
+\x02\x90\xb5\x02\x01\x51\x04\x90\xb5\x02\xe8\xb5\x02\x01\x58\x04\xe8\xb5\x02\
+\xf0\xb5\x02\x01\x51\x04\xf0\xb5\x02\xc8\xb6\x02\x01\x58\x04\xc8\xb6\x02\xd0\
+\xb6\x02\x01\x51\x04\xd0\xb6\x02\xa8\xb7\x02\x01\x58\x04\xa8\xb7\x02\xb0\xb7\
+\x02\x01\x51\x04\xb0\xb7\x02\x88\xb8\x02\x01\x58\x04\x88\xb8\x02\x90\xb8\x02\
+\x01\x51\x04\x90\xb8\x02\xe8\xb8\x02\x01\x58\x04\xe8\xb8\x02\xf0\xb8\x02\x01\
+\x51\x04\xf0\xb8\x02\xc0\xb9\x02\x01\x58\x04\xc0\xb9\x02\xc8\xb9\x02\x01\x51\
+\x04\xc8\xb9\x02\xb0\xba\x02\x01\x58\x04\xb0\xba\x02\xb8\xba\x02\x01\x53\x04\
+\xb8\xba\x02\x88\xbb\x02\x01\x58\x04\x88\xbb\x02\x90\xbb\x02\x01\x53\x04\x90\
+\xbb\x02\xe0\xbb\x02\x01\x58\x04\xe0\xbb\x02\xe8\xbb\x02\x01\x53\x04\xe8\xbb\
+\x02\xb8\xbc\x02\x01\x58\x04\xb8\xbc\x02\xc0\xbc\x02\x01\x53\x04\xc0\xbc\x02\
+\x90\xbd\x02\x01\x58\x04\x90\xbd\x02\x98\xbd\x02\x01\x53\x04\x98\xbd\x02\xe8\
+\xbd\x02\x01\x58\x04\xe8\xbd\x02\xf0\xbd\x02\x01\x53\x04\xf0\xbd\x02\xc0\xbe\
+\x02\x01\x58\x04\xc0\xbe\x02\xc8\xbe\x02\x01\x53\x04\xc8\xbe\x02\x98\xbf\x02\
+\x01\x58\x04\x98\xbf\x02\xa0\xbf\x02\x01\x53\x04\xa0\xbf\x02\xf0\xbf\x02\x01\
+\x58\x04\xf0\xbf\x02\xf8\xbf\x02\x01\x53\x04\xf8\xbf\x02\xc8\xc0\x02\x01\x58\
+\x04\xc8\xc0\x02\xd0\xc0\x02\x01\x53\x04\xd0\xc0\x02\xa0\xc1\x02\x01\x58\x04\
+\xa0\xc1\x02\xa8\xc1\x02\x01\x53\x04\xa8\xc1\x02\xf8\xc1\x02\x01\x58\x04\xf8\
+\xc1\x02\x80\xc2\x02\x01\x53\x04\x80\xc2\x02\xd0\xc2\x02\x01\x58\x04\xd0\xc2\
+\x02\xd8\xc2\x02\x01\x53\x04\xd8\xc2\x02\xa8\xc3\x02\x01\x58\x04\xa8\xc3\x02\
+\xb0\xc3\x02\x01\x53\x04\xb0\xc3\x02\x80\xc4\x02\x01\x58\x04\x80\xc4\x02\x88\
+\xc4\x02\x01\x53\x04\x88\xc4\x02\xd8\xc4\x02\x01\x58\x04\xd8\xc4\x02\xe0\xc4\
+\x02\x01\x53\x04\xe0\xc4\x02\xb0\xc5\x02\x01\x58\x04\xb0\xc5\x02\xb8\xc5\x02\
+\x01\x53\x04\xb8\xc5\x02\x88\xc6\x02\x01\x58\x04\x88\xc6\x02\x90\xc6\x02\x01\
+\x53\x04\x90\xc6\x02\xe0\xc6\x02\x01\x58\x04\xe0\xc6\x02\xe8\xc6\x02\x01\x53\
+\x04\xe8\xc6\x02\xb8\xc7\x02\x01\x58\x04\xb8\xc7\x02\xc0\xc7\x02\x01\x53\x04\
+\xc0\xc7\x02\x90\xc8\x02\x01\x58\x04\x90\xc8\x02\x98\xc8\x02\x01\x53\x04\x98\
+\xc8\x02\xe8\xc8\x02\x01\x58\x04\xe8\xc8\x02\xf0\xc8\x02\x01\x53\x04\xf0\xc8\
+\x02\xc0\xc9\x02\x01\x58\x04\xc0\xc9\x02\xc8\xc9\x02\x01\x53\x04\xc8\xc9\x02\
+\x98\xca\x02\x01\x58\x04\x98\xca\x02\xa0\xca\x02\x01\x53\x04\xa0\xca\x02\xf0\
+\xca\x02\x01\x58\x04\xf0\xca\x02\xf8\xca\x02\x01\x53\x04\xf8\xca\x02\xc8\xcb\
+\x02\x01\x58\x04\xc8\xcb\x02\xd0\xcb\x02\x01\x53\x04\xd0\xcb\x02\xa0\xcc\x02\
+\x01\x58\x04\xa0\xcc\x02\xa8\xcc\x02\x01\x53\x04\xa8\xcc\x02\xf8\xcc\x02\x01\
+\x58\x04\xf8\xcc\x02\x80\xcd\x02\x01\x53\x04\x80\xcd\x02\xd0\xcd\x02\x01\x58\
+\x04\xd0\xcd\x02\xd8\xcd\x02\x01\x53\x04\xd8\xcd\x02\xa8\xce\x02\x01\x58\x04\
+\xa8\xce\x02\xb0\xce\x02\x01\x53\x04\xb0\xce\x02\xf8\xce\x02\x01\x58\x04\xf8\
+\xce\x02\x80\xcf\x02\x01\x52\x04\x80\xcf\x02\xe0\xcf\x02\x01\x58\x04\xe0\xcf\
+\x02\xe8\xcf\x02\x01\x53\x04\xe8\xcf\x02\xb8\xd0\x02\x01\x58\x04\xb8\xd0\x02\
+\xc0\xd0\x02\x01\x53\x04\xc0\xd0\x02\x90\xd1\x02\x01\x58\x04\x90\xd1\x02\x98\
+\xd1\x02\x01\x53\x04\x98\xd1\x02\xe8\xd1\x02\x01\x58\x04\xe8\xd1\x02\xf0\xd1\
+\x02\x01\x53\x04\xf0\xd1\x02\xc0\xd2\x02\x01\x58\x04\xc0\xd2\x02\xc8\xd2\x02\
+\x01\x53\x04\xc8\xd2\x02\x98\xd3\x02\x01\x58\x04\x98\xd3\x02\xa0\xd3\x02\x01\
+\x53\x04\xa0\xd3\x02\xf0\xd3\x02\x01\x58\x04\xf0\xd3\x02\xf8\xd3\x02\x01\x53\
+\x04\xf8\xd3\x02\xc8\xd4\x02\x01\x58\x04\xc8\xd4\x02\xd0\xd4\x02\x01\x53\x04\
+\xd0\xd4\x02\xa0\xd5\x02\x01\x58\x04\xa0\xd5\x02\xa8\xd5\x02\x01\x53\x04\xa8\
+\xd5\x02\xf8\xd5\x02\x01\x58\x04\xf8\xd5\x02\x80\xd6\x02\x01\x53\x04\x80\xd6\
+\x02\xd0\xd6\x02\x01\x58\x04\xd0\xd6\x02\xd8\xd6\x02\x01\x53\x04\xd8\xd6\x02\
+\xa8\xd7\x02\x01\x58\x04\xa8\xd7\x02\xb0\xd7\x02\x01\x53\x04\xb0\xd7\x02\x80\
+\xd8\x02\x01\x58\x04\x80\xd8\x02\x88\xd8\x02\x01\x53\x04\x88\xd8\x02\xd8\xd8\
+\x02\x01\x58\x04\xd8\xd8\x02\xe0\xd8\x02\x01\x53\x04\xe0\xd8\x02\xb0\xd9\x02\
+\x01\x58\x04\xb0\xd9\x02\xb8\xd9\x02\x01\x53\x04\xb8\xd9\x02\x88\xda\x02\x01\
+\x58\x04\x88\xda\x02\x90\xda\x02\x01\x53\x04\x90\xda\x02\xe0\xda\x02\x01\x58\
+\x04\xe0\xda\x02\xe8\xda\x02\x01\x53\x04\xe8\xda\x02\xb8\xdb\x02\x01\x58\x04\
+\xb8\xdb\x02\xc0\xdb\x02\x01\x53\x04\xc0\xdb\x02\x90\xdc\x02\x01\x58\x04\x90\
+\xdc\x02\x98\xdc\x02\x01\x53\x04\x98\xdc\x02\xe8\xdc\x02\x01\x58\x04\xe8\xdc\
+\x02\xf0\xdc\x02\x01\x53\x04\xf0\xdc\x02\xc0\xdd\x02\x01\x58\x04\xc0\xdd\x02\
+\xc8\xdd\x02\x01\x53\x04\xc8\xdd\x02\x98\xde\x02\x01\x58\x04\x98\xde\x02\xa0\
+\xde\x02\x01\x53\x04\xa0\xde\x02\xf0\xde\x02\x01\x58\x04\xf0\xde\x02\xf8\xde\
+\x02\x01\x53\x04\xf8\xde\x02\xc8\xdf\x02\x01\x58\x04\xc8\xdf\x02\xd0\xdf\x02\
+\x01\x53\x04\xd0\xdf\x02\xa0\xe0\x02\x01\x58\x04\xa0\xe0\x02\xa8\xe0\x02\x01\
+\x53\x04\xa8\xe0\x02\xf8\xe0\x02\x01\x58\x04\xf8\xe0\x02\x80\xe1\x02\x01\x53\
+\x04\x80\xe1\x02\xd0\xe1\x02\x01\x58\x04\xd0\xe1\x02\xd8\xe1\x02\x01\x53\x04\
+\xd8\xe1\x02\xa8\xe2\x02\x01\x58\x04\xa8\xe2\x02\xb0\xe2\x02\x01\x53\x04\xb0\
+\xe2\x02\x80\xe3\x02\x01\x58\x04\x80\xe3\x02\x88\xe3\x02\x01\x53\x04\x88\xe3\
+\x02\xd8\xe3\x02\x01\x58\x04\xd8\xe3\x02\xe0\xe3\x02\x01\x53\x04\xe0\xe3\x02\
+\xb0\xe4\x02\x01\x58\x04\xb0\xe4\x02\xb8\xe4\x02\x01\x51\x04\xb8\xe4\x02\x98\
+\xe5\x02\x01\x58\x04\x98\xe5\x02\xa0\xe5\x02\x01\x53\x04\xa0\xe5\x02\xf0\xe5\
+\x02\x01\x58\x04\xf0\xe5\x02\xf8\xe5\x02\x01\x53\x04\xf8\xe5\x02\xc8\xe6\x02\
+\x01\x58\x04\xc8\xe6\x02\xd0\xe6\x02\x01\x53\x04\xd0\xe6\x02\xa0\xe7\x02\x01\
+\x58\x04\xa0\xe7\x02\xa8\xe7\x02\x01\x53\x04\xa8\xe7\x02\xf8\xe7\x02\x01\x58\
+\x04\xf8\xe7\x02\x80\xe8\x02\x01\x53\x04\x80\xe8\x02\xd0\xe8\x02\x01\x58\x04\
+\xd0\xe8\x02\xd8\xe8\x02\x01\x53\x04\xd8\xe8\x02\xa8\xe9\x02\x01\x58\x04\xa8\
+\xe9\x02\xb0\xe9\x02\x01\x53\x04\xb0\xe9\x02\x80\xea\x02\x01\x58\x04\x80\xea\
+\x02\x88\xea\x02\x01\x53\x04\x88\xea\x02\xd8\xea\x02\x01\x58\x04\xd8\xea\x02\
+\xe0\xea\x02\x01\x53\x04\xe0\xea\x02\xb0\xeb\x02\x01\x58\x04\xb0\xeb\x02\xb8\
+\xeb\x02\x01\x53\x04\xb8\xeb\x02\x88\xec\x02\x01\x58\x04\x88\xec\x02\x90\xec\
+\x02\x01\x53\x04\x90\xec\x02\xe0\xec\x02\x01\x58\x04\xe0\xec\x02\xe8\xec\x02\
+\x01\x53\x04\xe8\xec\x02\xb8\xed\x02\x01\x58\x04\xb8\xed\x02\xc0\xed\x02\x01\
+\x53\x04\xc0\xed\x02\x90\xee\x02\x01\x58\x04\x90\xee\x02\x98\xee\x02\x01\x53\
+\x04\x98\xee\x02\xe8\xee\x02\x01\x58\x04\xe8\xee\x02\xf0\xee\x02\x01\x53\x04\
+\xf0\xee\x02\xc0\xef\x02\x01\x58\x04\xc0\xef\x02\xc8\xef\x02\x01\x53\x04\xc8\
+\xef\x02\x98\xf0\x02\x01\x58\x04\x98\xf0\x02\xa0\xf0\x02\x01\x53\x04\xa0\xf0\
+\x02\xf0\xf0\x02\x01\x58\x04\xf0\xf0\x02\xf8\xf0\x02\x01\x53\x04\xf8\xf0\x02\
+\xc8\xf1\x02\x01\x58\x04\xc8\xf1\x02\xd0\xf1\x02\x01\x53\x04\xd0\xf1\x02\xa0\
+\xf2\x02\x01\x58\x04\xa0\xf2\x02\xa8\xf2\x02\x01\x53\x04\xa8\xf2\x02\xf8\xf2\
+\x02\x01\x58\x04\xf8\xf2\x02\x80\xf3\x02\x01\x53\x04\x80\xf3\x02\xd0\xf3\x02\
+\x01\x58\x04\xd0\xf3\x02\xd8\xf3\x02\x01\x53\x04\xd8\xf3\x02\xa8\xf4\x02\x01\
+\x58\x04\xa8\xf4\x02\xb0\xf4\x02\x01\x53\x04\xb0\xf4\x02\x80\xf5\x02\x01\x58\
+\x04\x80\xf5\x02\x88\xf5\x02\x01\x53\x04\x88\xf5\x02\xd8\xf5\x02\x01\x58\x04\
+\xd8\xf5\x02\xe0\xf5\x02\x01\x53\x04\xe0\xf5\x02\xb0\xf6\x02\x01\x58\x04\xb0\
+\xf6\x02\xb8\xf6\x02\x01\x53\x04\xb8\xf6\x02\x88\xf7\x02\x01\x58\x04\x88\xf7\
+\x02\x90\xf7\x02\x01\x53\x04\x90\xf7\x02\xe0\xf7\x02\x01\x58\x04\xe0\xf7\x02\
+\xe8\xf7\x02\x01\x53\x04\xe8\xf7\x02\xb8\xf8\x02\x01\x58\x04\xb8\xf8\x02\xc0\
+\xf8\x02\x01\x53\x04\xc0\xf8\x02\x90\xf9\x02\x01\x58\x04\x90\xf9\x02\x98\xf9\
+\x02\x01\x53\x04\x98\xf9\x02\xe8\xf9\x02\x01\x58\x04\xe8\xf9\x02\xf0\xf9\x02\
+\x01\x52\x04\xf0\xf9\x02\xd0\xfa\x02\x01\x58\x04\xd0\xfa\x02\xd8\xfa\x02\x01\
+\x53\x04\xd8\xfa\x02\xa8\xfb\x02\x01\x58\x04\xa8\xfb\x02\xb0\xfb\x02\x01\x53\
+\x04\xb0\xfb\x02\x80\xfc\x02\x01\x58\x04\x80\xfc\x02\x88\xfc\x02\x01\x53\x04\
+\x88\xfc\x02\xd8\xfc\x02\x01\x58\x04\xd8\xfc\x02\xe0\xfc\x02\x01\x53\x04\xe0\
+\xfc\x02\xb0\xfd\x02\x01\x58\x04\xb0\xfd\x02\xb8\xfd\x02\x01\x53\x04\xb8\xfd\
+\x02\x88\xfe\x02\x01\x58\x04\x88\xfe\x02\x90\xfe\x02\x01\x53\x04\x90\xfe\x02\
+\xe0\xfe\x02\x01\x58\x04\xe0\xfe\x02\xe8\xfe\x02\x01\x53\x04\xe8\xfe\x02\xb8\
+\xff\x02\x01\x58\x04\xb8\xff\x02\xc0\xff\x02\x01\x53\x04\xc0\xff\x02\x90\x80\
+\x03\x01\x58\x04\x90\x80\x03\x98\x80\x03\x01\x53\x04\x98\x80\x03\xe8\x80\x03\
+\x01\x58\x04\xe8\x80\x03\xf0\x80\x03\x01\x53\x04\xf0\x80\x03\xc0\x81\x03\x01\
+\x58\x04\xc0\x81\x03\xc8\x81\x03\x01\x53\x04\xc8\x81\x03\x98\x82\x03\x01\x58\
+\x04\x98\x82\x03\xa0\x82\x03\x01\x53\x04\xa0\x82\x03\xf0\x82\x03\x01\x58\x04\
+\xf0\x82\x03\xf8\x82\x03\x01\x53\x04\xf8\x82\x03\xc8\x83\x03\x01\x58\x04\xc8\
+\x83\x03\xd0\x83\x03\x01\x53\x04\xd0\x83\x03\xa0\x84\x03\x01\x58\x04\xa0\x84\
+\x03\xa8\x84\x03\x01\x53\x04\xa8\x84\x03\xf8\x84\x03\x01\x58\x04\xf8\x84\x03\
+\x80\x85\x03\x01\x53\x04\x80\x85\x03\xd0\x85\x03\x01\x58\x04\xd0\x85\x03\xd8\
+\x85\x03\x01\x53\x04\xd8\x85\x03\xa8\x86\x03\x01\x58\x04\xa8\x86\x03\xb0\x86\
+\x03\x01\x53\x04\xb0\x86\x03\x80\x87\x03\x01\x58\x04\x80\x87\x03\x88\x87\x03\
+\x01\x53\x04\x88\x87\x03\xd8\x87\x03\x01\x58\x04\xd8\x87\x03\xe0\x87\x03\x01\
+\x53\x04\xe0\x87\x03\xb0\x88\x03\x01\x58\x04\xb0\x88\x03\xb8\x88\x03\x01\x53\
+\x04\xb8\x88\x03\x88\x89\x03\x01\x58\x04\x88\x89\x03\x90\x89\x03\x01\x53\x04\
+\x90\x89\x03\xe0\x89\x03\x01\x58\x04\xe0\x89\x03\xe8\x89\x03\x01\x53\x04\xe8\
+\x89\x03\xb8\x8a\x03\x01\x58\x04\xb8\x8a\x03\xc0\x8a\x03\x01\x53\x04\xc0\x8a\
+\x03\x90\x8b\x03\x01\x58\x04\x90\x8b\x03\x98\x8b\x03\x01\x53\x04\x98\x8b\x03\
+\xe8\x8b\x03\x01\x58\x04\xe8\x8b\x03\xf0\x8b\x03\x01\x53\x04\xf0\x8b\x03\xc0\
+\x8c\x03\x01\x58\x04\xc0\x8c\x03\xc8\x8c\x03\x01\x53\x04\xc8\x8c\x03\x98\x8d\
+\x03\x01\x58\x04\x98\x8d\x03\xa0\x8d\x03\x01\x53\x04\xa0\x8d\x03\xf0\x8d\x03\
+\x01\x58\x04\xf0\x8d\x03\xf8\x8d\x03\x01\x53\x04\xf8\x8d\x03\xc8\x8e\x03\x01\
+\x58\x04\xc8\x8e\x03\xd0\x8e\x03\x01\x53\x04\xd0\x8e\x03\x98\x8f\x03\x01\x58\
+\x04\x98\x8f\x03\xa0\x8f\x03\x01\x51\x04\xa0\x8f\x03\x80\x90\x03\x01\x58\x04\
+\x80\x90\x03\x88\x90\x03\x01\x51\x04\x88\x90\x03\xe0\x90\x03\x01\x58\x04\xe0\
+\x90\x03\xe8\x90\x03\x01\x51\x04\xe8\x90\x03\xb8\x91\x03\x01\x58\x04\xb8\x91\
+\x03\xc0\x91\x03\x01\x51\x04\xc0\x91\x03\x90\x92\x03\x01\x58\x04\x90\x92\x03\
+\x98\x92\x03\x01\x51\x04\x98\x92\x03\xe8\x92\x03\x01\x58\x04\xe8\x92\x03\xf0\
+\x92\x03\x01\x51\x04\xf0\x92\x03\xc0\x93\x03\x01\x58\x04\xc0\x93\x03\xc8\x93\
+\x03\x01\x51\x04\xc8\x93\x03\x98\x94\x03\x01\x58\x04\x98\x94\x03\xa0\x94\x03\
+\x01\x51\x04\xa0\x94\x03\xf0\x94\x03\x01\x58\x04\xf0\x94\x03\xf8\x94\x03\x01\
+\x51\x04\xf8\x94\x03\xc8\x95\x03\x01\x58\x04\xc8\x95\x03\xd0\x95\x03\x01\x51\
+\x04\xd0\x95\x03\xa0\x96\x03\x01\x58\x04\xa0\x96\x03\xa8\x96\x03\x01\x51\x04\
+\xa8\x96\x03\xf8\x96\x03\x01\x58\x04\xf8\x96\x03\x80\x97\x03\x01\x51\x04\x80\
+\x97\x03\xd0\x97\x03\x01\x58\x04\xd0\x97\x03\xd8\x97\x03\x01\x51\x04\xd8\x97\
+\x03\xa8\x98\x03\x01\x58\x04\xa8\x98\x03\xb0\x98\x03\x01\x51\x04\xb0\x98\x03\
+\x80\x99\x03\x01\x58\x04\x80\x99\x03\x88\x99\x03\x01\x51\x04\x88\x99\x03\xd8\
+\x99\x03\x01\x58\x04\xd8\x99\x03\xe0\x99\x03\x01\x51\x04\xe0\x99\x03\xb0\x9a\
+\x03\x01\x58\x04\xb0\x9a\x03\xb8\x9a\x03\x01\x51\x04\xb8\x9a\x03\x88\x9b\x03\
+\x01\x58\x04\x88\x9b\x03\x90\x9b\x03\x01\x51\x04\x90\x9b\x03\xe0\x9b\x03\x01\
+\x58\x04\xe0\x9b\x03\xe8\x9b\x03\x01\x51\x04\xe8\x9b\x03\xb8\x9c\x03\x01\x58\
+\x04\xb8\x9c\x03\xc0\x9c\x03\x01\x51\x04\xc0\x9c\x03\x90\x9d\x03\x01\x58\x04\
+\x90\x9d\x03\x98\x9d\x03\x01\x51\x04\x98\x9d\x03\xe8\x9d\x03\x01\x58\x04\xe8\
+\x9d\x03\xf0\x9d\x03\x01\x51\x04\xf0\x9d\x03\xc0\x9e\x03\x01\x58\x04\xc0\x9e\
+\x03\xc8\x9e\x03\x01\x51\x04\xc8\x9e\x03\x98\x9f\x03\x01\x58\x04\x98\x9f\x03\
+\xa0\x9f\x03\x01\x51\x04\xa0\x9f\x03\xf0\x9f\x03\x01\x58\x04\xf0\x9f\x03\xf8\
+\x9f\x03\x01\x51\x04\xf8\x9f\x03\xc8\xa0\x03\x01\x58\x04\xc8\xa0\x03\xd0\xa0\
+\x03\x01\x51\x04\xd0\xa0\x03\xa0\xa1\x03\x01\x58\x04\xa0\xa1\x03\xa8\xa1\x03\
+\x01\x51\x04\xa8\xa1\x03\xf8\xa1\x03\x01\x58\x04\xf8\xa1\x03\x80\xa2\x03\x01\
+\x51\x04\x80\xa2\x03\xd0\xa2\x03\x01\x58\x04\xd0\xa2\x03\xd8\xa2\x03\x01\x51\
+\x04\xd8\xa2\x03\xa8\xa3\x03\x01\x58\x04\xa8\xa3\x03\xb0\xa3\x03\x01\x51\x04\
+\xb0\xa3\x03\x80\xa4\x03\x01\x58\x04\x80\xa4\x03\x88\xa4\x03\x01\x51\x04\x88\
+\xa4\x03\xd0\xa4\x03\x01\x58\x04\xd0\xa4\x03\xd8\xa4\x03\x01\x51\x04\xd8\xa4\
+\x03\xb8\xa5\x03\x01\x58\x04\xb8\xa5\x03\xc0\xa5\x03\x01\x52\x04\xc0\xa5\x03\
+\x90\xa6\x03\x01\x58\x04\x90\xa6\x03\x98\xa6\x03\x01\x52\x04\x98\xa6\x03\xe8\
+\xa6\x03\x01\x58\x04\xe8\xa6\x03\xf0\xa6\x03\x01\x52\x04\xf0\xa6\x03\xc0\xa7\
+\x03\x01\x58\x04\xc0\xa7\x03\xc8\xa7\x03\x01\x52\x04\xc8\xa7\x03\x98\xa8\x03\
+\x01\x58\x04\x98\xa8\x03\xa0\xa8\x03\x01\x52\x04\xa0\xa8\x03\xf0\xa8\x03\x01\
+\x58\x04\xf0\xa8\x03\xf8\xa8\x03\x01\x52\x04\xf8\xa8\x03\xc8\xa9\x03\x01\x58\
+\x04\xc8\xa9\x03\xd0\xa9\x03\x01\x52\x04\xd0\xa9\x03\xa0\xaa\x03\x01\x58\x04\
+\xa0\xaa\x03\xa8\xaa\x03\x01\x52\x04\xa8\xaa\x03\xf8\xaa\x03\x01\x58\x04\xf8\
+\xaa\x03\x80\xab\x03\x01\x52\x04\x80\xab\x03\xd0\xab\x03\x01\x58\x04\xd0\xab\
+\x03\xd8\xab\x03\x01\x52\x04\xd8\xab\x03\xa8\xac\x03\x01\x58\x04\xa8\xac\x03\
+\xb0\xac\x03\x01\x52\x04\xb0\xac\x03\x80\xad\x03\x01\x58\x04\x80\xad\x03\x88\
+\xad\x03\x01\x52\x04\x88\xad\x03\xd8\xad\x03\x01\x58\x04\xd8\xad\x03\xe0\xad\
+\x03\x01\x52\x04\xe0\xad\x03\xb0\xae\x03\x01\x58\x04\xb0\xae\x03\xb8\xae\x03\
+\x01\x52\x04\xb8\xae\x03\x88\xaf\x03\x01\x58\x04\x88\xaf\x03\x90\xaf\x03\x01\
+\x52\x04\x90\xaf\x03\xe0\xaf\x03\x01\x58\x04\xe0\xaf\x03\xe8\xaf\x03\x01\x52\
+\x04\xe8\xaf\x03\xb8\xb0\x03\x01\x58\x04\xb8\xb0\x03\xc0\xb0\x03\x01\x52\x04\
+\xc0\xb0\x03\x90\xb1\x03\x01\x58\x04\x90\xb1\x03\x98\xb1\x03\x01\x52\x04\x98\
+\xb1\x03\xe8\xb1\x03\x01\x58\x04\xe8\xb1\x03\xf0\xb1\x03\x01\x52\x04\xf0\xb1\
+\x03\xc0\xb2\x03\x01\x58\x04\xc0\xb2\x03\xc8\xb2\x03\x01\x52\x04\xc8\xb2\x03\
+\x98\xb3\x03\x01\x58\x04\x98\xb3\x03\xa0\xb3\x03\x01\x52\x04\xa0\xb3\x03\xf0\
+\xb3\x03\x01\x58\x04\xf0\xb3\x03\xf8\xb3\x03\x01\x52\x04\xf8\xb3\x03\xc8\xb4\
+\x03\x01\x58\x04\xc8\xb4\x03\xd0\xb4\x03\x01\x52\x04\xd0\xb4\x03\xa0\xb5\x03\
+\x01\x58\x04\xa0\xb5\x03\xa8\xb5\x03\x01\x52\x04\xa8\xb5\x03\xf8\xb5\x03\x01\
+\x58\x04\xf8\xb5\x03\x80\xb6\x03\x01\x52\x04\x80\xb6\x03\xd0\xb6\x03\x01\x58\
+\x04\xd0\xb6\x03\xd8\xb6\x03\x01\x52\x04\xd8\xb6\x03\xa8\xb7\x03\x01\x58\x04\
+\xa8\xb7\x03\xb0\xb7\x03\x01\x52\x04\xb0\xb7\x03\x80\xb8\x03\x01\x58\x04\x80\
+\xb8\x03\x88\xb8\x03\x01\x52\x04\x88\xb8\x03\xd8\xb8\x03\x01\x58\x04\xd8\xb8\
+\x03\xe0\xb8\x03\x01\x52\x04\xe0\xb8\x03\xb0\xb9\x03\x01\x58\x04\xb0\xb9\x03\
+\xb8\xb9\x03\x01\x52\x04\xb8\xb9\x03\x80\xba\x03\x01\x58\x04\x80\xba\x03\x88\
+\xba\x03\x01\x52\x04\x88\xba\x03\xe8\xba\x03\x01\x58\x04\xe8\xba\x03\xf0\xba\
+\x03\x01\x53\x04\xf0\xba\x03\xc0\xbb\x03\x01\x58\x04\xc0\xbb\x03\xc8\xbb\x03\
+\x01\x53\x04\xc8\xbb\x03\x98\xbc\x03\x01\x58\x04\x98\xbc\x03\xa0\xbc\x03\x01\
+\x53\x04\xa0\xbc\x03\xf0\xbc\x03\x01\x58\x04\xf0\xbc\x03\xf8\xbc\x03\x01\x53\
+\x04\xf8\xbc\x03\xc8\xbd\x03\x01\x58\x04\xc8\xbd\x03\xd0\xbd\x03\x01\x53\x04\
+\xd0\xbd\x03\xa0\xbe\x03\x01\x58\x04\xa0\xbe\x03\xa8\xbe\x03\x01\x53\x04\xa8\
+\xbe\x03\xf8\xbe\x03\x01\x58\x04\xf8\xbe\x03\x80\xbf\x03\x01\x53\x04\x80\xbf\
+\x03\xd0\xbf\x03\x01\x58\x04\xd0\xbf\x03\xd8\xbf\x03\x01\x53\x04\xd8\xbf\x03\
+\xa8\xc0\x03\x01\x58\x04\xa8\xc0\x03\xb0\xc0\x03\x01\x53\x04\xb0\xc0\x03\x80\
+\xc1\x03\x01\x58\x04\x80\xc1\x03\x88\xc1\x03\x01\x53\x04\x88\xc1\x03\xd8\xc1\
+\x03\x01\x58\x04\xd8\xc1\x03\xe0\xc1\x03\x01\x53\x04\xe0\xc1\x03\xb0\xc2\x03\
+\x01\x58\x04\xb0\xc2\x03\xb8\xc2\x03\x01\x53\x04\xb8\xc2\x03\x88\xc3\x03\x01\
+\x58\x04\x88\xc3\x03\x90\xc3\x03\x01\x53\x04\x90\xc3\x03\xe0\xc3\x03\x01\x58\
+\x04\xe0\xc3\x03\xe8\xc3\x03\x01\x53\x04\xe8\xc3\x03\xb8\xc4\x03\x01\x58\x04\
+\xb8\xc4\x03\xc0\xc4\x03\x01\x53\x04\xc0\xc4\x03\x90\xc5\x03\x01\x58\x04\x90\
+\xc5\x03\x98\xc5\x03\x01\x53\x04\x98\xc5\x03\xe8\xc5\x03\x01\x58\x04\xe8\xc5\
+\x03\xf0\xc5\x03\x01\x53\x04\xf0\xc5\x03\xc0\xc6\x03\x01\x58\x04\xc0\xc6\x03\
+\xc8\xc6\x03\x01\x53\x04\xc8\xc6\x03\x98\xc7\x03\x01\x58\x04\x98\xc7\x03\xa0\
+\xc7\x03\x01\x53\x04\xa0\xc7\x03\xf0\xc7\x03\x01\x58\x04\xf0\xc7\x03\xf8\xc7\
+\x03\x01\x53\x04\xf8\xc7\x03\xc8\xc8\x03\x01\x58\x04\xc8\xc8\x03\xd0\xc8\x03\
+\x01\x53\x04\xd0\xc8\x03\xa0\xc9\x03\x01\x58\x04\xa0\xc9\x03\xa8\xc9\x03\x01\
+\x53\x04\xa8\xc9\x03\xf8\xc9\x03\x01\x58\x04\xf8\xc9\x03\x80\xca\x03\x01\x53\
+\x04\x80\xca\x03\xd0\xca\x03\x01\x58\x04\xd0\xca\x03\xd8\xca\x03\x01\x53\x04\
+\xd8\xca\x03\xa8\xcb\x03\x01\x58\x04\xa8\xcb\x03\xb0\xcb\x03\x01\x53\x04\xb0\
+\xcb\x03\x80\xcc\x03\x01\x58\x04\x80\xcc\x03\x88\xcc\x03\x01\x53\x04\x88\xcc\
+\x03\xd8\xcc\x03\x01\x58\x04\xd8\xcc\x03\xe0\xcc\x03\x01\x53\x04\xe0\xcc\x03\
+\xb8\xcd\x03\x01\x58\x04\xb8\xcd\x03\xc0\xcd\x03\x01\x54\x04\xc0\xcd\x03\xa0\
+\xce\x03\x01\x58\x04\xa0\xce\x03\xa8\xce\x03\x01\x55\x04\xa8\xce\x03\x80\xcf\
+\x03\x01\x58\x04\x80\xcf\x03\x88\xcf\x03\x01\x54\x04\x88\xcf\x03\xd8\xcf\x03\
+\x01\x58\x04\xd8\xcf\x03\xe0\xcf\x03\x01\x51\x04\xe0\xcf\x03\xb8\xd0\x03\x01\
+\x58\x04\xb8\xd0\x03\xc0\xd0\x03\x01\x51\x04\xc0\xd0\x03\x90\xd1\x03\x01\x58\
+\x04\x90\xd1\x03\x98\xd1\x03\x01\x51\x04\x98\xd1\x03\xe8\xd1\x03\x01\x58\x04\
+\xe8\xd1\x03\xf0\xd1\x03\x01\x51\x04\xf0\xd1\x03\xc0\xd2\x03\x01\x58\x04\xc0\
+\xd2\x03\xc8\xd2\x03\x01\x51\x04\xc8\xd2\x03\x98\xd3\x03\x01\x58\x04\x98\xd3\
+\x03\xa0\xd3\x03\x01\x51\x04\xa0\xd3\x03\xf0\xd3\x03\x01\x58\x04\xf0\xd3\x03\
+\xf8\xd3\x03\x01\x51\x04\xf8\xd3\x03\xc8\xd4\x03\x01\x58\x04\xc8\xd4\x03\xd0\
+\xd4\x03\x01\x51\x04\xd0\xd4\x03\xa0\xd5\x03\x01\x58\x04\xa0\xd5\x03\xa8\xd5\
+\x03\x01\x51\x04\xa8\xd5\x03\xf8\xd5\x03\x01\x58\x04\xf8\xd5\x03\x80\xd6\x03\
+\x01\x51\x04\x80\xd6\x03\xd0\xd6\x03\x01\x58\x04\xd0\xd6\x03\xd8\xd6\x03\x01\
+\x51\x04\xd8\xd6\x03\xa8\xd7\x03\x01\x58\x04\xa8\xd7\x03\xb0\xd7\x03\x01\x51\
+\x04\xb0\xd7\x03\x80\xd8\x03\x01\x58\x04\x80\xd8\x03\x88\xd8\x03\x01\x51\x04\
+\x88\xd8\x03\xd8\xd8\x03\x01\x58\x04\xd8\xd8\x03\xe0\xd8\x03\x01\x51\x04\xe0\
+\xd8\x03\xb0\xd9\x03\x01\x58\x04\xb0\xd9\x03\xb8\xd9\x03\x01\x51\x04\xb8\xd9\
+\x03\x88\xda\x03\x01\x58\x04\x88\xda\x03\x90\xda\x03\x01\x51\x04\x90\xda\x03\
+\xe0\xda\x03\x01\x58\x04\xe0\xda\x03\xe8\xda\x03\x01\x51\x04\xe8\xda\x03\xb8\
+\xdb\x03\x01\x58\x04\xb8\xdb\x03\xc0\xdb\x03\x01\x51\x04\xc0\xdb\x03\x90\xdc\
+\x03\x01\x58\x04\x90\xdc\x03\x98\xdc\x03\x01\x51\x04\x98\xdc\x03\xe8\xdc\x03\
+\x01\x58\x04\xe8\xdc\x03\xf0\xdc\x03\x01\x51\x04\xf0\xdc\x03\xc0\xdd\x03\x01\
+\x58\x04\xc0\xdd\x03\xc8\xdd\x03\x01\x51\x04\xc8\xdd\x03\x98\xde\x03\x01\x58\
+\x04\x98\xde\x03\xa0\xde\x03\x01\x51\x04\xa0\xde\x03\xf0\xde\x03\x01\x58\x04\
+\xf0\xde\x03\xf8\xde\x03\x01\x51\x04\xf8\xde\x03\xc8\xdf\x03\x01\x58\x04\xc8\
+\xdf\x03\xd0\xdf\x03\x01\x51\x04\xd0\xdf\x03\xa0\xe0\x03\x01\x58\x04\xa0\xe0\
+\x03\xa8\xe0\x03\x01\x51\x04\xa8\xe0\x03\xf8\xe0\x03\x01\x58\x04\xf8\xe0\x03\
+\x80\xe1\x03\x01\x51\x04\x80\xe1\x03\xd0\xe1\x03\x01\x58\x04\xd0\xe1\x03\xd8\
+\xe1\x03\x01\x51\x04\xd8\xe1\x03\xa8\xe2\x03\x01\x58\x04\xa8\xe2\x03\xb0\xe2\
+\x03\x01\x51\x04\xb0\xe2\x03\x80\xe3\x03\x01\x58\x04\x80\xe3\x03\x88\xe3\x03\
+\x01\x51\x04\x88\xe3\x03\xd8\xe3\x03\x01\x58\x04\xd8\xe3\x03\xe0\xe3\x03\x01\
+\x51\x04\xe0\xe3\x03\xb0\xe4\x03\x01\x58\x04\xb0\xe4\x03\xb8\xe4\x03\x01\x51\
+\x04\xb8\xe4\x03\xc0\xe4\x03\x01\x58\x04\xc0\xe4\x03\xf8\xe4\x03\x03\x7a\xc0\0\
+\0\x01\x11\x01\x25\x25\x13\x05\x03\x25\x72\x17\x10\x17\x1b\x25\x11\x1b\x12\x06\
+\x73\x17\x74\x17\x8c\x01\x17\0\0\x02\x24\0\x03\x25\x3e\x0b\x0b\x0b\0\0\x03\x2e\
+\x01\x11\x1b\x12\x06\x40\x18\x7a\x19\x03\x25\x3a\x0b\x3b\x0b\x27\x19\x49\x13\
+\x3f\x19\0\0\x04\x34\0\x03\x25\x49\x13\x3a\x0b\x3b\x0b\x02\x18\0\0\x05\x34\0\
+\x03\x25\x49\x13\x3a\x0b\x3b\x05\x02\x18\0\0\x06\x05\0\x02\x22\x03\x25\x3a\x0b\
+\x3b\x0b\x49\x13\0\0\x07\x34\0\x02\x18\x03\x25\x3a\x0b\x3b\x0b\x49\x13\0\0\x08\
+\x34\0\x02\x22\x03\x25\x3a\x0b\x3b\x0b\x49\x13\0\0\x09\x1d\x01\x31\x13\x55\x23\
+\x58\x0b\x59\x05\x57\x0b\0\0\x0a\x05\0\x02\x22\x31\x13\0\0\x0b\x34\0\x02\x22\
+\x31\x13\0\0\x0c\x1d\x01\x31\x13\x55\x23\x58\x0b\x59\x0b\x57\x0b\0\0\x0d\x34\0\
+\x02\x18\x31\x13\0\0\x0e\x1d\x01\x31\x13\x11\x1b\x12\x06\x58\x0b\x59\x0b\x57\
+\x0b\0\0\x0f\x05\0\x02\x18\x31\x13\0\0\x10\x0b\x01\x55\x23\0\0\x11\x05\0\x1c\
+\x0f\x31\x13\0\0\x12\x0b\x01\x11\x1b\x12\x06\0\0\x13\x1d\x01\x31\x13\x11\x1b\
+\x12\x06\x58\x0b\x59\x05\x57\x0b\0\0\x14\x01\x01\x49\x13\0\0\x15\x21\0\x49\x13\
+\x37\x0b\0\0\x16\x26\0\x49\x13\0\0\x17\x24\0\x03\x25\x0b\x0b\x3e\x0b\0\0\x18\
+\x34\0\x03\x25\x49\x13\x3f\x19\x3a\x0b\x3b\x05\x02\x18\0\0\x19\x34\0\x03\x25\
+\x49\x13\x3f\x19\x3a\x0b\x3b\x0b\x02\x18\0\0\x1a\x13\x01\x0b\x0b\x3a\x0b\x3b\
+\x0b\0\0\x1b\x0d\0\x03\x25\x49\x13\x3a\x0b\x3b\x0b\x38\x0b\0\0\x1c\x0f\0\x49\
+\x13\0\0\x1d\x34\0\x03\x25\x49\x13\x3a\x0b\x3b\x0b\0\0\x1e\x15\x01\x49\x13\x27\
+\x19\0\0\x1f\x05\0\x49\x13\0\0\x20\x18\0\0\0\x21\x16\0\x49\x13\x03\x25\x3a\x0b\
+\x3b\x0b\0\0\x22\x0f\0\0\0\x23\x26\0\0\0\x24\x34\0\x03\x25\x49\x13\x3a\x0b\x3b\
+\x05\0\0\x25\x04\x01\x49\x13\x03\x25\x0b\x0b\x3a\x0b\x3b\x05\0\0\x26\x28\0\x03\
+\x25\x1c\x0f\0\0\x27\x04\x01\x49\x13\x03\x25\x0b\x0b\x3a\x0b\x3b\x0b\0\0\x28\
+\x04\x01\x49\x13\x0b\x0b\x3a\x0b\x3b\x0b\0\0\x29\x13\x01\x03\x25\x0b\x0b\x3a\
+\x0b\x3b\x0b\0\0\x2a\x0d\0\x49\x13\x3a\x0b\x3b\x0b\x38\x0b\0\0\x2b\x2e\x01\x03\
+\x25\x3a\x0b\x3b\x0b\x27\x19\x49\x13\x20\x21\x01\0\0\x2c\x05\0\x03\x25\x3a\x0b\
+\x3b\x0b\x49\x13\0\0\x2d\x34\0\x03\x25\x3a\x0b\x3b\x0b\x49\x13\0\0\x2e\x13\x01\
+\x03\x25\x0b\x0b\x3a\x0b\x3b\x05\0\0\x2f\x0d\0\x03\x25\x49\x13\x3a\x0b\x3b\x05\
+\x38\x0b\0\0\x30\x0d\0\x49\x13\x3a\x0b\x3b\x05\x88\x01\x0f\x38\x0b\0\0\x31\x17\
+\x01\x0b\x0b\x3a\x0b\x3b\x05\x88\x01\x0f\0\0\x32\x0d\0\x49\x13\x3a\x0b\x3b\x05\
+\x38\x0b\0\0\x33\x17\x01\x0b\x0b\x3a\x0b\x3b\x05\0\0\x34\x13\x01\x0b\x0b\x3a\
+\x0b\x3b\x05\0\0\x35\x0b\x01\0\0\x36\x0d\0\x03\x25\x49\x13\x3a\x0b\x3b\x0b\x0d\
+\x0b\x6b\x0b\0\0\x37\x17\x01\x0b\x0b\x3a\x0b\x3b\x0b\0\0\x38\x2e\x01\0\0\0\x7a\
+\x0b\0\0\x05\0\x01\x08\0\0\0\0\x01\0\x1d\0\x01\x08\0\0\0\0\0\0\0\x02\x05\xc8\
+\xf6\0\0\x08\0\0\0\x0c\0\0\0\x0c\0\0\0\x02\xbe\x07\x01\x02\xbd\x07\x02\x02\xbc\
+\x07\x04\x03\x05\xc8\xf6\0\0\x01\x5a\xbf\0\xf0\xaf\x02\0\0\x04\x03\x21\x02\0\0\
+\0\xfe\x02\xa1\0\x05\x03\x3a\x02\0\0\0\x03\x01\x02\xa1\x01\x05\x03\x46\x02\0\0\
+\0\x07\x01\x02\xa1\x02\x06\0\x43\0\xf0\x78\x0b\0\0\x07\x03\x91\xe0\0\xc0\0\xf3\
+\x6c\x0b\0\0\x08\x01\xc1\0\xf4\x39\x04\0\0\x08\x02\x84\0\xf2\xc1\x07\0\0\x08\
+\x06\x51\0\xf5\x0d\x03\0\0\x09\x70\x04\0\0\0\0\x02\x01\x09\x0a\x04\x78\x04\0\0\
+\x0a\x03\x80\x04\0\0\x0b\x05\x88\x04\0\0\x0c\x0d\x08\0\0\x01\0\xce\x0a\x0a\x09\
+\x15\x08\0\0\x0a\x08\x25\x08\0\0\x0d\x03\x91\x88\x01\x2d\x08\0\0\x0b\x07\x35\
+\x08\0\0\x0b\x0a\x3d\x08\0\0\x0e\x34\x09\0\0\x06\x18\x16\0\0\0\x56\x0a\x0b\x0b\
+\x54\x09\0\0\x0b\x0c\x5c\x09\0\0\x0b\x0d\x64\x09\0\0\0\x0e\xdc\x0a\0\0\x07\x10\
+\0\0\0\0\x59\x06\x0f\x04\x91\x88\x01\x9f\xe4\x0a\0\0\0\x10\x02\x0d\x03\x91\x80\
+\x01\x46\x08\0\0\x0c\x34\x09\0\0\x03\0\x66\x0a\x11\x03\x44\x09\0\0\x0a\x19\x4c\
+\x09\0\0\x0b\x16\x54\x09\0\0\x0b\x17\x5c\x09\0\0\x0b\x18\x64\x09\0\0\0\0\0\x0c\
+\x6d\x09\0\0\x04\0\xd0\x0a\x0a\x11\x75\x09\0\0\x0a\x10\x85\x09\0\0\x0d\x03\x91\
+\x88\x01\x8d\x09\0\0\x0b\x0e\x95\x09\0\0\x0b\x0f\x9d\x09\0\0\x0b\x12\xa5\x09\0\
+\0\x0b\x1d\xad\x09\0\0\x0b\x1e\xb5\x09\0\0\x0e\x34\x09\0\0\x08\x80\x55\0\0\0\
+\xad\x0a\x0b\x13\x54\x09\0\0\x0b\x14\x5c\x09\0\0\x0b\x15\x64\x09\0\0\0\x0c\xfb\
+\x0a\0\0\x05\0\xb0\x0a\x0a\x1a\x03\x0b\0\0\x0a\x1c\x0b\x0b\0\0\x0d\x03\x91\x80\
+\x01\x23\x0b\0\0\x0b\x1b\x2b\x0b\0\0\0\x12\x09\x28\0\0\0\x0d\x03\x91\x80\x01\
+\xbe\x09\0\0\0\x0c\x34\x09\0\0\x06\0\xc1\x09\x11\x09\x44\x09\0\0\x0f\x03\x91\
+\xc8\0\x4c\x09\0\0\x0b\x1f\x54\x09\0\0\x0b\x20\x5c\x09\0\0\x0b\x21\x64\x09\0\0\
+\0\0\0\x13\x53\x0b\0\0\x0a\x10\0\0\0\0\x06\x01\x18\x0f\x01\x56\x5b\x0b\0\0\0\0\
+\x14\x2d\x02\0\0\x15\x36\x02\0\0\x1b\0\x16\x32\x02\0\0\x02\x04\x06\x01\x17\x05\
+\x08\x07\x14\x2d\x02\0\0\x15\x36\x02\0\0\x09\0\x14\x2d\x02\0\0\x15\x36\x02\0\0\
+\x0a\0\x18\x06\x5e\x02\0\0\0\x0d\x01\x02\xa1\x03\x14\x32\x02\0\0\x15\x36\x02\0\
+\0\x0d\0\x19\x07\x75\x02\0\0\0\x1e\x02\xa1\x04\x1a\x20\0\x19\x1b\x08\x9e\x02\0\
+\0\0\x1a\0\x1b\x0a\xb3\x02\0\0\0\x1b\x08\x1b\x0b\xc4\x02\0\0\0\x1c\x10\x1b\x0c\
+\xd5\x02\0\0\0\x1d\x18\0\x1c\xa3\x02\0\0\x14\xaf\x02\0\0\x15\x36\x02\0\0\x01\0\
+\x02\x09\x05\x04\x1c\xb8\x02\0\0\x14\xaf\x02\0\0\x15\x36\x02\0\0\x02\0\x1c\xc9\
+\x02\0\0\x14\xaf\x02\0\0\x15\x36\x02\0\0\x70\0\x1c\xda\x02\0\0\x14\xaf\x02\0\0\
+\x15\x36\x02\0\0\x10\0\x1d\x0d\xee\x02\0\0\x02\xb1\x1c\xf3\x02\0\0\x1e\x04\x03\
+\0\0\x1f\x08\x03\0\0\x1f\x0d\x03\0\0\x20\0\x02\x0e\x05\x08\x1c\x2d\x02\0\0\x21\
+\x15\x03\0\0\x10\x01\x1b\x02\x0f\x07\x04\x1d\x11\x21\x03\0\0\x02\x38\x1c\x26\
+\x03\0\0\x1e\x36\x03\0\0\x1f\x36\x03\0\0\x1f\x37\x03\0\0\0\x22\x1c\x3c\x03\0\0\
+\x23\x24\x12\x46\x03\0\0\x02\x17\x07\x1c\x4b\x03\0\0\x1e\x04\x03\0\0\x1f\x37\
+\x03\0\0\x1f\x0d\x03\0\0\x1f\x36\x03\0\0\x1f\x0d\x03\0\0\x1f\x0d\x03\0\0\0\x25\
+\x15\x03\0\0\x15\x04\x03\x4e\x17\x26\x13\0\x26\x14\x01\0\x27\x15\x03\0\0\x1a\
+\x04\x04\x16\x26\x16\0\x26\x17\x01\x26\x18\x02\x26\x19\x03\0\x28\x15\x03\0\0\
+\x04\x05\x1d\x26\x1b\0\x26\x1c\x01\x26\x1d\x02\x26\x1e\x04\x26\x1f\x06\x26\x20\
+\x08\x26\x21\x0c\x26\x22\x11\x26\x23\x16\x26\x24\x1d\x26\x25\x21\x26\x26\x29\
+\x26\x27\x2e\x26\x28\x2f\x26\x29\x32\x26\x2a\x33\x26\x2b\x5c\x26\x2c\x5e\x26\
+\x2d\x62\x26\x2e\x67\x26\x2f\x6c\x26\x30\x73\x26\x31\x84\x01\x26\x32\x88\x01\
+\x26\x33\x89\x01\x26\x34\x8f\x01\x26\x35\xff\x01\x26\x36\x86\x02\x26\x37\x87\
+\x02\0\x1c\xfd\x03\0\0\x16\x02\x04\0\0\x29\x3f\x1c\0\xdd\x2a\x0f\x04\0\0\0\xde\
+\0\x1a\x08\0\xde\x1b\x38\x15\x03\0\0\0\xdf\0\x1b\x39\x39\x04\0\0\0\xe0\x04\x1b\
+\x3c\x39\x04\0\0\0\xe1\x06\0\x1b\x3d\x45\x04\0\0\0\xe4\x08\0\x21\x41\x04\0\0\
+\x3b\x01\x18\x02\x3a\x07\x02\x14\x51\x04\0\0\x15\x36\x02\0\0\x14\0\x02\x3e\x08\
+\x01\x1c\x5a\x04\0\0\x16\x0d\x03\0\0\x1c\x0d\x03\0\0\x21\x6c\x04\0\0\x41\x01\
+\x1f\x02\x40\x07\x08\x2b\x42\0\xc9\x0d\x03\0\0\x2c\x43\0\xc9\x91\x04\0\0\x2c\
+\x84\0\xc9\xc1\x07\0\0\x2d\x86\0\xcb\x55\x04\0\0\0\x1c\x96\x04\0\0\x16\x9b\x04\
+\0\0\x2e\x83\xc0\x03\x77\x17\x2f\x44\x0d\x03\0\0\x03\x78\x17\0\x2f\x45\x0d\x03\
+\0\0\x03\x79\x17\x04\x2f\x46\x0d\x03\0\0\x03\x7a\x17\x08\x2f\x47\x0d\x03\0\0\
+\x03\x7b\x17\x0c\x2f\x48\x0d\x03\0\0\x03\x7c\x17\x10\x2f\x49\x0d\x03\0\0\x03\
+\x7d\x17\x14\x2f\x4a\x0d\x03\0\0\x03\x7e\x17\x18\x2f\x4b\x0d\x03\0\0\x03\x7f\
+\x17\x1c\x2f\x4c\x0d\x03\0\0\x03\x80\x17\x20\x2f\x4d\x0d\x03\0\0\x03\x81\x17\
+\x24\x2f\x4e\x0d\x03\0\0\x03\x82\x17\x28\x2f\x4f\x0d\x03\0\0\x03\x83\x17\x2c\
+\x2f\x50\x18\x06\0\0\x03\x84\x17\x30\x2f\x51\x0d\x03\0\0\x03\x85\x17\x44\x2f\
+\x3c\x0d\x03\0\0\x03\x86\x17\x48\x2f\x3d\x0d\x03\0\0\x03\x87\x17\x4c\x2f\x52\
+\x0d\x03\0\0\x03\x88\x17\x50\x2f\x53\x0d\x03\0\0\x03\x89\x17\x54\x2f\x54\x0d\
+\x03\0\0\x03\x8c\x17\x58\x2f\x55\x0d\x03\0\0\x03\x8d\x17\x5c\x2f\x56\x0d\x03\0\
+\0\x03\x8e\x17\x60\x2f\x57\x24\x06\0\0\x03\x8f\x17\x64\x2f\x58\x24\x06\0\0\x03\
+\x90\x17\x74\x2f\x59\x0d\x03\0\0\x03\x91\x17\x84\x2f\x5a\x0d\x03\0\0\x03\x92\
+\x17\x88\x2f\x5b\x0d\x03\0\0\x03\x95\x17\x8c\x30\xaf\x05\0\0\x03\x96\x17\x08\
+\x90\x31\x08\x03\x96\x17\x08\x2f\x5c\x30\x06\0\0\x03\x96\x17\0\0\x2f\x71\x64\
+\x04\0\0\x03\x97\x17\x98\x2f\x72\x0d\x03\0\0\x03\x98\x17\xa0\x2f\x73\x0d\x03\0\
+\0\x03\x99\x17\xa4\x30\xe8\x05\0\0\x03\x9a\x17\x08\xa8\x31\x08\x03\x9a\x17\x08\
+\x2f\x74\x21\x07\0\0\x03\x9a\x17\0\0\x2f\x80\x0d\x03\0\0\x03\x9b\x17\xb0\x2f\
+\x81\x09\x07\0\0\x03\x9c\x17\xb4\x2f\x82\x64\x04\0\0\x03\x9e\x17\xb8\0\x14\x0d\
+\x03\0\0\x15\x36\x02\0\0\x05\0\x14\x0d\x03\0\0\x15\x36\x02\0\0\x04\0\x1c\x35\
+\x06\0\0\x2e\x70\x38\x03\x2b\x1b\x2f\x5d\x39\x04\0\0\x03\x2c\x1b\0\x2f\x5e\x39\
+\x04\0\0\x03\x2d\x1b\x02\x2f\x5f\x39\x04\0\0\x03\x2e\x1b\x04\x2f\x60\x09\x07\0\
+\0\x03\x2f\x1b\x06\x2f\x62\x09\x07\0\0\x03\x30\x1b\x07\x2f\x63\x09\x07\0\0\x03\
+\x31\x1b\x08\x2f\x64\x09\x07\0\0\x03\x32\x1b\x09\x2f\x65\x11\x07\0\0\x03\x33\
+\x1b\x0a\x2f\x67\x11\x07\0\0\x03\x34\x1b\x0c\x2f\x68\x11\x07\0\0\x03\x35\x1b\
+\x0e\x32\xa8\x06\0\0\x03\x36\x1b\x10\x33\x20\x03\x36\x1b\x32\xb6\x06\0\0\x03\
+\x37\x1b\0\x34\x08\x03\x37\x1b\x2f\x69\x19\x07\0\0\x03\x38\x1b\0\x2f\x6b\x19\
+\x07\0\0\x03\x39\x1b\x04\0\x32\xd9\x06\0\0\x03\x3b\x1b\0\x34\x20\x03\x3b\x1b\
+\x2f\x6c\x24\x06\0\0\x03\x3c\x1b\0\x2f\x6d\x24\x06\0\0\x03\x3d\x1b\x10\0\0\x2f\
+\x6e\x0d\x03\0\0\x03\x40\x1b\x30\x2f\x6f\x19\x07\0\0\x03\x41\x1b\x34\0\x21\x51\
+\x04\0\0\x61\x01\x15\x21\x39\x04\0\0\x66\x06\x20\x21\x0d\x03\0\0\x6a\x06\x22\
+\x1c\x26\x07\0\0\x2e\x7f\x50\x03\xdf\x17\x2f\x75\x0d\x03\0\0\x03\xe0\x17\0\x2f\
+\x54\x0d\x03\0\0\x03\xe1\x17\x04\x2f\x08\x0d\x03\0\0\x03\xe2\x17\x08\x2f\x48\
+\x0d\x03\0\0\x03\xe3\x17\x0c\x2f\x46\x0d\x03\0\0\x03\xe4\x17\x10\x2f\x4c\x0d\
+\x03\0\0\x03\xe5\x17\x14\x2f\x76\x0d\x03\0\0\x03\xe7\x17\x18\x2f\x77\x24\x06\0\
+\0\x03\xe8\x17\x1c\x2f\x78\x0d\x03\0\0\x03\xe9\x17\x2c\x2f\x79\x11\x07\0\0\x03\
+\xea\x17\x30\x2f\x7a\x0d\x03\0\0\x03\xec\x17\x34\x2f\x7b\x24\x06\0\0\x03\xed\
+\x17\x38\x2f\x7c\x0d\x03\0\0\x03\xee\x17\x48\x2f\x7d\xb9\x07\0\0\x03\xef\x17\
+\x4c\0\x21\xaf\x02\0\0\x7e\x01\x1a\x1c\xc6\x07\0\0\x16\xcb\x07\0\0\x29\x89\x70\
+\x04\x1d\x1b\x85\x0d\x03\0\0\x04\x1e\0\x1b\x86\xf5\x07\0\0\x04\x1f\x04\x1b\x87\
+\x0d\x03\0\0\x04\x20\x2c\x1b\x88\x01\x08\0\0\x04\x21\x30\0\x14\x09\x07\0\0\x15\
+\x36\x02\0\0\x28\0\x14\x0d\x03\0\0\x15\x36\x02\0\0\x10\0\x2b\x8a\0\x42\x0d\x03\
+\0\0\x2c\x43\0\x42\x91\x04\0\0\x2c\x8b\0\x42\x0d\x03\0\0\x2c\x86\0\x42\x55\x04\
+\0\0\x2d\x8c\0\x44\x50\x08\0\0\x2d\x9a\0\x45\x0d\x03\0\0\x2d\x9b\0\x4f\xfe\x08\
+\0\0\x35\x2d\x9e\0\x5d\x28\x09\0\0\0\0\x29\x99\x14\x07\x57\x36\x8d\x09\x07\0\0\
+\x07\x59\x04\0\x36\x8e\x09\x07\0\0\x07\x5a\x04\x04\x1b\x8f\x09\x07\0\0\x07\x61\
+\x01\x1b\x90\x11\x07\0\0\x07\x62\x02\x1b\x91\x11\x07\0\0\x07\x63\x04\x1b\x92\
+\x11\x07\0\0\x07\x64\x06\x1b\x93\x09\x07\0\0\x07\x65\x08\x1b\x48\x09\x07\0\0\
+\x07\x66\x09\x1b\x94\xf5\x08\0\0\x07\x67\x0a\x2a\xb0\x08\0\0\x07\x68\x0c\x37\
+\x08\x07\x68\x2a\xbc\x08\0\0\x07\x68\0\x1a\x08\x07\x68\x1b\x96\x19\x07\0\0\x07\
+\x68\0\x1b\x97\x19\x07\0\0\x07\x68\x04\0\x1b\x98\xdc\x08\0\0\x07\x68\0\x1a\x08\
+\x07\x68\x1b\x96\x19\x07\0\0\x07\x68\0\x1b\x97\x19\x07\0\0\x07\x68\x04\0\0\0\
+\x21\x39\x04\0\0\x95\x06\x26\x38\x1a\x0c\0\x4a\x1b\x9c\x0d\x03\0\0\0\x4b\0\x1b\
+\x9d\x0d\x03\0\0\0\x4c\x04\x1b\x68\x39\x04\0\0\0\x4d\x08\x1b\x67\x39\x04\0\0\0\
+\x4e\x0a\0\0\x14\x39\x04\0\0\x15\x36\x02\0\0\x02\0\x2b\x9f\0\x26\x0d\x03\0\0\
+\x2c\xa0\0\x26\x55\x04\0\0\x2c\xa1\0\x26\x0d\x03\0\0\x2c\x86\0\x26\x55\x04\0\0\
+\x2d\xa2\0\x28\x0d\x03\0\0\x2d\xa3\0\x28\x0d\x03\0\0\x2d\x51\0\x28\x0d\x03\0\0\
+\0\x2b\xa4\0\x97\x0d\x03\0\0\x2c\x43\0\x97\x91\x04\0\0\x2c\x8b\0\x97\x0d\x03\0\
+\0\x2c\x86\0\x97\x55\x04\0\0\x2d\xa5\0\x9f\xc8\x09\0\0\x2d\x9a\0\xa0\x0d\x03\0\
+\0\x2d\xb0\0\x9e\xb2\x0a\0\0\x2d\xa3\0\xa0\x0d\x03\0\0\x2d\xb1\0\xa1\xaf\x02\0\
+\0\x2d\xb2\0\xa1\xaf\x02\0\0\x35\x2d\x9e\0\xb7\x28\x09\0\0\0\0\x29\xaf\x28\x08\
+\x76\x36\x4c\x09\x07\0\0\x08\x78\x04\0\x36\x8e\x09\x07\0\0\x08\x79\x04\x04\x1b\
+\xa6\x52\x0a\0\0\x08\x80\x01\x1b\xa7\x11\x07\0\0\x08\x82\x04\x1b\xa8\x09\x07\0\
+\0\x08\x83\x06\x1b\xa9\x09\x07\0\0\x08\x84\x07\x2a\x0d\x0a\0\0\x08\x86\x08\x37\
+\x20\x08\x86\x2a\x19\x0a\0\0\x08\x86\0\x1a\x20\x08\x86\x1b\x96\x5e\x0a\0\0\x08\
+\x86\0\x1b\x97\x5e\x0a\0\0\x08\x86\x10\0\x1b\x98\x39\x0a\0\0\x08\x86\0\x1a\x20\
+\x08\x86\x1b\x96\x5e\x0a\0\0\x08\x86\0\x1b\x97\x5e\x0a\0\0\x08\x86\x10\0\0\0\
+\x14\x09\x07\0\0\x15\x36\x02\0\0\x03\0\x29\xae\x10\x09\x21\x1b\xaa\x6c\x0a\0\0\
+\x09\x28\0\x37\x10\x09\x22\x1b\xab\x8d\x0a\0\0\x09\x23\0\x1b\xac\x99\x0a\0\0\
+\x09\x25\0\x1b\xad\xa5\x0a\0\0\x09\x26\0\0\0\x14\x09\x07\0\0\x15\x36\x02\0\0\
+\x10\0\x14\x11\x07\0\0\x15\x36\x02\0\0\x08\0\x14\x19\x07\0\0\x15\x36\x02\0\0\
+\x04\0\x38\x1a\x24\0\x99\x1b\x9c\x24\x06\0\0\0\x9a\0\x1b\x9d\x24\x06\0\0\0\x9b\
+\x10\x1b\x68\x39\x04\0\0\0\x9c\x20\x1b\x67\x39\x04\0\0\0\x9d\x22\0\0\x2b\xb3\0\
+\x39\xed\x0a\0\0\x2c\x8c\0\x39\xf1\x0a\0\0\0\x02\xb4\x02\x01\x1c\xf6\x0a\0\0\
+\x16\x50\x08\0\0\x2b\xb5\0\x6e\xaf\x02\0\0\x2c\xb1\0\x6e\x39\x04\0\0\x2c\x43\0\
+\x6e\x91\x04\0\0\x2c\x9a\0\x6e\x5f\x04\0\0\x2c\xb2\0\x6e\x34\x0b\0\0\x2d\xb6\0\
+\x73\x3a\x0b\0\0\x2d\xa2\0\x74\x15\x03\0\0\0\x1c\xaf\x02\0\0\x38\x29\xb8\x02\0\
+\x70\x1b\xb7\x09\x07\0\0\0\x71\0\x1b\x44\x09\x07\0\0\0\x72\x01\0\0\x2b\xb9\0\
+\xd7\x0d\x03\0\0\x2c\xba\0\xd7\x0d\x03\0\0\x2c\xbb\0\xd7\x0d\x03\0\0\0\x14\x32\
+\x02\0\0\x15\x36\x02\0\0\x1c\0\x1c\x9b\x04\0\0\0\xc9\0\0\0\x05\0\x08\0\x07\0\0\
+\0\x1c\0\0\0\x28\0\0\0\x3a\0\0\0\x57\0\0\0\x7b\0\0\0\x8e\0\0\0\x9d\0\0\0\x04\
+\xf8\x01\xa0\x02\x04\xe8\x02\xc8\xeb\x03\0\x04\xc0\x03\xe0\x03\x04\x90\x04\xf8\
+\x30\x04\xb0\xdf\x01\xf0\xa0\x02\0\x04\xe0\xdf\x01\xc8\x88\x02\x04\xd0\x88\x02\
+\xa8\x89\x02\x04\xb8\x89\x02\x90\x8a\x02\x04\x98\x8a\x02\xf0\xa0\x02\0\x04\xd0\
+\xe0\x01\xc8\x88\x02\x04\xd0\x88\x02\xa8\x89\x02\x04\xb8\x89\x02\x90\x8a\x02\
+\x04\x98\x8a\x02\xf0\x8a\x02\x04\xf8\x8a\x02\xf0\xa0\x02\0\x04\xe0\x31\x80\x32\
+\x04\xb0\x32\xf8\xde\x01\x04\x88\xa1\x02\xc8\xeb\x03\0\x04\x98\xa1\x02\xb0\xa1\
+\x02\x04\xf8\xe4\x03\xc8\xeb\x03\0\x04\x98\xa2\x02\xe0\xcc\x03\x04\xe8\xcc\x03\
+\xc0\xcd\x03\x04\xd0\xcd\x03\xa8\xce\x03\x04\xb0\xce\x03\x88\xcf\x03\x04\x90\
+\xcf\x03\xf8\xe4\x03\0\x0c\x03\0\0\x05\0\0\0\0\0\0\0\x21\0\0\0\x2b\0\0\0\x5f\0\
+\0\0\x67\0\0\0\x6c\0\0\0\x80\0\0\0\x89\0\0\0\x91\0\0\0\x96\0\0\0\x9a\0\0\0\xa3\
+\0\0\0\xae\0\0\0\xba\0\0\0\xcb\0\0\0\xd0\0\0\0\xdd\0\0\0\xe3\0\0\0\xf7\0\0\0\
+\x13\x01\0\0\x25\x01\0\0\x37\x01\0\0\x49\x01\0\0\x5c\x01\0\0\x72\x01\0\0\x85\
+\x01\0\0\x9b\x01\0\0\xa6\x01\0\0\xb1\x01\0\0\xbe\x01\0\0\xcb\x01\0\0\xd8\x01\0\
+\0\xe4\x01\0\0\xf0\x01\0\0\xfc\x01\0\0\x08\x02\0\0\x14\x02\0\0\x1f\x02\0\0\x2c\
+\x02\0\0\x39\x02\0\0\x46\x02\0\0\x52\x02\0\0\x5e\x02\0\0\x69\x02\0\0\x75\x02\0\
+\0\x84\x02\0\0\x92\x02\0\0\x9e\x02\0\0\xab\x02\0\0\xb8\x02\0\0\xc5\x02\0\0\xd5\
+\x02\0\0\xe2\x02\0\0\xf3\x02\0\0\xff\x02\0\0\x0d\x03\0\0\x19\x03\0\0\x21\x03\0\
+\0\x39\x03\0\0\x48\x03\0\0\x4e\x03\0\0\x59\x03\0\0\x5e\x03\0\0\x6c\x03\0\0\x79\
+\x03\0\0\x8c\x03\0\0\x92\x03\0\0\xa5\x03\0\0\xa9\x03\0\0\xad\x03\0\0\xb6\x03\0\
+\0\xbb\x03\0\0\xc9\x03\0\0\xd2\x03\0\0\xdf\x03\0\0\xe8\x03\0\0\xf3\x03\0\0\xfc\
+\x03\0\0\x0c\x04\0\0\x14\x04\0\0\x1d\x04\0\0\x20\x04\0\0\x25\x04\0\0\x2e\x04\0\
+\0\x36\x04\0\0\x3d\x04\0\0\x48\x04\0\0\x52\x04\0\0\x5d\x04\0\0\x67\x04\0\0\x73\
+\x04\0\0\x7e\x04\0\0\x88\x04\0\0\x92\x04\0\0\x98\x04\0\0\x9e\x04\0\0\xa9\x04\0\
+\0\xb1\x04\0\0\xb6\x04\0\0\xc4\x04\0\0\xcd\x04\0\0\xd6\x04\0\0\xde\x04\0\0\xe5\
+\x04\0\0\xeb\x04\0\0\xf1\x04\0\0\xfa\x04\0\0\x01\x05\0\0\x0a\x05\0\0\x13\x05\0\
+\0\x1c\x05\0\0\x22\x05\0\0\x2d\x05\0\0\x3b\x05\0\0\x42\x05\0\0\x4b\x05\0\0\x54\
+\x05\0\0\x57\x05\0\0\x64\x05\0\0\x6c\x05\0\0\x74\x05\0\0\x7d\x05\0\0\x86\x05\0\
+\0\x8e\x05\0\0\x96\x05\0\0\x9c\x05\0\0\xad\x05\0\0\xb3\x05\0\0\xbc\x05\0\0\xc5\
+\x05\0\0\xd1\x05\0\0\xda\x05\0\0\xe4\x05\0\0\xeb\x05\0\0\xf7\x05\0\0\xfb\x05\0\
+\0\x05\x06\0\0\x0c\x06\0\0\x14\x06\0\0\x1f\x06\0\0\x29\x06\0\0\x2d\x06\0\0\x31\
+\x06\0\0\x39\x06\0\0\x3d\x06\0\0\x45\x06\0\0\x48\x06\0\0\x51\x06\0\0\x55\x06\0\
+\0\x5b\x06\0\0\x63\x06\0\0\x69\x06\0\0\x6f\x06\0\0\x75\x06\0\0\x7b\x06\0\0\x7f\
+\x06\0\0\x88\x06\0\0\x91\x06\0\0\x9a\x06\0\0\xa7\x06\0\0\xb2\x06\0\0\xbe\x06\0\
+\0\xc8\x06\0\0\xca\x06\0\0\xcc\x06\0\0\xd7\x06\0\0\xdc\x06\0\0\xe5\x06\0\0\xf1\
+\x06\0\0\xf9\x06\0\0\x03\x07\0\0\x09\x07\0\0\x12\x07\0\0\x1c\x07\0\0\x26\x07\0\
+\0\x2f\x07\0\0\x37\x07\0\0\x40\x07\0\0\x46\x07\0\0\x4b\x07\0\0\x5c\x07\0\0\x62\
+\x07\0\0\x6f\x07\0\0\x72\x07\0\0\x7b\x07\0\0\x83\x07\0\0\x94\x07\0\0\x98\x07\0\
+\0\x9a\x07\0\0\xad\x07\0\0\xc0\x07\0\0\xd2\x07\0\0\xe2\x07\0\0\xe6\x07\0\0\x44\
+\x65\x62\x69\x61\x6e\x20\x63\x6c\x61\x6e\x67\x20\x76\x65\x72\x73\x69\x6f\x6e\
+\x20\x31\x36\x2e\x30\x2e\x36\x20\x28\x31\x39\x29\0\x74\x61\x70\x5f\x72\x73\x73\
+\x2e\x63\0\x2f\x68\x6f\x6d\x65\x2f\x73\x68\x65\x6d\x6d\x69\x6e\x67\x65\x72\x2f\
+\x44\x50\x44\x4b\x2f\x74\x61\x70\x2f\x66\x69\x78\x69\x74\x2f\x64\x72\x69\x76\
+\x65\x72\x73\x2f\x6e\x65\x74\x2f\x74\x61\x70\x2f\x62\x70\x66\0\x5f\x5f\x5f\x5f\
+\x66\x6d\x74\0\x63\x68\x61\x72\0\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\x49\x5a\
+\x45\x5f\x54\x59\x50\x45\x5f\x5f\0\x5f\x6c\x69\x63\x65\x6e\x73\x65\0\x72\x73\
+\x73\x5f\x6d\x61\x70\0\x74\x79\x70\x65\0\x69\x6e\x74\0\x6b\x65\x79\x5f\x73\x69\
+\x7a\x65\0\x76\x61\x6c\x75\x65\x5f\x73\x69\x7a\x65\0\x6d\x61\x78\x5f\x65\x6e\
+\x74\x72\x69\x65\x73\0\x62\x70\x66\x5f\x74\x72\x61\x63\x65\x5f\x70\x72\x69\x6e\
+\x74\x6b\0\x6c\x6f\x6e\x67\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\0\
+\x5f\x5f\x75\x33\x32\0\x62\x70\x66\x5f\x6d\x61\x70\x5f\x6c\x6f\x6f\x6b\x75\x70\
+\x5f\x65\x6c\x65\x6d\0\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\
+\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\0\x42\x50\x46\x5f\x48\x44\
+\x52\x5f\x53\x54\x41\x52\x54\x5f\x4d\x41\x43\0\x42\x50\x46\x5f\x48\x44\x52\x5f\
+\x53\x54\x41\x52\x54\x5f\x4e\x45\x54\0\x62\x70\x66\x5f\x68\x64\x72\x5f\x73\x74\
+\x61\x72\x74\x5f\x6f\x66\x66\0\x48\x41\x53\x48\x5f\x46\x49\x45\x4c\x44\x5f\x49\
+\x50\x56\x34\x5f\x4c\x33\0\x48\x41\x53\x48\x5f\x46\x49\x45\x4c\x44\x5f\x49\x50\
+\x56\x34\x5f\x4c\x33\x5f\x4c\x34\0\x48\x41\x53\x48\x5f\x46\x49\x45\x4c\x44\x5f\
+\x49\x50\x56\x36\x5f\x4c\x33\0\x48\x41\x53\x48\x5f\x46\x49\x45\x4c\x44\x5f\x49\
+\x50\x56\x36\x5f\x4c\x33\x5f\x4c\x34\0\x68\x61\x73\x68\x5f\x66\x69\x65\x6c\x64\
+\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x49\x50\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\
+\x49\x43\x4d\x50\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x49\x47\x4d\x50\0\x49\x50\
+\x50\x52\x4f\x54\x4f\x5f\x49\x50\x49\x50\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x54\
+\x43\x50\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x45\x47\x50\0\x49\x50\x50\x52\x4f\
+\x54\x4f\x5f\x50\x55\x50\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x55\x44\x50\0\x49\
+\x50\x50\x52\x4f\x54\x4f\x5f\x49\x44\x50\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x54\
+\x50\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x44\x43\x43\x50\0\x49\x50\x50\x52\x4f\
+\x54\x4f\x5f\x49\x50\x56\x36\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x52\x53\x56\x50\
+\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x47\x52\x45\0\x49\x50\x50\x52\x4f\x54\x4f\
+\x5f\x45\x53\x50\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x41\x48\0\x49\x50\x50\x52\
+\x4f\x54\x4f\x5f\x4d\x54\x50\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x42\x45\x45\x54\
+\x50\x48\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x45\x4e\x43\x41\x50\0\x49\x50\x50\
+\x52\x4f\x54\x4f\x5f\x50\x49\x4d\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x43\x4f\x4d\
+\x50\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x4c\x32\x54\x50\0\x49\x50\x50\x52\x4f\
+\x54\x4f\x5f\x53\x43\x54\x50\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x55\x44\x50\x4c\
+\x49\x54\x45\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x4d\x50\x4c\x53\0\x49\x50\x50\
+\x52\x4f\x54\x4f\x5f\x45\x54\x48\x45\x52\x4e\x45\x54\0\x49\x50\x50\x52\x4f\x54\
+\x4f\x5f\x52\x41\x57\0\x49\x50\x50\x52\x4f\x54\x4f\x5f\x4d\x50\x54\x43\x50\0\
+\x49\x50\x50\x52\x4f\x54\x4f\x5f\x4d\x41\x58\0\x70\x6b\x74\x5f\x6c\x65\x6e\0\
+\x73\x6c\x61\x76\x65\x5f\x64\x65\x76\x5f\x71\x75\x65\x75\x65\x5f\x6d\x61\x70\
+\x70\x69\x6e\x67\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x73\x68\x6f\x72\x74\0\
+\x5f\x5f\x75\x31\x36\0\x74\x63\x5f\x63\x6c\x61\x73\x73\x69\x64\0\x64\x61\x74\
+\x61\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x63\x68\x61\x72\0\x71\x64\x69\x73\
+\x63\x5f\x73\x6b\x62\x5f\x63\x62\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x6c\x6f\
+\x6e\x67\x20\x6c\x6f\x6e\x67\0\x5f\x5f\x75\x36\x34\0\x63\x61\x6c\x63\x75\x6c\
+\x61\x74\x65\x5f\x72\x73\x73\x5f\x68\x61\x73\x68\0\x73\x6b\x62\0\x6c\x65\x6e\0\
+\x70\x6b\x74\x5f\x74\x79\x70\x65\0\x6d\x61\x72\x6b\0\x71\x75\x65\x75\x65\x5f\
+\x6d\x61\x70\x70\x69\x6e\x67\0\x70\x72\x6f\x74\x6f\x63\x6f\x6c\0\x76\x6c\x61\
+\x6e\x5f\x70\x72\x65\x73\x65\x6e\x74\0\x76\x6c\x61\x6e\x5f\x74\x63\x69\0\x76\
+\x6c\x61\x6e\x5f\x70\x72\x6f\x74\x6f\0\x70\x72\x69\x6f\x72\x69\x74\x79\0\x69\
+\x6e\x67\x72\x65\x73\x73\x5f\x69\x66\x69\x6e\x64\x65\x78\0\x69\x66\x69\x6e\x64\
+\x65\x78\0\x74\x63\x5f\x69\x6e\x64\x65\x78\0\x63\x62\0\x68\x61\x73\x68\0\x64\
+\x61\x74\x61\x5f\x65\x6e\x64\0\x6e\x61\x70\x69\x5f\x69\x64\0\x66\x61\x6d\x69\
+\x6c\x79\0\x72\x65\x6d\x6f\x74\x65\x5f\x69\x70\x34\0\x6c\x6f\x63\x61\x6c\x5f\
+\x69\x70\x34\0\x72\x65\x6d\x6f\x74\x65\x5f\x69\x70\x36\0\x6c\x6f\x63\x61\x6c\
+\x5f\x69\x70\x36\0\x72\x65\x6d\x6f\x74\x65\x5f\x70\x6f\x72\x74\0\x6c\x6f\x63\
+\x61\x6c\x5f\x70\x6f\x72\x74\0\x64\x61\x74\x61\x5f\x6d\x65\x74\x61\0\x66\x6c\
+\x6f\x77\x5f\x6b\x65\x79\x73\0\x6e\x68\x6f\x66\x66\0\x74\x68\x6f\x66\x66\0\x61\
+\x64\x64\x72\x5f\x70\x72\x6f\x74\x6f\0\x69\x73\x5f\x66\x72\x61\x67\0\x5f\x5f\
+\x75\x38\0\x69\x73\x5f\x66\x69\x72\x73\x74\x5f\x66\x72\x61\x67\0\x69\x73\x5f\
+\x65\x6e\x63\x61\x70\0\x69\x70\x5f\x70\x72\x6f\x74\x6f\0\x6e\x5f\x70\x72\x6f\
+\x74\x6f\0\x5f\x5f\x62\x65\x31\x36\0\x73\x70\x6f\x72\x74\0\x64\x70\x6f\x72\x74\
+\0\x69\x70\x76\x34\x5f\x73\x72\x63\0\x5f\x5f\x62\x65\x33\x32\0\x69\x70\x76\x34\
+\x5f\x64\x73\x74\0\x69\x70\x76\x36\x5f\x73\x72\x63\0\x69\x70\x76\x36\x5f\x64\
+\x73\x74\0\x66\x6c\x61\x67\x73\0\x66\x6c\x6f\x77\x5f\x6c\x61\x62\x65\x6c\0\x62\
+\x70\x66\x5f\x66\x6c\x6f\x77\x5f\x6b\x65\x79\x73\0\x74\x73\x74\x61\x6d\x70\0\
+\x77\x69\x72\x65\x5f\x6c\x65\x6e\0\x67\x73\x6f\x5f\x73\x65\x67\x73\0\x73\x6b\0\
+\x62\x6f\x75\x6e\x64\x5f\x64\x65\x76\x5f\x69\x66\0\x73\x72\x63\x5f\x69\x70\x34\
+\0\x73\x72\x63\x5f\x69\x70\x36\0\x73\x72\x63\x5f\x70\x6f\x72\x74\0\x64\x73\x74\
+\x5f\x70\x6f\x72\x74\0\x64\x73\x74\x5f\x69\x70\x34\0\x64\x73\x74\x5f\x69\x70\
+\x36\0\x73\x74\x61\x74\x65\0\x72\x78\x5f\x71\x75\x65\x75\x65\x5f\x6d\x61\x70\
+\x70\x69\x6e\x67\0\x5f\x5f\x73\x33\x32\0\x62\x70\x66\x5f\x73\x6f\x63\x6b\0\x67\
+\x73\x6f\x5f\x73\x69\x7a\x65\0\x74\x73\x74\x61\x6d\x70\x5f\x74\x79\x70\x65\0\
+\x68\x77\x74\x73\x74\x61\x6d\x70\0\x5f\x5f\x73\x6b\x5f\x62\x75\x66\x66\0\x72\
+\x73\x73\x6b\x65\x79\0\x68\x61\x73\x68\x5f\x66\x69\x65\x6c\x64\x73\0\x6b\x65\
+\x79\0\x6e\x62\x5f\x71\x75\x65\x75\x65\x73\0\x71\x75\x65\x75\x65\x73\0\x72\x73\
+\x73\x5f\x6b\x65\x79\0\x70\x61\x72\x73\x65\x5f\x69\x70\x76\x34\0\x68\x61\x73\
+\x68\x5f\x74\x79\x70\x65\0\x69\x70\x68\0\x69\x68\x6c\0\x76\x65\x72\x73\x69\x6f\
+\x6e\0\x74\x6f\x73\0\x74\x6f\x74\x5f\x6c\x65\x6e\0\x69\x64\0\x66\x72\x61\x67\
+\x5f\x6f\x66\x66\0\x74\x74\x6c\0\x63\x68\x65\x63\x6b\0\x5f\x5f\x73\x75\x6d\x31\
+\x36\0\x73\x61\x64\x64\x72\0\x64\x61\x64\x64\x72\0\x61\x64\x64\x72\x73\0\x69\
+\x70\x68\x64\x72\0\x6f\x66\x66\0\x76\x34\x5f\x74\x75\x70\x6c\x65\0\x73\x72\x63\
+\x5f\x61\x64\x64\x72\0\x64\x73\x74\x5f\x61\x64\x64\x72\0\x73\x72\x63\x5f\x64\
+\x73\x74\x5f\x70\x6f\x72\x74\0\x73\x6f\x66\x74\x72\x73\x73\x5f\x62\x65\0\x69\
+\x6e\x70\x75\x74\x5f\x74\x75\x70\x6c\x65\0\x69\x6e\x70\x75\x74\x5f\x6c\x65\x6e\
+\0\x69\0\x6a\0\x70\x61\x72\x73\x65\x5f\x69\x70\x76\x36\0\x69\x70\x36\x68\0\x66\
+\x6c\x6f\x77\x5f\x6c\x62\x6c\0\x70\x61\x79\x6c\x6f\x61\x64\x5f\x6c\x65\x6e\0\
+\x6e\x65\x78\x74\x68\x64\x72\0\x68\x6f\x70\x5f\x6c\x69\x6d\x69\x74\0\x69\x6e\
+\x36\x5f\x75\0\x75\x36\x5f\x61\x64\x64\x72\x38\0\x75\x36\x5f\x61\x64\x64\x72\
+\x31\x36\0\x75\x36\x5f\x61\x64\x64\x72\x33\x32\0\x69\x6e\x36\x5f\x61\x64\x64\
+\x72\0\x69\x70\x76\x36\x68\x64\x72\0\x76\x36\x5f\x74\x75\x70\x6c\x65\0\x70\x72\
+\x6f\x74\x6f\0\x66\x72\x61\x67\0\x69\x73\x5f\x69\x70\x76\x34\x5f\x66\x72\x61\
+\x67\x6d\x65\x6e\x74\0\x5f\x42\x6f\x6f\x6c\0\x73\x6b\x69\x70\x5f\x69\x70\x36\
+\x5f\x65\x78\x74\0\x78\x68\0\x6e\x65\x78\x74\x5f\x68\x64\x72\0\x65\x78\x74\x5f\
+\x68\x64\x72\0\x72\x65\x63\x69\x70\x72\x6f\x63\x61\x6c\x5f\x73\x63\x61\x6c\x65\
+\0\x76\x61\x6c\0\x6e\0\x44\x57\x5f\x41\x54\x45\x5f\x75\x6e\x73\x69\x67\x6e\x65\
+\x64\x5f\x33\x32\0\x44\x57\x5f\x41\x54\x45\x5f\x75\x6e\x73\x69\x67\x6e\x65\x64\
+\x5f\x31\x36\0\x44\x57\x5f\x41\x54\x45\x5f\x75\x6e\x73\x69\x67\x6e\x65\x64\x5f\
+\x38\0\x72\x73\x73\x5f\x66\x6c\x6f\x77\x5f\x61\x63\x74\x69\x6f\x6e\0\x66\x6d\
+\x74\0\x63\x6c\x61\x73\x73\x69\x64\0\x5c\0\0\0\x05\0\x08\0\0\0\0\0\0\0\0\0\x1b\
+\0\0\0\0\0\0\0\x24\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\x60\x02\0\0\0\0\0\0\xb0\x6f\0\0\0\0\0\0\xf8\x19\0\0\0\0\0\0\xd8\x90\0\0\0\0\
+\0\0\x70\xf6\0\0\0\0\0\0\0\0\x9f\xeb\x01\0\x18\0\0\0\0\0\0\0\xcc\x04\0\0\xcc\
+\x04\0\0\xda\x09\0\0\0\0\0\0\0\0\0\x02\x03\0\0\0\x01\0\0\0\0\0\0\x01\x04\0\0\0\
+\x20\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x01\0\0\0\x05\0\0\0\
+\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\0\0\0\0\0\0\x02\x06\0\0\0\0\0\0\0\0\0\0\x03\0\
+\0\0\0\x02\0\0\0\x04\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\x02\x08\0\0\0\0\0\0\0\0\0\0\
+\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x70\0\0\0\0\0\0\0\0\0\0\x02\x0a\0\0\0\0\0\0\0\
+\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x10\0\0\0\0\0\0\0\x04\0\0\x04\x20\0\0\0\
+\x19\0\0\0\x01\0\0\0\0\0\0\0\x1e\0\0\0\x05\0\0\0\x40\0\0\0\x27\0\0\0\x07\0\0\0\
+\x80\0\0\0\x32\0\0\0\x09\0\0\0\xc0\0\0\0\x3e\0\0\0\0\0\0\x0e\x0b\0\0\0\x01\0\0\
+\0\0\0\0\0\0\0\0\x02\x0e\0\0\0\x46\0\0\0\x22\0\0\x04\xc0\0\0\0\x50\0\0\0\x0f\0\
+\0\0\0\0\0\0\x54\0\0\0\x0f\0\0\0\x20\0\0\0\x5d\0\0\0\x0f\0\0\0\x40\0\0\0\x62\0\
+\0\0\x0f\0\0\0\x60\0\0\0\x70\0\0\0\x0f\0\0\0\x80\0\0\0\x79\0\0\0\x0f\0\0\0\xa0\
+\0\0\0\x86\0\0\0\x0f\0\0\0\xc0\0\0\0\x8f\0\0\0\x0f\0\0\0\xe0\0\0\0\x9a\0\0\0\
+\x0f\0\0\0\0\x01\0\0\xa3\0\0\0\x0f\0\0\0\x20\x01\0\0\xb3\0\0\0\x0f\0\0\0\x40\
+\x01\0\0\xbb\0\0\0\x0f\0\0\0\x60\x01\0\0\xc4\0\0\0\x11\0\0\0\x80\x01\0\0\xc7\0\
+\0\0\x0f\0\0\0\x20\x02\0\0\xcc\0\0\0\x0f\0\0\0\x40\x02\0\0\xd7\0\0\0\x0f\0\0\0\
+\x60\x02\0\0\xdc\0\0\0\x0f\0\0\0\x80\x02\0\0\xe5\0\0\0\x0f\0\0\0\xa0\x02\0\0\
+\xed\0\0\0\x0f\0\0\0\xc0\x02\0\0\xf4\0\0\0\x0f\0\0\0\xe0\x02\0\0\xff\0\0\0\x0f\
+\0\0\0\0\x03\0\0\x09\x01\0\0\x12\0\0\0\x20\x03\0\0\x14\x01\0\0\x12\0\0\0\xa0\
+\x03\0\0\x1e\x01\0\0\x0f\0\0\0\x20\x04\0\0\x2a\x01\0\0\x0f\0\0\0\x40\x04\0\0\
+\x35\x01\0\0\x0f\0\0\0\x60\x04\0\0\0\0\0\0\x13\0\0\0\x80\x04\0\0\x3f\x01\0\0\
+\x15\0\0\0\xc0\x04\0\0\x46\x01\0\0\x0f\0\0\0\0\x05\0\0\x4f\x01\0\0\x0f\0\0\0\
+\x20\x05\0\0\0\0\0\0\x17\0\0\0\x40\x05\0\0\x58\x01\0\0\x0f\0\0\0\x80\x05\0\0\
+\x61\x01\0\0\x19\0\0\0\xa0\x05\0\0\x6d\x01\0\0\x15\0\0\0\xc0\x05\0\0\x76\x01\0\
+\0\0\0\0\x08\x10\0\0\0\x7c\x01\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\0\0\0\0\0\0\
+\x03\0\0\0\0\x0f\0\0\0\x04\0\0\0\x05\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x0f\0\0\0\
+\x04\0\0\0\x04\0\0\0\0\0\0\0\x01\0\0\x05\x08\0\0\0\x89\x01\0\0\x14\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x02\x2a\0\0\0\x93\x01\0\0\0\0\0\x08\x16\0\0\0\x99\x01\0\0\0\0\
+\0\x01\x08\0\0\0\x40\0\0\0\0\0\0\0\x01\0\0\x05\x08\0\0\0\xac\x01\0\0\x18\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x02\x2b\0\0\0\xaf\x01\0\0\0\0\0\x08\x1a\0\0\0\xb4\x01\0\
+\0\0\0\0\x01\x01\0\0\0\x08\0\0\0\0\0\0\0\x01\0\0\x0d\x02\0\0\0\xc2\x01\0\0\x0d\
+\0\0\0\xc6\x01\0\0\x01\0\0\x0c\x1b\0\0\0\0\0\0\0\0\0\0\x0a\x1e\0\0\0\x53\x09\0\
+\0\0\0\0\x01\x01\0\0\0\x08\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x1d\0\0\0\x04\0\0\
+\0\x1b\0\0\0\x58\x09\0\0\0\0\0\x0e\x1f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\
+\x1d\0\0\0\x04\0\0\0\x09\0\0\0\x70\x09\0\0\0\0\0\x0e\x21\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\x03\0\0\0\0\x1d\0\0\0\x04\0\0\0\x0a\0\0\0\x8a\x09\0\0\0\0\0\x0e\x23\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x1e\0\0\0\x04\0\0\0\x0d\0\0\0\xa4\x09\0\0\
+\0\0\0\x0e\x25\0\0\0\x01\0\0\0\xad\x09\0\0\x01\0\0\x0f\0\0\0\0\x0c\0\0\0\0\0\0\
+\0\x20\0\0\0\xb3\x09\0\0\x03\0\0\x0f\0\0\0\0\x20\0\0\0\0\0\0\0\x1b\0\0\0\x22\0\
+\0\0\x1b\0\0\0\x09\0\0\0\x24\0\0\0\x24\0\0\0\x0a\0\0\0\xbb\x09\0\0\x01\0\0\x0f\
+\0\0\0\0\x26\0\0\0\0\0\0\0\x0d\0\0\0\xc3\x09\0\0\0\0\0\x07\0\0\0\0\xd1\x09\0\0\
+\0\0\0\x07\0\0\0\0\0\x69\x6e\x74\0\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\x49\x5a\
+\x45\x5f\x54\x59\x50\x45\x5f\x5f\0\x74\x79\x70\x65\0\x6b\x65\x79\x5f\x73\x69\
+\x7a\x65\0\x76\x61\x6c\x75\x65\x5f\x73\x69\x7a\x65\0\x6d\x61\x78\x5f\x65\x6e\
+\x74\x72\x69\x65\x73\0\x72\x73\x73\x5f\x6d\x61\x70\0\x5f\x5f\x73\x6b\x5f\x62\
+\x75\x66\x66\0\x6c\x65\x6e\0\x70\x6b\x74\x5f\x74\x79\x70\x65\0\x6d\x61\x72\x6b\
+\0\x71\x75\x65\x75\x65\x5f\x6d\x61\x70\x70\x69\x6e\x67\0\x70\x72\x6f\x74\x6f\
+\x63\x6f\x6c\0\x76\x6c\x61\x6e\x5f\x70\x72\x65\x73\x65\x6e\x74\0\x76\x6c\x61\
+\x6e\x5f\x74\x63\x69\0\x76\x6c\x61\x6e\x5f\x70\x72\x6f\x74\x6f\0\x70\x72\x69\
+\x6f\x72\x69\x74\x79\0\x69\x6e\x67\x72\x65\x73\x73\x5f\x69\x66\x69\x6e\x64\x65\
+\x78\0\x69\x66\x69\x6e\x64\x65\x78\0\x74\x63\x5f\x69\x6e\x64\x65\x78\0\x63\x62\
+\0\x68\x61\x73\x68\0\x74\x63\x5f\x63\x6c\x61\x73\x73\x69\x64\0\x64\x61\x74\x61\
+\0\x64\x61\x74\x61\x5f\x65\x6e\x64\0\x6e\x61\x70\x69\x5f\x69\x64\0\x66\x61\x6d\
+\x69\x6c\x79\0\x72\x65\x6d\x6f\x74\x65\x5f\x69\x70\x34\0\x6c\x6f\x63\x61\x6c\
+\x5f\x69\x70\x34\0\x72\x65\x6d\x6f\x74\x65\x5f\x69\x70\x36\0\x6c\x6f\x63\x61\
+\x6c\x5f\x69\x70\x36\0\x72\x65\x6d\x6f\x74\x65\x5f\x70\x6f\x72\x74\0\x6c\x6f\
+\x63\x61\x6c\x5f\x70\x6f\x72\x74\0\x64\x61\x74\x61\x5f\x6d\x65\x74\x61\0\x74\
+\x73\x74\x61\x6d\x70\0\x77\x69\x72\x65\x5f\x6c\x65\x6e\0\x67\x73\x6f\x5f\x73\
+\x65\x67\x73\0\x67\x73\x6f\x5f\x73\x69\x7a\x65\0\x74\x73\x74\x61\x6d\x70\x5f\
+\x74\x79\x70\x65\0\x68\x77\x74\x73\x74\x61\x6d\x70\0\x5f\x5f\x75\x33\x32\0\x75\
+\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\0\x66\x6c\x6f\x77\x5f\x6b\x65\x79\
+\x73\0\x5f\x5f\x75\x36\x34\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x6c\x6f\x6e\
+\x67\x20\x6c\x6f\x6e\x67\0\x73\x6b\0\x5f\x5f\x75\x38\0\x75\x6e\x73\x69\x67\x6e\
+\x65\x64\x20\x63\x68\x61\x72\0\x73\x6b\x62\0\x72\x73\x73\x5f\x66\x6c\x6f\x77\
+\x5f\x61\x63\x74\x69\x6f\x6e\0\x74\x63\x2f\x69\x6e\x67\x72\x65\x73\x73\0\x2f\
+\x68\x6f\x6d\x65\x2f\x73\x68\x65\x6d\x6d\x69\x6e\x67\x65\x72\x2f\x44\x50\x44\
+\x4b\x2f\x74\x61\x70\x2f\x66\x69\x78\x69\x74\x2f\x64\x72\x69\x76\x65\x72\x73\
+\x2f\x6e\x65\x74\x2f\x74\x61\x70\x2f\x62\x70\x66\x2f\x74\x61\x70\x5f\x72\x73\
+\x73\x2e\x63\0\x72\x73\x73\x5f\x66\x6c\x6f\x77\x5f\x61\x63\x74\x69\x6f\x6e\x28\
+\x73\x74\x72\x75\x63\x74\x20\x5f\x5f\x73\x6b\x5f\x62\x75\x66\x66\x20\x2a\x73\
+\x6b\x62\x29\0\x09\x63\x68\x61\x72\x20\x66\x6d\x74\x5b\x5d\x20\x3d\x20\x22\x72\
+\x73\x73\x5f\x66\x6c\x6f\x77\x5f\x61\x63\x74\x69\x6f\x6e\x20\x63\x6c\x61\x73\
+\x73\x69\x64\x3a\x25\x75\x5c\x6e\x22\x3b\0\x09\x63\x6c\x61\x73\x73\x69\x64\x20\
+\x3d\x20\x28\x28\x63\x6f\x6e\x73\x74\x20\x73\x74\x72\x75\x63\x74\x20\x71\x64\
+\x69\x73\x63\x5f\x73\x6b\x62\x5f\x63\x62\x20\x2a\x29\x73\x6b\x62\x2d\x3e\x63\
+\x62\x29\x2d\x3e\x74\x63\x5f\x63\x6c\x61\x73\x73\x69\x64\x3b\0\x09\x62\x70\x66\
+\x5f\x74\x72\x61\x63\x65\x5f\x70\x72\x69\x6e\x74\x6b\x28\x66\x6d\x74\x2c\x20\
+\x73\x69\x7a\x65\x6f\x66\x28\x66\x6d\x74\x29\x2c\x20\x63\x6c\x61\x73\x73\x69\
+\x64\x29\x3b\0\x09\x72\x73\x73\x6b\x65\x79\x20\x3d\x20\x62\x70\x66\x5f\x6d\x61\
+\x70\x5f\x6c\x6f\x6f\x6b\x75\x70\x5f\x65\x6c\x65\x6d\x28\x26\x72\x73\x73\x5f\
+\x6d\x61\x70\x2c\x20\x26\x63\x6c\x61\x73\x73\x69\x64\x29\x3b\0\x09\x69\x66\x20\
+\x28\x72\x73\x73\x6b\x65\x79\x20\x3d\x3d\x20\x4e\x55\x4c\x4c\x29\x20\x7b\0\x09\
+\x09\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x68\x61\x73\x68\x28\x29\
+\x3a\x20\x72\x73\x73\x20\x6e\x6f\x74\x20\x63\x6f\x6e\x66\x69\x67\x75\x72\x65\
+\x64\x22\x29\x3b\0\x09\x63\x6f\x6e\x73\x74\x20\x5f\x5f\x75\x33\x32\x20\x2a\x6b\
+\x65\x79\x20\x3d\x20\x28\x63\x6f\x6e\x73\x74\x20\x5f\x5f\x75\x33\x32\x20\x2a\
+\x29\x72\x73\x73\x6b\x65\x79\x2d\x3e\x6b\x65\x79\x3b\0\x09\x69\x66\x20\x28\x73\
+\x6b\x62\x2d\x3e\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\x3d\x20\x62\x70\x66\
+\x5f\x68\x74\x6f\x6e\x73\x28\x45\x54\x48\x5f\x50\x5f\x49\x50\x29\x29\0\x09\x62\
+\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x68\x61\x73\x68\x20\x25\x75\x5c\
+\x6e\x22\x2c\x20\x68\x61\x73\x68\x29\x3b\0\x09\x09\x72\x65\x74\x75\x72\x6e\x20\
+\x70\x61\x72\x73\x65\x5f\x69\x70\x76\x34\x28\x73\x6b\x62\x2c\x20\x72\x73\x73\
+\x6b\x65\x79\x2d\x3e\x68\x61\x73\x68\x5f\x66\x69\x65\x6c\x64\x73\x2c\x20\x6b\
+\x65\x79\x29\x3b\0\x09\x69\x66\x20\x28\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\
+\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\
+\x6b\x62\x2c\x20\x6f\x66\x66\x2c\x20\x26\x69\x70\x68\x2c\x20\x73\x69\x7a\x65\
+\x6f\x66\x28\x69\x70\x68\x29\x2c\x20\x42\x50\x46\x5f\x48\x44\x52\x5f\x53\x54\
+\x41\x52\x54\x5f\x4e\x45\x54\x29\x29\0\x09\x09\x2e\x64\x73\x74\x5f\x61\x64\x64\
+\x72\x20\x3d\x20\x62\x70\x66\x5f\x6e\x74\x6f\x68\x6c\x28\x69\x70\x68\x2e\x64\
+\x61\x64\x64\x72\x29\x2c\0\x09\x09\x2e\x73\x72\x63\x5f\x61\x64\x64\x72\x20\x3d\
+\x20\x62\x70\x66\x5f\x6e\x74\x6f\x68\x6c\x28\x69\x70\x68\x2e\x73\x61\x64\x64\
+\x72\x29\x2c\0\x09\x69\x66\x20\x28\x68\x61\x73\x68\x5f\x74\x79\x70\x65\x20\x26\
+\x20\x28\x31\x20\x3c\x3c\x20\x48\x41\x53\x48\x5f\x46\x49\x45\x4c\x44\x5f\x49\
+\x50\x56\x34\x5f\x4c\x33\x29\x29\0\x09\x09\x09\x69\x66\x20\x28\x69\x6e\x70\x75\
+\x74\x5f\x74\x75\x70\x6c\x65\x5b\x6a\x5d\x20\x26\x20\x28\x31\x55\x20\x3c\x3c\
+\x20\x28\x33\x31\x20\x2d\x20\x69\x29\x29\x29\0\x09\x09\x09\x09\x68\x61\x73\x68\
+\x20\x5e\x3d\x20\x6b\x65\x79\x5b\x6a\x5d\x20\x3c\x3c\x20\x69\x20\x7c\x20\x6b\
+\x65\x79\x5b\x6a\x20\x2b\x20\x31\x5d\x20\x3e\x3e\x20\x28\x33\x32\x20\x2d\x20\
+\x69\x29\x3b\0\x09\x09\x72\x65\x74\x75\x72\x6e\x20\x70\x61\x72\x73\x65\x5f\x69\
+\x70\x76\x36\x28\x73\x6b\x62\x2c\x20\x72\x73\x73\x6b\x65\x79\x2d\x3e\x68\x61\
+\x73\x68\x5f\x66\x69\x65\x6c\x64\x73\x2c\x20\x6b\x65\x79\x29\x3b\0\x09\x69\x66\
+\x20\x28\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\
+\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x6f\x66\x66\
+\x2c\x20\x26\x69\x70\x36\x68\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\x69\x70\x36\
+\x68\x29\x2c\x20\x42\x50\x46\x5f\x48\x44\x52\x5f\x53\x54\x41\x52\x54\x5f\x4e\
+\x45\x54\x29\x29\0\x09\x09\x76\x36\x5f\x74\x75\x70\x6c\x65\x2e\x64\x73\x74\x5f\
+\x61\x64\x64\x72\x5b\x6a\x5d\x20\x3d\x20\x62\x70\x66\x5f\x6e\x74\x6f\x68\x6c\
+\x28\x69\x70\x36\x68\x2e\x64\x61\x64\x64\x72\x2e\x69\x6e\x36\x5f\x75\x2e\x75\
+\x36\x5f\x61\x64\x64\x72\x33\x32\x5b\x6a\x5d\x29\x3b\0\x09\x09\x76\x36\x5f\x74\
+\x75\x70\x6c\x65\x2e\x73\x72\x63\x5f\x61\x64\x64\x72\x5b\x6a\x5d\x20\x3d\x20\
+\x62\x70\x66\x5f\x6e\x74\x6f\x68\x6c\x28\x69\x70\x36\x68\x2e\x73\x61\x64\x64\
+\x72\x2e\x69\x6e\x36\x5f\x75\x2e\x75\x36\x5f\x61\x64\x64\x72\x33\x32\x5b\x6a\
+\x5d\x29\x3b\0\x09\x69\x66\x20\x28\x68\x61\x73\x68\x5f\x74\x79\x70\x65\x20\x26\
+\x20\x28\x31\x20\x3c\x3c\x20\x48\x41\x53\x48\x5f\x46\x49\x45\x4c\x44\x5f\x49\
+\x50\x56\x36\x5f\x4c\x33\x29\x29\0\x09\x72\x65\x74\x75\x72\x6e\x20\x28\x69\x70\
+\x68\x2d\x3e\x66\x72\x61\x67\x5f\x6f\x66\x66\x20\x26\x20\x62\x70\x66\x5f\x68\
+\x74\x6f\x6e\x73\x28\x49\x50\x5f\x4d\x46\x20\x7c\x20\x49\x50\x5f\x4f\x46\x46\
+\x53\x45\x54\x29\x29\x20\x21\x3d\x20\x30\x3b\0\x09\x69\x66\x20\x28\x69\x73\x5f\
+\x69\x70\x76\x34\x5f\x66\x72\x61\x67\x6d\x65\x6e\x74\x28\x26\x69\x70\x68\x29\
+\x20\x7c\x7c\0\x09\x20\x20\x20\x20\x21\x28\x69\x70\x68\x2e\x70\x72\x6f\x74\x6f\
+\x63\x6f\x6c\x20\x3d\x3d\x20\x49\x50\x50\x52\x4f\x54\x4f\x5f\x55\x44\x50\x20\
+\x7c\x7c\x20\x69\x70\x68\x2e\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\x3d\x20\
+\x49\x50\x50\x52\x4f\x54\x4f\x5f\x54\x43\x50\x29\x29\x20\x7b\0\x09\x09\x6f\x66\
+\x66\x20\x2b\x3d\x20\x69\x70\x68\x2e\x69\x68\x6c\x20\x2a\x20\x34\x3b\0\x09\x09\
+\x69\x66\x20\x28\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\
+\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x6f\
+\x66\x66\x2c\0\x09\x70\x72\x6f\x74\x6f\x20\x3d\x20\x73\x6b\x69\x70\x5f\x69\x70\
+\x36\x5f\x65\x78\x74\x28\x69\x70\x36\x68\x2e\x6e\x65\x78\x74\x68\x64\x72\x2c\
+\x20\x73\x6b\x62\x2c\x20\x26\x6f\x66\x66\x2c\x20\x26\x66\x72\x61\x67\x29\x3b\0\
+\x09\x09\x73\x77\x69\x74\x63\x68\x20\x28\x70\x72\x6f\x74\x6f\x29\x20\x7b\0\x09\
+\x69\x66\x20\x28\x66\x72\x61\x67\x20\x7c\x7c\x20\x21\x28\x70\x72\x6f\x74\x6f\
+\x20\x3d\x3d\x20\x49\x50\x50\x52\x4f\x54\x4f\x5f\x55\x44\x50\x20\x7c\x7c\x20\
+\x70\x72\x6f\x74\x6f\x20\x3d\x3d\x20\x49\x50\x50\x52\x4f\x54\x4f\x5f\x54\x43\
+\x50\x29\x29\x20\x7b\0\x09\x09\x69\x66\x20\x28\x62\x70\x66\x5f\x73\x6b\x62\x5f\
+\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\
+\x28\x73\x6b\x62\x2c\x20\x6f\x66\x66\x2c\x20\x26\x73\x72\x63\x5f\x64\x73\x74\
+\x5f\x70\x6f\x72\x74\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\x73\x72\x63\x5f\x64\
+\x73\x74\x5f\x70\x6f\x72\x74\x29\x2c\0\x09\x09\x09\x69\x66\x20\x28\x62\x70\x66\
+\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\
+\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x2a\x6f\x66\x66\x2c\x20\x26\x78\
+\x68\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\x78\x68\x29\x2c\x20\x42\x50\x46\x5f\
+\x48\x44\x52\x5f\x53\x54\x41\x52\x54\x5f\x4e\x45\x54\x29\x29\0\x09\x09\x09\x2a\
+\x6f\x66\x66\x20\x2b\x3d\x20\x28\x78\x68\x2e\x6c\x65\x6e\x20\x2b\x20\x31\x29\
+\x20\x2a\x20\x38\x3b\0\x09\x09\x09\x70\x72\x6f\x74\x6f\x20\x3d\x20\x78\x68\x2e\
+\x6e\x65\x78\x74\x5f\x68\x64\x72\x3b\0\x09\x69\x66\x20\x28\x68\x61\x73\x68\x29\
+\x20\x7b\0\x09\x09\x73\x6b\x62\x2d\x3e\x71\x75\x65\x75\x65\x5f\x6d\x61\x70\x70\
+\x69\x6e\x67\x20\x3d\x20\x72\x65\x63\x69\x70\x72\x6f\x63\x61\x6c\x5f\x73\x63\
+\x61\x6c\x65\x28\x68\x61\x73\x68\x2c\x20\x72\x73\x73\x6b\x65\x79\x2d\x3e\x6e\
+\x62\x5f\x71\x75\x65\x75\x65\x73\x29\x3b\0\x09\x72\x65\x74\x75\x72\x6e\x20\x28\
+\x5f\x5f\x75\x33\x32\x29\x28\x28\x28\x5f\x5f\x75\x36\x34\x29\x76\x61\x6c\x20\
+\x2a\x20\x6e\x29\x20\x3e\x3e\x20\x33\x32\x29\x3b\0\x09\x09\x62\x70\x66\x5f\x70\
+\x72\x69\x6e\x74\x6b\x28\x22\x71\x75\x65\x75\x65\x20\x25\x75\x5c\x6e\x22\x2c\
+\x20\x73\x6b\x62\x2d\x3e\x71\x75\x65\x75\x65\x5f\x6d\x61\x70\x70\x69\x6e\x67\
+\x29\x3b\0\x7d\0\x63\x68\x61\x72\0\x72\x73\x73\x5f\x66\x6c\x6f\x77\x5f\x61\x63\
+\x74\x69\x6f\x6e\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\0\x72\x73\x73\x5f\x66\x6c\x6f\
+\x77\x5f\x61\x63\x74\x69\x6f\x6e\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\0\x72\
+\x73\x73\x5f\x66\x6c\x6f\x77\x5f\x61\x63\x74\x69\x6f\x6e\x2e\x5f\x5f\x5f\x5f\
+\x66\x6d\x74\x2e\x32\0\x5f\x6c\x69\x63\x65\x6e\x73\x65\0\x2e\x6d\x61\x70\x73\0\
+\x2e\x72\x6f\x64\x61\x74\x61\0\x6c\x69\x63\x65\x6e\x73\x65\0\x62\x70\x66\x5f\
+\x66\x6c\x6f\x77\x5f\x6b\x65\x79\x73\0\x62\x70\x66\x5f\x73\x6f\x63\x6b\0\0\0\
+\x9f\xeb\x01\0\x20\0\0\0\0\0\0\0\x14\0\0\0\x14\0\0\0\xfc\x2f\x01\0\x10\x30\x01\
+\0\0\0\0\0\x08\0\0\0\xd6\x01\0\0\x01\0\0\0\0\0\0\0\x1c\0\0\0\x10\0\0\0\xd6\x01\
+\0\0\xff\x12\0\0\0\0\0\0\xe1\x01\0\0\x1f\x02\0\0\0\xc0\x03\0\x10\0\0\0\xe1\x01\
+\0\0\x46\x02\0\0\x07\xcc\x03\0\x60\0\0\0\xe1\x01\0\0\x74\x02\0\0\x34\xe0\x03\0\
+\x68\0\0\0\xe1\x01\0\0\x74\x02\0\0\x0a\xe0\x03\0\x78\0\0\0\xe1\x01\0\0\0\0\0\0\
+\0\0\0\0\x80\0\0\0\xe1\x01\0\0\xb3\x02\0\0\x02\xe4\x03\0\x98\0\0\0\xe1\x01\0\0\
+\0\0\0\0\0\0\0\0\xa0\0\0\0\xe1\x01\0\0\xe1\x02\0\0\x0b\xf0\x03\0\xb8\0\0\0\xe1\
+\x01\0\0\x14\x03\0\0\x06\xf4\x03\0\xc0\0\0\0\xe1\x01\0\0\x2b\x03\0\0\x03\xf8\
+\x03\0\xf0\0\0\0\xe1\x01\0\0\0\0\0\0\0\0\0\0\xf8\0\0\0\xe1\x01\0\0\x57\x03\0\0\
+\x2c\x2c\x03\0\x08\x01\0\0\xe1\x01\0\0\x87\x03\0\0\x0b\x34\x03\0\x10\x01\0\0\
+\xe1\x01\0\0\x87\x03\0\0\x06\x34\x03\0\x28\x01\0\0\xe1\x01\0\0\xb2\x03\0\0\x02\
+\x0c\x04\0\x68\x01\0\0\xe1\x01\0\0\xd2\x03\0\0\x22\x38\x03\0\xc0\x01\0\0\xe1\
+\x01\0\0\x06\x04\0\0\x06\x1c\x01\0\xd8\x01\0\0\xe1\x01\0\0\x06\x04\0\0\x06\x1c\
+\x01\0\xe0\x01\0\0\xe1\x01\0\0\xd2\x03\0\0\0\x38\x03\0\x10\x02\0\0\xe1\x01\0\0\
+\x58\x04\0\0\x0f\x44\x01\0\x20\x02\0\0\xe1\x01\0\0\x7c\x04\0\0\x0f\x40\x01\0\
+\x30\x02\0\0\xe1\x01\0\0\xa0\x04\0\0\x10\x54\x01\0\x38\x02\0\0\xe1\x01\0\0\xa0\
+\x04\0\0\x06\x54\x01\0\x60\x02\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\x02\
+\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x78\x02\0\0\xe1\x01\0\0\xf6\x04\0\0\
+\x0d\xbc\0\0\x88\x02\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\x02\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x98\x02\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xb0\x02\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\x02\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xc8\x02\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\x02\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x02\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xe8\x02\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x03\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x0a\xbc\0\0\x10\x03\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x20\
+\x03\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\x03\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x38\x03\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x03\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x03\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x60\x03\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\x03\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x80\x03\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x88\x03\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x03\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xa0\x03\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\x03\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x03\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\
+\x03\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\x03\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xe8\x03\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\x03\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x04\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\
+\x08\x04\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x04\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x30\x04\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\x04\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\x04\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x58\x04\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x04\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x04\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\
+\x04\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x04\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xa0\x04\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\x04\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x04\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xc0\x04\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\x04\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xe0\x04\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\x04\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\x05\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x08\x05\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x05\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x20\x05\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\
+\x05\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x05\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x50\x05\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x05\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\x05\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x78\x05\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x05\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x88\x05\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x05\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x05\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xc0\x05\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\x05\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\x05\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\
+\x05\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x05\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\0\x06\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x06\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x20\x06\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x28\x06\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x06\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x40\x06\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x06\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x06\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x70\x06\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\x06\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x88\x06\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\
+\x06\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x06\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xa8\x06\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x06\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\x06\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xe0\x06\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\x06\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xf8\x06\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x07\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x08\x07\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x20\x07\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x30\x07\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x40\x07\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\
+\x07\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x07\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x60\x07\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x07\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x07\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x90\x07\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa0\x07\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xa8\x07\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x07\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x07\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xc8\x07\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x07\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\x07\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\
+\x08\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x08\x08\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x18\x08\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x08\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\x08\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x40\x08\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x50\x08\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x60\x08\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\x08\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\x08\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x80\x08\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x88\x08\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x08\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\
+\x08\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\x08\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xc8\x08\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\x08\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x08\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xe8\x08\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x09\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x10\x09\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x20\x09\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\x09\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x38\x09\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x09\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x09\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\
+\x09\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\x09\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x80\x09\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x88\x09\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x09\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xa0\x09\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\x09\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xc0\x09\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\x09\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\x09\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xe8\x09\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\x09\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\0\x0a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x08\
+\x0a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x0a\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x30\x0a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\x0a\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\x0a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x58\x0a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x0a\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x68\x0a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x0a\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x0a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xa0\x0a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\x0a\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x0a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\
+\x0a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\x0a\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xe0\x0a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\x0a\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\x0b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\
+\x08\x0b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x0b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x20\x0b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\x0b\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x0b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x50\x0b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x0b\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x68\x0b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\
+\x0b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x0b\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x88\x0b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x0b\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x0b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xc0\x0b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\x0b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xd8\x0b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x0b\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x0b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\0\x0c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x0c\0\0\xe1\x01\0\0\
+\xcc\x04\0\0\x17\xb8\0\0\x20\x0c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\
+\x0c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x0c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x40\x0c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x0c\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x0c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x70\x0c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\x0c\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x88\x0c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x0c\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x0c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xa8\x0c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x0c\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\x0c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\
+\x0c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\x0c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xf8\x0c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x0d\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x08\x0d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x20\x0d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x30\x0d\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x40\x0d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\x0d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x0d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x60\x0d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x0d\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x80\x0d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\
+\x0d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x98\x0d\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xa0\x0d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\x0d\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x0d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xc0\x0d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x0d\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xf0\x0d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\x0e\0\0\
+\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x08\x0e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x10\x0e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x0e\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x20\x0e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\
+\x0e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x48\x0e\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x58\x0e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x60\x0e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x68\x0e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x70\x0e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x78\x0e\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x90\x0e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\x0e\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xb0\x0e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xb8\x0e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc0\x0e\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xc8\x0e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\
+\x0e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x0e\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xf8\x0e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x08\x0f\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x10\x0f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x18\x0f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x0f\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x28\x0f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x0f\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x50\x0f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x60\x0f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\x0f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x70\x0f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\
+\x0f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x80\x0f\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x98\x0f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\x0f\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xb8\x0f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xc0\x0f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc8\x0f\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xd0\x0f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\x0f\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\x0f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\0\x10\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\x10\0\0\xe1\x01\0\0\
+\xcc\x04\0\0\x08\xb8\0\0\x18\x10\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\
+\x10\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\x10\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x30\x10\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x10\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x58\x10\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x68\x10\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x70\x10\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x78\x10\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x10\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x88\x10\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xa0\x10\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x10\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xc0\x10\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\
+\x10\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd0\x10\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xd8\x10\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\x10\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x10\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x08\x11\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x18\x11\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x20\x11\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\x11\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x11\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x38\x11\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x11\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x60\x11\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\
+\x11\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x78\x11\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x80\x11\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\x11\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x90\x11\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xa8\x11\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\x11\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xc8\x11\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\x11\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\x11\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xe0\x11\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x11\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\0\x12\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\
+\x12\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x20\x12\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x28\x12\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\x12\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x12\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x40\x12\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\x12\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x68\x12\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\x12\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x80\x12\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x88\x12\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\x12\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x98\x12\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\
+\x12\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc0\x12\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xd0\x12\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\x12\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe0\x12\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xe8\x12\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\x12\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x08\x13\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\x13\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x28\x13\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x30\x13\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x13\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x40\x13\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\
+\x13\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x13\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x70\x13\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\x13\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x88\x13\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x90\x13\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x13\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xa0\x13\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x13\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc8\x13\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xd8\x13\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\x13\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xe8\x13\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\
+\x13\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf8\x13\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x10\x14\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\x14\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x30\x14\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x38\x14\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x40\x14\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x48\x14\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\x14\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x14\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x78\x14\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\x14\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x90\x14\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\
+\x14\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x14\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xa8\x14\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x14\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\x14\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xe0\x14\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\x14\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xf0\x14\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x14\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\0\x15\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x18\x15\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\x15\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x38\x15\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\
+\x15\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x48\x15\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x50\x15\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\x15\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x15\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x80\x15\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x90\x15\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x98\x15\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\x15\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x15\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xb0\x15\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\x15\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xd8\x15\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\
+\x15\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf0\x15\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xf8\x15\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x16\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x08\x16\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x20\x16\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x30\x16\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x40\x16\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\x16\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x50\x16\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x58\x16\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x60\x16\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x78\x16\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\
+\x16\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x98\x16\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xa0\x16\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\x16\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x16\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xb8\x16\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\x16\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xe0\x16\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\x16\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf8\x16\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\0\x17\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x17\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x1b\xbc\0\0\x10\x17\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\
+\x17\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x38\x17\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x48\x17\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\x17\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x17\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x60\x17\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x17\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x80\x17\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x17\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa0\x17\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xa8\x17\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\x17\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x17\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\
+\x17\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x17\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xe8\x17\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\x17\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\0\x18\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\
+\x08\x18\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x18\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x18\x18\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x18\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x48\x18\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x50\x18\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\x18\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x60\x18\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\
+\x18\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x88\x18\0\0\xe1\x01\0\0\x28\x05\0\
+\0\x22\x40\x03\0\xe0\x18\0\0\xe1\x01\0\0\x5c\x05\0\0\x06\x8c\x02\0\xf8\x18\0\0\
+\xe1\x01\0\0\x5c\x05\0\0\x06\x8c\x02\0\0\x19\0\0\xe1\x01\0\0\x28\x05\0\0\0\x40\
+\x03\0\x30\x19\0\0\xe1\x01\0\0\xb0\x05\0\0\x1a\xa4\x02\0\x48\x19\0\0\xe1\x01\0\
+\0\xf3\x05\0\0\x1a\xa0\x02\0\x60\x19\0\0\xe1\x01\0\0\xb0\x05\0\0\x1a\xa4\x02\0\
+\x70\x19\0\0\xe1\x01\0\0\xf3\x05\0\0\x1a\xa0\x02\0\x88\x19\0\0\xe1\x01\0\0\xb0\
+\x05\0\0\x1a\xa4\x02\0\xa0\x19\0\0\xe1\x01\0\0\xf3\x05\0\0\x1a\xa0\x02\0\xb0\
+\x19\0\0\xe1\x01\0\0\xb0\x05\0\0\x1a\xa4\x02\0\xc8\x19\0\0\xe1\x01\0\0\xf3\x05\
+\0\0\x1a\xa0\x02\0\xd8\x19\0\0\xe1\x01\0\0\x36\x06\0\0\x10\xb0\x02\0\xe0\x19\0\
+\0\xe1\x01\0\0\x36\x06\0\0\x06\xb0\x02\0\xf8\x19\0\0\xe1\x01\0\0\xcc\x04\0\0\
+\x17\xb8\0\0\x18\x1a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\x1a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\x1a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x30\x1a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\x1a\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x50\x1a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\x1a\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x70\x1a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x78\x1a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x1a\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x88\x1a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\
+\x1a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x1a\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xc8\x1a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\x1a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\x1a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xe0\x1a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x1a\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\0\x1b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x1b\0\0\
+\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x20\x1b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x28\x1b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\x1b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x38\x1b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\
+\x1b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\x1b\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x68\x1b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\x1b\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x80\x1b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x88\x1b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\x1b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x98\x1b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x1b\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc0\x1b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xd0\x1b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\x1b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xe0\x1b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\
+\x1b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\x1b\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x08\x1c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\x1c\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x28\x1c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x30\x1c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x1c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x40\x1c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x1c\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x1c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x70\x1c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\x1c\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x88\x1c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\
+\x1c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x1c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xa0\x1c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x1c\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc8\x1c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xd8\x1c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\x1c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xe8\x1c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\x1c\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf8\x1c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x10\x1d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\x1d\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x30\x1d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\
+\x1d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x40\x1d\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x48\x1d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\x1d\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x1d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x78\x1d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\x1d\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x90\x1d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x1d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x1d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xa8\x1d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x1d\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\x1d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\
+\x1d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\x1d\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xf0\x1d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x1d\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\0\x1e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\
+\x18\x1e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\x1e\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x38\x1e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\x1e\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x48\x1e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x50\x1e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\x1e\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x70\x1e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\
+\x1e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x90\x1e\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x98\x1e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\x1e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x1e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xb0\x1e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\x1e\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xd8\x1e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\x1e\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf0\x1e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xf8\x1e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x1f\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x1b\xbc\0\0\x08\x1f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\
+\x1f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x30\x1f\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x40\x1f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\x1f\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x50\x1f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x58\x1f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x60\x1f\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x78\x1f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\x1f\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x98\x1f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xa0\x1f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\x1f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x1f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\
+\x1f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\x1f\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xe0\x1f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\x1f\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf8\x1f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\0\x20\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x20\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x10\x20\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\x20\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x38\x20\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x48\x20\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\x20\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x20\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\
+\x20\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x20\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x80\x20\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x20\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa0\x20\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xa8\x20\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\x20\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xb8\x20\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\x20\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x20\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xe8\x20\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\x20\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\0\x21\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\
+\x21\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x21\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x18\x21\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x21\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x40\x21\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x50\x21\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\x21\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x60\x21\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x21\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x70\x21\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x88\x21\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\x21\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xa8\x21\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\
+\x21\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x21\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xc0\x21\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\x21\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x21\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xf0\x21\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\x22\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x08\x22\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\x22\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x22\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x20\x22\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x22\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x48\x22\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\
+\x22\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x60\x22\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x68\x22\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x22\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x78\x22\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x90\x22\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\x22\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xb0\x22\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\x22\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc0\x22\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xc8\x22\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\x22\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x22\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\
+\x22\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x08\x23\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x10\x23\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x23\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x23\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x28\x23\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x23\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x50\x23\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x23\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\x23\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x70\x23\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x23\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x80\x23\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\
+\x23\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\x23\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xb8\x23\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\x23\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc8\x23\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xd0\x23\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\x23\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xf0\x23\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\x24\0\0\
+\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\x24\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x18\x24\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\x24\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x28\x24\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\
+\x24\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x24\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x58\x24\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x24\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\x24\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x70\x24\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x24\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x80\x24\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x24\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\x24\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xc8\x24\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\x24\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\x24\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\
+\x24\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x24\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\0\x25\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x25\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x28\x25\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x30\x25\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x25\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x40\x25\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x25\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x25\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x70\x25\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\x25\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x88\x25\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\
+\x25\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x25\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xa0\x25\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x25\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc8\x25\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xd8\x25\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\x25\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xe8\x25\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\x25\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf8\x25\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x10\x26\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\x26\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x30\x26\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\
+\x26\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x40\x26\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x48\x26\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\x26\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x26\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x78\x26\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\x26\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x90\x26\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x26\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x26\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xa8\x26\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x26\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\x26\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\
+\x26\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\x26\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xf0\x26\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x26\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\0\x27\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\
+\x18\x27\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\x27\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x38\x27\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\x27\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x48\x27\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x50\x27\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\x27\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x70\x27\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\
+\x27\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x90\x27\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x98\x27\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\x27\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x27\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xb0\x27\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\x27\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xd8\x27\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\x27\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf0\x27\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xf8\x27\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x28\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x1b\xbc\0\0\x08\x28\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\
+\x28\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x30\x28\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x40\x28\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\x28\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x50\x28\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x58\x28\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x60\x28\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x78\x28\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\x28\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x98\x28\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xa0\x28\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\x28\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x28\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\
+\x28\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\x28\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xe0\x28\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\x28\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf8\x28\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\0\x29\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x29\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x10\x29\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\x29\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x38\x29\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x48\x29\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\x29\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x29\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\
+\x29\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x29\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x80\x29\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x29\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa0\x29\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xa8\x29\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\x29\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xb8\x29\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\x29\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x29\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xe8\x29\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\x29\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\0\x2a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\
+\x2a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x2a\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x18\x2a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x2a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x40\x2a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x50\x2a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\x2a\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x60\x2a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x2a\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x70\x2a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x88\x2a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\x2a\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xa8\x2a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\
+\x2a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x2a\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xc0\x2a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\x2a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x2a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xf0\x2a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\x2b\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x08\x2b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\x2b\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x2b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x20\x2b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x2b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x48\x2b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\
+\x2b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x60\x2b\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x68\x2b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x2b\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x78\x2b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x90\x2b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\x2b\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xb0\x2b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\x2b\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc0\x2b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xc8\x2b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\x2b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x2b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\
+\x2b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x08\x2c\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x10\x2c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x2c\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x2c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x28\x2c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x2c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x50\x2c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x2c\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\x2c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x70\x2c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x2c\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x80\x2c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\
+\x2c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\x2c\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xb8\x2c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\x2c\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc8\x2c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xd0\x2c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\x2c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xf0\x2c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\x2d\0\0\
+\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\x2d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x18\x2d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\x2d\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x28\x2d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\
+\x2d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x2d\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x58\x2d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\x2d\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x70\x2d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x78\x2d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x2d\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x88\x2d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x2d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x2d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xc0\x2d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\x2d\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xd0\x2d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\
+\x2d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\x2d\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xf8\x2d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\x2e\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x18\x2e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x20\x2e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\x2e\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x30\x2e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\x2e\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x2e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x60\x2e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\x2e\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x78\x2e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\
+\x2e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\x2e\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x90\x2e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x2e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\x2e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xc8\x2e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\x2e\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xd8\x2e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x2e\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x2e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\0\x2f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x2f\0\0\xe1\x01\0\0\
+\xcc\x04\0\0\x17\xb8\0\0\x18\x2f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\
+\x2f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\x2f\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x30\x2f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\x2f\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x2f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x78\x2f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\x2f\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x90\x2f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x2f\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x2f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xa8\x2f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x2f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\x2f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\
+\x2f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\x2f\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xf0\x2f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x2f\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\0\x30\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\
+\x18\x30\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\x30\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x38\x30\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\x30\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x48\x30\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x50\x30\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\x30\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x70\x30\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\
+\x30\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x90\x30\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x98\x30\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\x30\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x30\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xb0\x30\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\x30\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xd8\x30\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\x30\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf0\x30\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xf8\x30\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x31\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x1b\xbc\0\0\x08\x31\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\
+\x31\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x30\x31\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x40\x31\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\x31\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x50\x31\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x58\x31\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x60\x31\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x78\x31\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\x31\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x98\x31\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xa0\x31\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\x31\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x31\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\
+\x31\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\x31\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xe0\x31\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\x31\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf8\x31\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\0\x32\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x32\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x10\x32\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\x32\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x38\x32\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x48\x32\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\x32\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x32\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\
+\x32\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x32\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x80\x32\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x32\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa0\x32\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xa8\x32\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\x32\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xb8\x32\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\x32\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x32\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xe8\x32\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\x32\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\0\x33\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\
+\x33\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x33\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x18\x33\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x33\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x40\x33\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x50\x33\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\x33\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x60\x33\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x33\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x70\x33\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x88\x33\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\x33\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xa8\x33\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\
+\x33\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x33\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xc0\x33\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\x33\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x33\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xf0\x33\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\x34\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x08\x34\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\x34\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x34\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x20\x34\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x34\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x48\x34\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\
+\x34\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x60\x34\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x68\x34\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x34\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x78\x34\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x90\x34\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\x34\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xb0\x34\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\x34\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc0\x34\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xc8\x34\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\x34\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x34\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\
+\x34\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x08\x35\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x10\x35\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x35\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x35\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x28\x35\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x35\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x50\x35\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x35\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\x35\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x70\x35\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x35\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x80\x35\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\
+\x35\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\x35\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xb8\x35\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\x35\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc8\x35\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xd0\x35\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\x35\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xf0\x35\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\x36\0\0\
+\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\x36\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x18\x36\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\x36\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x28\x36\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\
+\x36\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x36\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x58\x36\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\x36\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x70\x36\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x78\x36\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x36\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x88\x36\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x36\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x36\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xc0\x36\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\x36\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xd0\x36\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\
+\x36\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\x36\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xf8\x36\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\x37\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x18\x37\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x20\x37\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\x37\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x30\x37\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\x37\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x37\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x60\x37\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\x37\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x78\x37\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\
+\x37\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\x37\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x90\x37\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x37\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\x37\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xc8\x37\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\x37\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xd8\x37\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x37\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x37\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\0\x38\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x38\0\0\xe1\x01\0\0\
+\xcc\x04\0\0\x17\xb8\0\0\x20\x38\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\
+\x38\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\x38\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x38\x38\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\x38\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\x38\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x68\x38\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\x38\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x80\x38\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\x38\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\x38\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x98\x38\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x38\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xc0\x38\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\
+\x38\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\x38\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xe0\x38\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x38\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\x38\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x08\x39\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\x39\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x28\x39\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\x39\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x39\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x40\x39\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x39\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x60\x39\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\
+\x39\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\x39\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x88\x39\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\x39\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x39\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xa0\x39\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x39\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xd0\x39\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\x39\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\x39\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xe8\x39\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\x39\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xf8\x39\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\
+\x3a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x30\x3a\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x40\x3a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\x3a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x50\x3a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x58\x3a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x60\x3a\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x78\x3a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\x3a\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x98\x3a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xa0\x3a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\x3a\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x3a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\
+\x3a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\x3a\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xe0\x3a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\x3a\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf8\x3a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\0\x3b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x3b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x10\x3b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\x3b\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x38\x3b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x48\x3b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\x3b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x3b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\
+\x3b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x3b\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x80\x3b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x3b\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa0\x3b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xa8\x3b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\x3b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xb8\x3b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\x3b\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x3b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xe8\x3b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\x3b\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\0\x3c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\
+\x3c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x3c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x18\x3c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x3c\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x40\x3c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x50\x3c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\x3c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x60\x3c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x3c\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x70\x3c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x88\x3c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\x3c\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xa8\x3c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\
+\x3c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x3c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xc0\x3c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\x3c\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x3c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xf0\x3c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\x3d\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x08\x3d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\x3d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x3d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x20\x3d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x3d\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x48\x3d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\
+\x3d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x60\x3d\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x68\x3d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x3d\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x78\x3d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x90\x3d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\x3d\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xb0\x3d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\x3d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc0\x3d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xc8\x3d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\x3d\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x3d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\
+\x3d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x08\x3e\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x10\x3e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x3e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x3e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x28\x3e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x3e\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x50\x3e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x3e\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\x3e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x70\x3e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x3e\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x80\x3e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\
+\x3e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\x3e\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xb8\x3e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\x3e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc8\x3e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xd0\x3e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\x3e\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xf0\x3e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\x3f\0\0\
+\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\x3f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x18\x3f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\x3f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x28\x3f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\
+\x3f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x3f\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x58\x3f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\x3f\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x70\x3f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x78\x3f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x3f\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x88\x3f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x3f\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x3f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xc0\x3f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\x3f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xd0\x3f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\
+\x3f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\x3f\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xf8\x3f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\x40\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x18\x40\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x20\x40\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\x40\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x30\x40\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\x40\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x40\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x60\x40\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\x40\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x78\x40\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\
+\x40\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\x40\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x90\x40\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x40\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\x40\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xc8\x40\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\x40\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xd8\x40\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x40\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x40\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\0\x41\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x41\0\0\xe1\x01\0\0\
+\xcc\x04\0\0\x17\xb8\0\0\x20\x41\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\
+\x41\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\x41\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x38\x41\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\x41\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\x41\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x68\x41\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\x41\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x80\x41\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\x41\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\x41\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x98\x41\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x41\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xc0\x41\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\
+\x41\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\x41\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xe0\x41\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x41\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\x41\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x08\x42\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\x42\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x28\x42\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\x42\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x42\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x40\x42\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x42\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x60\x42\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\
+\x42\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\x42\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x88\x42\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\x42\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x42\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xa0\x42\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x42\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xc8\x42\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\x42\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\x42\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xe8\x42\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\x42\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xf8\x42\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\
+\x43\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\x43\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x30\x43\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\x43\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x40\x43\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x48\x43\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\x43\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x68\x43\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\x43\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\x43\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x90\x43\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x43\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x43\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\
+\x43\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x43\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xd0\x43\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\x43\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\x43\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xf0\x43\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x43\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\0\x44\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x44\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\x44\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x38\x44\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\x44\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x48\x44\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\
+\x44\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\x44\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x70\x44\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\x44\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\x44\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x90\x44\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x44\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xa0\x44\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\x44\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x44\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xe0\x44\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\x44\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xf8\x44\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\0\
+\x45\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x45\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x10\x45\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\x45\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x38\x45\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x48\x45\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\x45\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x58\x45\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x45\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x45\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x80\x45\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x45\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xa0\x45\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\
+\x45\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\x45\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xb8\x45\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\x45\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x45\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xe8\x45\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\x45\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\0\x46\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\x46\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x46\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x18\x46\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x46\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x40\x46\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x50\
+\x46\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\x46\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x60\x46\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x46\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x70\x46\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x88\x46\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\x46\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xa8\x46\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\x46\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x46\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xc0\x46\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\x46\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x46\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\
+\x46\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\x47\0\0\xe1\x01\0\0\xcc\x04\0\0\
+\x08\xb8\0\0\x08\x47\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\x47\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x47\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x20\x47\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x47\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x48\x47\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\x47\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x60\x47\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x68\x47\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x47\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x78\x47\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\
+\x47\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\x47\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xb0\x47\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\x47\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc0\x47\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xc8\x47\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\x47\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xe8\x47\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\x47\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x08\x48\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x10\x48\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x48\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x20\x48\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\
+\x48\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x48\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x50\x48\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x48\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\x48\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x70\x48\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x48\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x80\x48\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x48\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\x48\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xb8\x48\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\x48\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xc8\x48\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\
+\x48\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\x48\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xf0\x48\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\x49\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\x49\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x18\x49\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\x49\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x28\x49\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\x49\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x49\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x58\x49\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\x49\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x70\x49\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\
+\x49\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x49\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x88\x49\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x49\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x49\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xc0\x49\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\x49\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xd0\x49\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x49\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\x49\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xf8\x49\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\x4a\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x18\x4a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\
+\x4a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\x4a\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x30\x4a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\x4a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x4a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x60\x4a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\x4a\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x78\x4a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\x4a\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\x4a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x90\x4a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x4a\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\x4a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc8\
+\x4a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\x4a\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xd8\x4a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x4a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x4a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\0\x4b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x4b\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x20\x4b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\x4b\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\x4b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x38\x4b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\x4b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x58\x4b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x68\
+\x4b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\x4b\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x80\x4b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\x4b\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\x4b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x98\x4b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x4b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xc0\x4b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\x4b\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\x4b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xe0\x4b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x4b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\x4b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\
+\x4c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\x4c\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x28\x4c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\x4c\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x4c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x40\x4c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x4c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x60\x4c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\x4c\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\x4c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x88\x4c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\x4c\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x98\x4c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\
+\x4c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x4c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xc8\x4c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\x4c\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\x4c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xe8\x4c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\x4c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xf8\x4c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x4d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\x4d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x30\x4d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\x4d\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x40\x4d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\
+\x4d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\x4d\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x68\x4d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\x4d\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\x4d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x90\x4d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x4d\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xa0\x4d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\x4d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x4d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xd0\x4d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\x4d\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xe8\x4d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\
+\x4d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x4d\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\0\x4e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x4e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\x4e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x38\x4e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\x4e\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x48\x4e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x4e\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\x4e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x70\x4e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\x4e\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x90\x4e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\
+\x4e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\x4e\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xa8\x4e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\x4e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\x4e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xd8\x4e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\x4e\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xf0\x4e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\x4e\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x4f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x08\x4f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x4f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x30\x4f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x38\
+\x4f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\x4f\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x48\x4f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x4f\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\x4f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x70\x4f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x4f\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xa0\x4f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\x4f\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\x4f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xb8\x4f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\x4f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x4f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe8\
+\x4f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\x4f\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\0\x50\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\x50\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x50\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x18\x50\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x50\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x40\x50\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x50\x50\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\x50\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x60\x50\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x50\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x70\x50\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\
+\x50\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\x50\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xa8\x50\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\x50\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x50\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xc0\x50\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\x50\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xe0\x50\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\x50\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\x51\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x08\x51\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\x51\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x18\x51\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x20\
+\x51\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x51\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x48\x51\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\x51\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x60\x51\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x68\x51\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x51\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x78\x51\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\x51\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\x51\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xb0\x51\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\x51\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xc0\x51\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\
+\x51\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\x51\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xe8\x51\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\x51\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x08\x52\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x10\x52\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x52\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x20\x52\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\x52\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x52\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x50\x52\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x52\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x68\x52\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x70\
+\x52\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x52\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x80\x52\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x52\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\x52\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xb8\x52\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\x52\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xc8\x52\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\x52\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\x52\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xf0\x52\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\x53\0\0\xe1\x01\0\0\
+\xcc\x04\0\0\x17\xb8\0\0\x10\x53\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x18\
+\x53\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\x53\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x28\x53\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\x53\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x53\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x58\x53\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\x53\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x70\x53\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\x53\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x53\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x88\x53\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x53\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x53\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\
+\x53\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\x53\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xd0\x53\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x53\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\x53\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xf8\x53\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\x54\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x18\x54\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\x54\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\x54\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x30\x54\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\x54\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x50\x54\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x60\
+\x54\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\x54\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x78\x54\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\x54\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\x54\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x90\x54\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x54\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xb8\x54\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc8\x54\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\x54\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xd8\x54\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x54\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x54\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\
+\x55\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x55\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x20\x55\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\x55\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\x55\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x38\x55\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\x55\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x58\x55\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x68\x55\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\x55\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x80\x55\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\x55\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x90\x55\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x98\
+\x55\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x55\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xc0\x55\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\x55\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\x55\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xe0\x55\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x55\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xf0\x55\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x56\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\x56\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x28\x56\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\x56\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x56\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\
+\x56\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x56\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x60\x56\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\x56\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\x56\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x88\x56\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\x56\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x98\x56\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\x56\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x56\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xc8\x56\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\x56\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xe0\x56\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe8\
+\x56\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\x56\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xf8\x56\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x57\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\x57\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x30\x57\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\x57\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x40\x57\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x57\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\x57\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x68\x57\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\x57\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x88\x57\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x90\
+\x57\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x57\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xa0\x57\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\x57\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x57\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xd0\x57\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\x57\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xe8\x57\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\x57\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x57\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\0\x58\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x58\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x0a\xbc\0\0\x28\x58\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x38\
+\x58\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\x58\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x48\x58\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x58\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\x58\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x70\x58\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\x58\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x90\x58\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\x58\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\x58\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xa8\x58\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\x58\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xc8\x58\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd8\
+\x58\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\x58\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xf0\x58\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\x58\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x59\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\
+\x08\x59\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x59\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x30\x59\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\x59\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\x59\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x50\x59\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\x59\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x60\x59\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\
+\x59\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\x59\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x98\x59\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa0\x59\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\x59\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xb0\x59\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\x59\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xd0\x59\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe0\x59\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\x59\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xf0\x59\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\x59\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\0\x5a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x08\
+\x5a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x5a\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x40\x5a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x50\x5a\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\x5a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x60\x5a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x5a\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x70\x5a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\x5a\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\x5a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xb0\x5a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\x5a\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xc0\x5a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\
+\x5a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\x5a\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xe8\x5a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\x5a\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x08\x5b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x10\x5b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x5b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x20\x5b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\x5b\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x5b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x50\x5b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x5b\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x68\x5b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x70\
+\x5b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x5b\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x80\x5b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x5b\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\x5b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xb8\x5b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\x5b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xc8\x5b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\x5b\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\x5b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xf0\x5b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\x5c\0\0\xe1\x01\0\0\
+\xcc\x04\0\0\x17\xb8\0\0\x10\x5c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x18\
+\x5c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\x5c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x28\x5c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\x5c\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x5c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x58\x5c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\x5c\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x70\x5c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\x5c\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x5c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x88\x5c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x5c\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x5c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\
+\x5c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\x5c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xd0\x5c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x5c\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\x5c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xf8\x5c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\x5d\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x18\x5d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\x5d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\x5d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x30\x5d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\x5d\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x50\x5d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x60\
+\x5d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\x5d\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x78\x5d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\x5d\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\x5d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x90\x5d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x5d\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xb8\x5d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc8\x5d\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\x5d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xd8\x5d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x5d\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x5d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\
+\x5e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x5e\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x20\x5e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\x5e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\x5e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x38\x5e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\x5e\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x58\x5e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x68\x5e\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\x5e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x80\x5e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\x5e\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x90\x5e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x98\
+\x5e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x5e\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xc0\x5e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\x5e\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\x5e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xe0\x5e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x5e\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xf0\x5e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x5f\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\x5f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x28\x5f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\x5f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x5f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\
+\x5f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x5f\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x60\x5f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\x5f\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\x5f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x88\x5f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\x5f\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x98\x5f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\x5f\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x5f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xc8\x5f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\x5f\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xe0\x5f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe8\
+\x5f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\x5f\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xf8\x5f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x60\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\x60\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x30\x60\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\x60\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x40\x60\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x60\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\x60\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x68\x60\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\x60\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x88\x60\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x90\
+\x60\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x60\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xa0\x60\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\x60\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x60\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xd0\x60\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\x60\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xe8\x60\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\x60\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x60\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\0\x61\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x61\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x0a\xbc\0\0\x28\x61\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x38\
+\x61\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\x61\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x48\x61\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x61\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\x61\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x70\x61\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\x61\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x90\x61\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\x61\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\x61\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xa8\x61\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\x61\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xc8\x61\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd8\
+\x61\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\x61\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xf0\x61\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\x61\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x62\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\
+\x08\x62\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x62\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x30\x62\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\x62\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\x62\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x50\x62\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\x62\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x60\x62\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\
+\x62\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\x62\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x98\x62\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa0\x62\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\x62\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xb0\x62\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\x62\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xd0\x62\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe0\x62\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\x62\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xf8\x62\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\0\x63\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x19\xbc\0\0\x08\x63\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x10\
+\x63\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\x63\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x38\x63\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x48\x63\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\x63\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x58\x63\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x63\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x68\x63\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x63\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x63\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xa0\x63\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\x63\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\x63\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\
+\x63\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\x63\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xd8\x63\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe8\x63\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\x63\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\0\x64\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\x64\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x10\x64\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x18\x64\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x64\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x40\x64\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x50\x64\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x58\x64\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x60\
+\x64\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x64\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x70\x64\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\x64\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\x64\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xa0\x64\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\x64\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xb0\x64\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x64\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\x64\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xd8\x64\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\x64\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\0\x65\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x08\
+\x65\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\x65\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x18\x65\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x20\x65\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x65\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x48\x65\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\x65\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x60\x65\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x68\x65\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x65\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x78\x65\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\x65\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\x65\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xb0\
+\x65\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\x65\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xc0\x65\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\x65\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\x65\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xe8\x65\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\x65\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x08\x66\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x10\x66\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x66\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x20\x66\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\x66\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x40\x66\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x50\
+\x66\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x66\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x68\x66\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x70\x66\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x66\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x80\x66\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x66\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xa8\x66\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xb8\x66\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\x66\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xc8\x66\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\x66\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\x66\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\
+\x66\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\x67\0\0\xe1\x01\0\0\xcc\x04\0\0\
+\x17\xb8\0\0\x10\x67\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x18\x67\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\x67\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x28\x67\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\x67\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x48\x67\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x58\x67\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\x67\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x70\x67\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\x67\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x80\x67\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x88\
+\x67\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x67\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xb0\x67\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\x67\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\x67\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xd0\x67\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x67\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xe0\x67\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x67\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\x68\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x18\x68\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\x68\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x28\x68\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\
+\x68\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\x68\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x50\x68\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x60\x68\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\x68\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x78\x68\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\x68\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x88\x68\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x90\x68\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x68\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xb8\x68\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc8\x68\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xd0\x68\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\
+\x68\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x68\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xe8\x68\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x69\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x69\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x20\x69\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\x69\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x30\x69\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x69\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\x69\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x58\x69\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x68\x69\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x78\x69\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x80\
+\x69\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\x69\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x90\x69\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x98\x69\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x69\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xc0\x69\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\x69\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xd8\x69\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe0\x69\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x69\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xf0\x69\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x6a\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x18\x6a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x28\
+\x6a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\x6a\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x38\x6a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x6a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x6a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x60\x6a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\x6a\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x80\x6a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x88\x6a\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\x6a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x98\x6a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\x6a\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x6a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc8\
+\x6a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\x6a\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xe0\x6a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe8\x6a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\x6a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xf8\x6a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x6b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x20\x6b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x30\x6b\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\x6b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x40\x6b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x6b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x50\x6b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\
+\x6b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\x6b\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x88\x6b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x90\x6b\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x6b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xa0\x6b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\x6b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xc0\x6b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\x6b\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\x6b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xe8\x6b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\x6b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x6b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\0\
+\x6c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x6c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x28\x6c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x38\x6c\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\x6c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x48\x6c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x6c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x58\x6c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x6c\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\x6c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x90\x6c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\x6c\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\x6c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\
+\x6c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\x6c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xc8\x6c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd8\x6c\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\x6c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xf0\x6c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\x6c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\0\x6d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x08\x6d\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x6d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x30\x6d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\x6d\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x48\x6d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x50\
+\x6d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\x6d\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x60\x6d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x6d\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\x6d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x98\x6d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa0\x6d\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xa8\x6d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x6d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\x6d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xd0\x6d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe0\x6d\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xf0\x6d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf8\
+\x6d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\0\x6e\0\0\xe1\x01\0\0\xf6\x04\0\0\
+\x19\xbc\0\0\x08\x6e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x10\x6e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\x6e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x38\x6e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x48\x6e\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x50\x6e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x6e\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x6e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x68\x6e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x6e\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x6e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa0\
+\x6e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\x6e\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xb0\x6e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x6e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\x6e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xd8\x6e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe8\x6e\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xf8\x6e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\0\x6f\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\x6f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x10\x6f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x18\x6f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x30\x6f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x50\
+\x6f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\x6f\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x60\x6f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x68\x6f\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x6f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x78\x6f\0\0\xe1\x01\0\0\0\0\0\0\0\0\0\0\xb0\x6f\0\0\xe1\x01\0\0\x62\x06\0\0\
+\x0f\xec\0\0\xb8\x6f\0\0\xe1\x01\0\0\x62\x06\0\0\x18\xec\0\0\xc0\x6f\0\0\xe1\
+\x01\0\0\x9f\x06\0\0\x1d\x64\x01\0\xc8\x6f\0\0\xe1\x01\0\0\xbe\x06\0\0\x24\x68\
+\x01\0\xe0\x6f\0\0\xe1\x01\0\0\x04\x07\0\0\x0e\x7c\x01\0\xe8\x6f\0\0\xe1\x01\0\
+\0\x04\x07\0\0\x12\x7c\x01\0\0\x70\0\0\xe1\x01\0\0\x04\x07\0\0\x0e\x7c\x01\0\
+\x08\x70\0\0\xe1\x01\0\0\x1a\x07\0\0\x07\x80\x01\0\x30\x70\0\0\xe1\x01\0\0\x1a\
+\x07\0\0\x07\x80\x01\0\x50\x70\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\x70\
+\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x70\x70\0\0\xe1\x01\0\0\xf6\x04\0\0\
+\x0d\xbc\0\0\x78\x70\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x70\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x88\x70\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xa8\x70\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xb8\x70\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xc0\x70\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc8\x70\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\x70\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xd8\x70\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\x70\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\0\x71\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\
+\x71\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x18\x71\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x20\x71\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\x71\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\x71\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x48\x71\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x58\x71\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x68\x71\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x70\x71\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\x71\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x80\x71\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x88\x71\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x71\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\
+\x71\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\x71\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xc8\x71\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd0\x71\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x71\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xe0\x71\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x71\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x08\x72\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x18\x72\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\x72\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x28\x72\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x72\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x38\x72\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\
+\x72\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x60\x72\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x70\x72\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x78\x72\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\x72\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x88\x72\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x90\x72\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xa8\x72\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\x72\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc8\x72\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xd0\x72\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\x72\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x72\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\
+\x72\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x73\0\0\xe1\x01\0\0\xf6\x04\0\0\
+\x0a\xbc\0\0\x10\x73\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x20\x73\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\x73\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x30\x73\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x73\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x40\x73\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\x73\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x68\x73\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x78\x73\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x80\x73\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x88\x73\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\
+\x73\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x98\x73\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xb0\x73\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc0\x73\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\x73\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xd8\x73\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe0\x73\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xe8\x73\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\x73\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x74\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x18\x74\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x28\x74\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x30\x74\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\
+\x74\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x74\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x48\x74\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x74\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\x74\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x80\x74\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x88\x74\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x90\x74\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x74\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\x74\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xb8\x74\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc8\x74\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xd8\x74\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\
+\x74\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe8\x74\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xf0\x74\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf8\x74\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x75\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x20\x75\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x30\x75\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x38\x75\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x40\x75\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x75\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x50\x75\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x75\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x78\x75\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\
+\x75\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x90\x75\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x98\x75\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x75\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\x75\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xc0\x75\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\x75\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xe0\x75\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\x75\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\x75\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xf8\x75\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\0\x76\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x19\xbc\0\0\x18\x76\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\
+\x76\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x38\x76\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x40\x76\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x48\x76\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x76\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x58\x76\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x76\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x80\x76\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x90\x76\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\x76\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xa0\x76\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x76\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\x76\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\
+\x76\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd8\x76\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xe8\x76\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf0\x76\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\x76\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\0\x77\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x08\x77\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x20\x77\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x30\x77\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\x77\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x48\x77\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x50\x77\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x58\x77\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x60\
+\x77\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x77\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x88\x77\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x98\x77\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa0\x77\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xa8\x77\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x77\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xb8\x77\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\x77\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe0\x77\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xf0\x77\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf8\x77\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\0\x78\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\
+\x78\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x10\x78\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x28\x78\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x38\x78\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x48\x78\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x50\x78\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x78\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x60\x78\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x78\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x78\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x90\x78\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa0\x78\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xa8\x78\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\
+\x78\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x78\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xc0\x78\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x78\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe8\x78\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xf8\x78\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\0\x79\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x08\x79\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x79\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x18\x79\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x30\x79\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x40\x79\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x50\x79\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\
+\x79\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x60\x79\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x68\x79\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x70\x79\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\x79\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x98\x79\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa8\x79\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xb0\x79\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x79\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x79\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xc8\x79\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x79\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\x79\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\
+\x7a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x08\x7a\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x10\x7a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x7a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x20\x7a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x38\x7a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x48\x7a\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x58\x7a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x60\x7a\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x68\x7a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x70\x7a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x78\x7a\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x90\x7a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\
+\x7a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa8\x7a\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xb0\x7a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x7a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x7a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xc8\x7a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x7a\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\0\x7b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\x7b\0\0\
+\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x18\x7b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x20\x7b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\x7b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x30\x7b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\
+\x7b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x58\x7b\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x68\x7b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x70\x7b\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\x7b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x80\x7b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x88\x7b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xa0\x7b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x7b\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\x7b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xc8\x7b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd0\x7b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x7b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\
+\x7b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x7b\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x08\x7c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x18\x7c\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\x7c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x28\x7c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x7c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x38\x7c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x7c\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x60\x7c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x70\x7c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x78\x7c\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x80\x7c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\
+\x7c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x90\x7c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xa8\x7c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\x7c\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc8\x7c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xd0\x7c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\x7c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xe0\x7c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x7c\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x7d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x10\x7d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x20\x7d\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x28\x7d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\
+\x7d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x7d\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x40\x7d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\x7d\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x68\x7d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x78\x7d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x80\x7d\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x88\x7d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\x7d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x98\x7d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xb0\x7d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc0\x7d\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xd0\x7d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\
+\x7d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe0\x7d\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xe8\x7d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\x7d\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x7e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x18\x7e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x28\x7e\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x30\x7e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x7e\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x7e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x48\x7e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x7e\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x70\x7e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\
+\x7e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x88\x7e\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x90\x7e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x7e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\x7e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xb8\x7e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc8\x7e\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xd8\x7e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\x7e\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe8\x7e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xf0\x7e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf8\x7e\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x10\x7f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\
+\x7f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x30\x7f\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x38\x7f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x40\x7f\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\x7f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x50\x7f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x7f\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x78\x7f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\x7f\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x90\x7f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x98\x7f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x7f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\x7f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\
+\x7f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\x7f\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xe0\x7f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\x7f\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\x7f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xf8\x7f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\0\x80\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x18\x80\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\x80\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x38\x80\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x40\x80\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x48\x80\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x50\x80\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\
+\x80\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x80\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x80\x80\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x90\x80\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\x80\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xa0\x80\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x80\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xb0\x80\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\x80\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd8\x80\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xe8\x80\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf0\x80\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\x80\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\
+\x81\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x08\x81\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x20\x81\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x30\x81\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\x81\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x48\x81\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x50\x81\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x58\x81\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x60\x81\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x81\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x88\x81\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x98\x81\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xa0\x81\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\
+\x81\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x81\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xb8\x81\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\x81\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe0\x81\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xf0\x81\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf8\x81\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\0\x82\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x82\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x10\x82\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x28\x82\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x38\x82\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x48\x82\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\
+\x82\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x82\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x60\x82\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x82\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x82\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x90\x82\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa0\x82\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xa8\x82\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\x82\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x82\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xc0\x82\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x82\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xe8\x82\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\
+\x82\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\0\x83\0\0\xe1\x01\0\0\xf6\x04\0\0\
+\x0d\xbc\0\0\x08\x83\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x83\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x18\x83\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x30\x83\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x40\x83\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x50\x83\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\x83\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x60\x83\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x68\x83\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x70\x83\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x88\x83\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\
+\x83\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa8\x83\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xb0\x83\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x83\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x83\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xc8\x83\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x83\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xf0\x83\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\x84\0\0\
+\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x08\x84\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x10\x84\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x84\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x20\x84\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\
+\x84\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x48\x84\0\0\xe1\x01\0\0\0\0\0\0\0\
+\0\0\0\x50\x84\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x84\0\0\xe1\x01\0\0\
+\xcc\x04\0\0\x08\xb8\0\0\x68\x84\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x70\
+\x84\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x84\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x80\x84\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x84\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\x84\0\0\xe1\x01\0\0\0\0\0\0\0\0\0\0\xb8\
+\x84\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc8\x84\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xd0\x84\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\x84\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x84\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xe8\x84\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x85\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x10\x85\0\0\xe1\x01\0\0\0\0\0\0\0\0\0\0\x18\x85\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x28\x85\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x30\x85\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x85\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x40\x85\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x85\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x85\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x70\x85\0\0\xe1\x01\0\0\0\0\0\0\0\0\0\0\x78\x85\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x80\x85\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x88\x85\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\x85\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x98\x85\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\x85\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x85\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\
+\x85\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\x85\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xe8\x85\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\x85\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x85\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\0\x86\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x86\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x28\x86\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x38\x86\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\x86\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x48\x86\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x86\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x58\x86\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\
+\x86\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\x86\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x90\x86\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\x86\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\x86\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xa8\x86\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\x86\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xc8\x86\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd8\x86\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\x86\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xf0\x86\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\x86\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\0\x87\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x08\
+\x87\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x87\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x30\x87\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\x87\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\x87\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x50\x87\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\x87\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x60\x87\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\x87\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\x87\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x98\x87\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa0\x87\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\x87\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\
+\x87\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\x87\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xd0\x87\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe0\x87\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\x87\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xf8\x87\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\0\x88\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x08\x88\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x10\x88\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\x88\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x38\x88\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x48\x88\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x50\x88\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x58\
+\x88\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x88\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x68\x88\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x88\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x88\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xa0\x88\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\x88\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xb0\x88\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x88\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\x88\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xd8\x88\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe8\x88\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xf8\x88\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\0\
+\x89\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\x89\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x10\x89\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x18\x89\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x89\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x40\x89\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x50\x89\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x58\x89\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x60\x89\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x89\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x70\x89\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\x89\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x98\x89\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa8\
+\x89\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\x89\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xb8\x89\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x89\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\x89\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xe0\x89\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\x89\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\0\x8a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x08\x8a\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\x8a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x18\x8a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x20\x8a\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x38\x8a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x48\
+\x8a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\x8a\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x60\x8a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x68\x8a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x8a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x78\x8a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\x8a\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xa0\x8a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xb0\x8a\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\x8a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xc0\x8a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\x8a\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\x8a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\
+\x8a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\x8a\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x08\x8b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x10\x8b\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x8b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x20\x8b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\x8b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x40\x8b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x50\x8b\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x8b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x68\x8b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x70\x8b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x78\x8b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x80\
+\x8b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\x8b\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xa8\x8b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xb8\x8b\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\x8b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xc8\x8b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\x8b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xd8\x8b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\x8b\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\x8c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x10\x8c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x18\x8c\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x20\x8c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\
+\x8c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\x8c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x48\x8c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x58\x8c\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\x8c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x70\x8c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\x8c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x80\x8c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x88\x8c\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x8c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xb0\x8c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\x8c\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xc8\x8c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd0\
+\x8c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x8c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xe0\x8c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\x8c\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\x8d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x18\x8d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\x8d\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x28\x8d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x8d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\x8d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x50\x8d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x60\x8d\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x70\x8d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x78\
+\x8d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\x8d\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x88\x8d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x90\x8d\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x8d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xb8\x8d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc8\x8d\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xd0\x8d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\x8d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x8d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xe8\x8d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x8e\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x0a\xbc\0\0\x10\x8e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x20\
+\x8e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\x8e\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x30\x8e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x8e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\x8e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x58\x8e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x68\x8e\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x78\x8e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x80\x8e\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\x8e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x90\x8e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x98\x8e\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xb0\x8e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc0\
+\x8e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\x8e\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xd8\x8e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe0\x8e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x8e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xf0\x8e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x8f\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x18\x8f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x28\x8f\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\x8f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x38\x8f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x8f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x8f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\
+\x8f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\x8f\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x80\x8f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x88\x8f\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\x8f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x98\x8f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\x8f\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xb8\x8f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc8\x8f\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\x8f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xe0\x8f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe8\x8f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xf0\x8f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf8\
+\x8f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x90\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x20\x90\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x28\x90\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\x90\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x38\x90\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x90\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x48\x90\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x90\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\x90\0\0\xe1\x01\0\0\x46\x07\0\0\x1c\
+\xc0\x02\0\x98\x90\0\0\xe1\x01\0\0\x7d\x07\0\0\x03\xec\x01\0\xb0\x90\0\0\xe1\
+\x01\0\0\x90\x07\0\0\x25\xd0\x02\0\xd0\x90\0\0\xe1\x01\0\0\0\0\0\0\0\0\0\0\xd8\
+\x90\0\0\xe1\x01\0\0\xd0\x07\0\0\x07\xe4\x02\0\xf8\x90\0\0\xe1\x01\0\0\xd0\x07\
+\0\0\x07\xe4\x02\0\x18\x91\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x30\x91\0\0\
+\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\x91\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x48\x91\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\x91\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x58\x91\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\
+\x91\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\x91\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x90\x91\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\x91\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\x91\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xb0\x91\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\x91\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xd8\x91\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\x91\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\0\x92\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x10\x92\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x92\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x20\x92\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\
+\x92\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x48\x92\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x60\x92\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\x92\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\x92\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x80\x92\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x88\x92\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xa0\x92\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x92\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\x92\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xc8\x92\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\x92\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x92\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\
+\x92\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x93\0\0\xe1\x01\0\0\xf6\x04\0\0\
+\x0a\xbc\0\0\x10\x93\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x20\x93\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\x93\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x38\x93\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x93\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x48\x93\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x93\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\x93\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x80\x93\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x88\x93\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x93\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\
+\x93\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\x93\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xc0\x93\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\x93\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\x93\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xe8\x93\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\x93\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\0\x94\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x08\x94\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x94\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x30\x94\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\x94\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x48\x94\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x58\
+\x94\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x94\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x68\x94\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x94\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x94\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xa0\x94\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\x94\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xb8\x94\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x94\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\x94\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xe0\x94\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\x94\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\0\x95\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x08\
+\x95\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x95\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x20\x95\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\x95\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x95\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x50\x95\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x95\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x68\x95\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\x95\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x95\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x88\x95\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x95\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x95\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\
+\x95\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\x95\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xd8\x95\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x95\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x95\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\0\x96\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x96\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x20\x96\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\x96\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x96\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x40\x96\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x96\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x60\x96\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\
+\x96\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\x96\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x88\x96\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\x96\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x96\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xa8\x96\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x96\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xd0\x96\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\x96\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\x96\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xf8\x96\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x97\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x1b\xbc\0\0\x08\x97\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\
+\x97\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x30\x97\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x40\x97\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\x97\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x97\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x60\x97\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x97\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x80\x97\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x97\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa0\x97\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xa8\x97\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x97\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x97\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\
+\x97\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x97\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xf0\x97\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\x98\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x08\x98\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x18\x98\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x98\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x28\x98\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x98\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x50\x98\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x60\x98\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\x98\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x78\x98\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\
+\x98\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x88\x98\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xa0\x98\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\x98\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\x98\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xc8\x98\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd8\x98\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xe0\x98\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x98\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\x99\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x10\x99\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x20\x99\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x28\x99\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\
+\x99\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\x99\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x48\x99\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x99\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\x99\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x80\x99\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x88\x99\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x98\x99\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x99\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\x99\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xc0\x99\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\x99\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xe0\x99\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\
+\x99\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\x99\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\0\x9a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x08\x9a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\x9a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x30\x9a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\x9a\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x48\x9a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x9a\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\x9a\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x68\x9a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x9a\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x9a\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa0\
+\x9a\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\x9a\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xb8\x9a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\x9a\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\x9a\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xe0\x9a\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\x9a\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\0\x9b\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x08\x9b\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\x9b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x20\x9b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\x9b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x40\x9b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x50\
+\x9b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\x9b\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x68\x9b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\x9b\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\x9b\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x88\x9b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\x9b\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xb0\x9b\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\x9b\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\x9b\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xd8\x9b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x9b\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\x9b\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\
+\x9c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\x9c\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x20\x9c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\x9c\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\x9c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x40\x9c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\x9c\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x60\x9c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\x9c\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\x9c\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x80\x9c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\x9c\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x98\x9c\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\
+\x9c\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\x9c\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xe0\x9c\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\x9c\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xf8\x9c\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\0\x9d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\x9d\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x10\x9d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\x9d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x38\x9d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x48\x9d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\x9d\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x58\x9d\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\
+\x9d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x68\x9d\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x80\x9d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\x9d\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa0\x9d\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xa8\x9d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\x9d\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xb8\x9d\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\x9d\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\x9d\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xe8\x9d\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\x9d\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\0\x9e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\
+\x9e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\x9e\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x18\x9e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\x9e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x40\x9e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x50\x9e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\x9e\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x60\x9e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\x9e\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x70\x9e\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x88\x9e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\x9e\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xa8\x9e\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\
+\x9e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\x9e\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xc0\x9e\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\x9e\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\x9e\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xf0\x9e\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\x9f\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x08\x9f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\x9f\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\x9f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x20\x9f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\x9f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x48\x9f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\
+\x9f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x60\x9f\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x68\x9f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\x9f\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x78\x9f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x90\x9f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\x9f\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xb0\x9f\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\x9f\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc0\x9f\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xc8\x9f\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\x9f\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xe8\x9f\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\
+\x9f\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x08\xa0\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x10\xa0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\xa0\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\xa0\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x28\xa0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\xa0\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x50\xa0\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\xa0\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\xa0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x70\xa0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\xa0\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x80\xa0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\
+\xa0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\xa0\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xb8\xa0\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\xa0\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc8\xa0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xd0\xa0\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\xa0\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xf0\xa0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\xa1\0\0\
+\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\xa1\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x18\xa1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\xa1\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x28\xa1\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\
+\xa1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\xa1\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x58\xa1\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\xa1\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x70\xa1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x78\xa1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\xa1\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x88\xa1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\xa1\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\xa1\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xc0\xa1\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\xa1\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xd0\xa1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\
+\xa1\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\xa1\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xf8\xa1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\xa2\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x18\xa2\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x20\xa2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\xa2\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x30\xa2\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\xa2\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\xa2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x60\xa2\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\xa2\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x78\xa2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\
+\xa2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\xa2\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x90\xa2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\xa2\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\xa2\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xc8\xa2\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\xa2\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xd8\xa2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\xa2\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\xa2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\0\xa3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\xa3\0\0\xe1\x01\0\0\
+\xcc\x04\0\0\x17\xb8\0\0\x20\xa3\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\
+\xa3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\xa3\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x38\xa3\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\xa3\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\xa3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x68\xa3\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\xa3\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x80\xa3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\xa3\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\xa3\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x98\xa3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\xa3\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xc0\xa3\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\
+\xa3\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\xa3\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xe0\xa3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\xa3\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\xa3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x08\xa4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\xa4\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x28\xa4\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\xa4\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\xa4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x40\xa4\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\xa4\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x60\xa4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\
+\xa4\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\xa4\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x88\xa4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\xa4\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\xa4\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xa0\xa4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\xa4\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xc8\xa4\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\xa4\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\xa4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xe8\xa4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\xa4\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xf8\xa4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\
+\xa5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\xa5\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x30\xa5\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\xa5\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x40\xa5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x48\xa5\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\xa5\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x68\xa5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\xa5\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\xa5\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x90\xa5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\xa5\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xa0\xa5\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\
+\xa5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\xa5\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xd0\xa5\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\xa5\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\xa5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xf0\xa5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\xa5\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\0\xa6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\xa6\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\xa6\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x38\xa6\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\xa6\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x48\xa6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\
+\xa6\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\xa6\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x70\xa6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\xa6\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x90\xa6\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x98\xa6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\xa6\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xa8\xa6\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\xa6\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\xa6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xd8\xa6\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\xa6\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xf0\xa6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\
+\xa6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\xa7\0\0\xe1\x01\0\0\xf6\x04\0\0\
+\x1b\xbc\0\0\x08\xa7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\xa7\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x30\xa7\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x38\xa7\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\xa7\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x48\xa7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\xa7\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\xa7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x70\xa7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\xa7\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xa0\xa7\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\
+\xa7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\xa7\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xb8\xa7\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\xa7\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\xa7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xe8\xa7\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\xa7\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\0\xa8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\xa8\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\xa8\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x18\xa8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\xa8\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x40\xa8\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x50\
+\xa8\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\xa8\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x60\xa8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\xa8\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x70\xa8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x88\xa8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\xa8\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xa8\xa8\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\xa8\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\xa8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xc0\xa8\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\xa8\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xe0\xa8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\
+\xa8\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\xa9\0\0\xe1\x01\0\0\xcc\x04\0\0\
+\x08\xb8\0\0\x08\xa9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\xa9\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\xa9\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x20\xa9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\xa9\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x48\xa9\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\xa9\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x60\xa9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x68\xa9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\xa9\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x78\xa9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\
+\xa9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\xa9\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xb0\xa9\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\xa9\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc0\xa9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xc8\xa9\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\xa9\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xe8\xa9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\xa9\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x08\xaa\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x10\xaa\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\xaa\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x20\xaa\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\
+\xaa\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\xaa\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x50\xaa\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\xaa\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\xaa\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x70\xaa\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\xaa\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x80\xaa\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\xaa\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\xaa\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xb8\xaa\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\xaa\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xc8\xaa\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\
+\xaa\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\xaa\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xf0\xaa\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\xab\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\xab\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x18\xab\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\xab\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x28\xab\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\xab\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\xab\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x58\xab\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\xab\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x70\xab\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\
+\xab\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\xab\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x88\xab\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\xab\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\xab\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xc0\xab\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\xab\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xd0\xab\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\xab\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\xab\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xf8\xab\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\xac\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x18\xac\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\
+\xac\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\xac\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x30\xac\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\xac\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\xac\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x60\xac\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\xac\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x78\xac\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\xac\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\xac\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x90\xac\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\xac\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\xac\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc8\
+\xac\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\xac\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xd8\xac\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\xac\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\xac\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\0\xad\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\xad\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x20\xad\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\xad\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\xad\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x38\xad\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\xad\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x58\xad\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x68\
+\xad\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\xad\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x80\xad\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\xad\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\xad\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x98\xad\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\xad\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xc0\xad\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\xad\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\xad\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xe0\xad\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\xad\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\xad\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\
+\xae\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\xae\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x28\xae\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\xae\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\xae\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x40\xae\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\xae\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x60\xae\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\xae\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\xae\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x88\xae\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\xae\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x98\xae\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\
+\xae\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\xae\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xc8\xae\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\xae\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\xae\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xe8\xae\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\xae\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xf8\xae\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\xaf\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\xaf\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x30\xaf\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\xaf\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x40\xaf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\
+\xaf\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\xaf\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x68\xaf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\xaf\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\xaf\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x90\xaf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\xaf\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xa0\xaf\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\xaf\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\xaf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xd0\xaf\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\xaf\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xe8\xaf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\
+\xaf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\xaf\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\0\xb0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\xb0\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\xb0\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x38\xb0\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\xb0\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x48\xb0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\xb0\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\xb0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x70\xb0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\xb0\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x90\xb0\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\
+\xb0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\xb0\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xa8\xb0\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\xb0\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\xb0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xd8\xb0\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\xb0\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xf0\xb0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\xb0\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\xb1\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x08\xb1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\xb1\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x30\xb1\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\
+\xb1\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\xb1\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x50\xb1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\xb1\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x60\xb1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x78\xb1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\xb1\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x98\xb1\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa0\xb1\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\xb1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xb0\xb1\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\xb1\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xd0\xb1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe8\
+\xb1\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\xb1\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xf8\xb1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\0\xb2\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\xb2\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x10\xb2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\xb2\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x48\xb2\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\xb2\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x60\xb2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x68\xb2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\xb2\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x78\xb2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\
+\xb2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\xb2\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xb0\xb2\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\xb2\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc0\xb2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xc8\xb2\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\xb2\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xe8\xb2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\xb2\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x08\xb3\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x10\xb3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\xb3\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x20\xb3\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\
+\xb3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\xb3\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x50\xb3\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\xb3\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\xb3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x70\xb3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\xb3\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x80\xb3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\xb3\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\xb3\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xb8\xb3\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\xb3\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xc8\xb3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\
+\xb3\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\xb3\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xf0\xb3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\xb4\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\xb4\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x18\xb4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\xb4\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x28\xb4\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\xb4\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\xb4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x58\xb4\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\xb4\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x70\xb4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\
+\xb4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\xb4\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x88\xb4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\xb4\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\xb4\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xc0\xb4\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\xb4\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xd0\xb4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\xb4\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\xb4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xf8\xb4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\xb5\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x18\xb5\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\
+\xb5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\xb5\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x30\xb5\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\xb5\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\xb5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x60\xb5\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\xb5\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x78\xb5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\xb5\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\xb5\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x90\xb5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\xb5\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\xb5\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc8\
+\xb5\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\xb5\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xd8\xb5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\xb5\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\xb5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\0\xb6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\xb6\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x20\xb6\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\xb6\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\xb6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x38\xb6\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\xb6\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x58\xb6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x68\
+\xb6\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\xb6\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x80\xb6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\xb6\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\xb6\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x98\xb6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\xb6\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xc0\xb6\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\xb6\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\xb6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xe0\xb6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\xb6\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\xb6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\
+\xb7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\xb7\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x28\xb7\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\xb7\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\xb7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x40\xb7\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\xb7\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x60\xb7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\xb7\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\xb7\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x88\xb7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\xb7\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x98\xb7\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\
+\xb7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\xb7\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xc8\xb7\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\xb7\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\xb7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xe8\xb7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\xb7\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xf8\xb7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\xb8\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\xb8\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x30\xb8\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\xb8\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x40\xb8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\
+\xb8\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\xb8\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x68\xb8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\xb8\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\xb8\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x90\xb8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\xb8\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xa0\xb8\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\xb8\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\xb8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xd0\xb8\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\xb8\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xe8\xb8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\
+\xb8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\xb8\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\0\xb9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\xb9\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\xb9\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x38\xb9\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\xb9\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x48\xb9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\xb9\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\xb9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x70\xb9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\xb9\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x90\xb9\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\
+\xb9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\xb9\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xa8\xb9\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\xb9\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\xb9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xd8\xb9\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\xb9\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xf0\xb9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\xb9\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\xba\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x08\xba\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\xba\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x30\xba\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\
+\xba\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\xba\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x50\xba\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\xba\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x60\xba\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x78\xba\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\xba\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x98\xba\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa0\xba\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\xba\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xb0\xba\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\xba\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xd0\xba\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe0\
+\xba\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\xba\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xf8\xba\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\0\xbb\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\xbb\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x10\xbb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\xbb\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x38\xbb\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x48\xbb\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\xbb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x58\xbb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\xbb\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x68\xbb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\
+\xbb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\xbb\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xa0\xbb\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\xbb\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\xbb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xb8\xbb\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\xbb\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xd8\xbb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe8\xbb\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\xbb\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\0\xbc\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\xbc\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x19\xbc\0\0\x10\xbc\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x18\
+\xbc\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\xbc\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x40\xbc\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x50\xbc\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\xbc\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x60\xbc\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\xbc\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x70\xbc\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\xbc\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\xbc\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xa8\xbc\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\xbc\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\xbc\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\
+\xbc\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\xbc\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xe0\xbc\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\xbd\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\xbd\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x18\xbd\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\xbd\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x28\xbd\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\xbd\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\xbd\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x58\xbd\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\xbd\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x70\xbd\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\
+\xbd\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\xbd\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x88\xbd\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\xbd\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\xbd\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xc0\xbd\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\xbd\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xd0\xbd\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\xbd\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\xbd\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xf8\xbd\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\xbe\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x18\xbe\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\
+\xbe\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\xbe\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x30\xbe\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\xbe\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\xbe\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x60\xbe\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\xbe\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x78\xbe\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\xbe\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\xbe\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x90\xbe\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\xbe\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\xbe\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc8\
+\xbe\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\xbe\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xd8\xbe\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\xbe\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\xbe\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\0\xbf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\xbf\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x20\xbf\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\xbf\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\xbf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x38\xbf\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\xbf\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x58\xbf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x68\
+\xbf\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\xbf\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x80\xbf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\xbf\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\xbf\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x98\xbf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\xbf\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xc0\xbf\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\xbf\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\xbf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xe0\xbf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\xbf\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\xbf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\
+\xc0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\xc0\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x28\xc0\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\xc0\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\xc0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x40\xc0\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\xc0\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x60\xc0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\xc0\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\xc0\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x88\xc0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\xc0\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x98\xc0\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\
+\xc0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\xc0\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xc8\xc0\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\xc0\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\xc0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xe8\xc0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\xc0\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xf8\xc0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\xc1\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\xc1\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x30\xc1\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\xc1\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x40\xc1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\
+\xc1\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\xc1\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x68\xc1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\xc1\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\xc1\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x90\xc1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\xc1\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xa0\xc1\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\xc1\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\xc1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xd0\xc1\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\xc1\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xe8\xc1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\
+\xc1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\xc1\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\0\xc2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\xc2\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\xc2\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x38\xc2\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\xc2\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x48\xc2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\xc2\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\xc2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x70\xc2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\xc2\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x90\xc2\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\
+\xc2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\xc2\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xa8\xc2\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\xc2\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\xc2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xd8\xc2\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\xc2\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xf0\xc2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\xc2\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\xc3\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x08\xc3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\xc3\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x30\xc3\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\
+\xc3\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\xc3\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x50\xc3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\xc3\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x60\xc3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x78\xc3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\xc3\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x98\xc3\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa0\xc3\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\xc3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xb0\xc3\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\xc3\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xd0\xc3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe0\
+\xc3\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\xc3\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xf8\xc3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\0\xc4\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\xc4\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x10\xc4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\xc4\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x38\xc4\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x48\xc4\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\xc4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x58\xc4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\xc4\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x68\xc4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\
+\xc4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\xc4\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xa0\xc4\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\xc4\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\xc4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xb8\xc4\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\xc4\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xd8\xc4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe8\xc4\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\xc4\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\0\xc5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\xc5\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x19\xbc\0\0\x10\xc5\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x18\
+\xc5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\xc5\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x40\xc5\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x50\xc5\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\xc5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x60\xc5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\xc5\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x70\xc5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\xc5\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\xc5\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xa8\xc5\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\xc5\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\xc5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\
+\xc5\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\xc5\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xe0\xc5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\xc5\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\xc6\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\
+\x08\xc6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\xc6\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x18\xc6\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x20\xc6\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\xc6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x48\xc6\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\xc6\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x60\xc6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x68\
+\xc6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\xc6\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x78\xc6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\xc6\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\xc6\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xb0\xc6\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\xc6\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xc0\xc6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\xc6\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\xc6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xe8\xc6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\xc6\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x08\xc7\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x10\
+\xc7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\xc7\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x20\xc7\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\xc7\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\xc7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x50\xc7\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\xc7\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x60\xc7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x68\xc7\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\xc7\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x78\xc7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\xc7\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\xc7\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\
+\xc7\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\xc7\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xd0\xc7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\xc7\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\xc7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xf8\xc7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\xc8\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x20\xc8\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\xc8\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\xc8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x38\xc8\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\xc8\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x58\xc8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x68\
+\xc8\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\xc8\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x80\xc8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\xc8\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\xc8\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x98\xc8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\xc8\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xc0\xc8\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\xc8\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\xc8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xe0\xc8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\xc8\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\xc8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\
+\xc9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\xc9\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x28\xc9\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\xc9\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\xc9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x40\xc9\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\xc9\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x60\xc9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\xc9\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\xc9\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x88\xc9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\xc9\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x98\xc9\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\
+\xc9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\xc9\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xc8\xc9\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\xc9\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\xc9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xe8\xc9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\xc9\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xf8\xc9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\xca\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\xca\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x30\xca\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\xca\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x40\xca\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\
+\xca\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\xca\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x68\xca\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\xca\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\xca\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x90\xca\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\xca\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xa0\xca\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\xca\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\xca\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xd0\xca\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\xca\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xe8\xca\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\
+\xca\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\xca\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\0\xcb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\xcb\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\xcb\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x38\xcb\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\xcb\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x48\xcb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\xcb\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\xcb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x70\xcb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\xcb\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x90\xcb\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\
+\xcb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\xcb\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xa8\xcb\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\xcb\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\xcb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xd8\xcb\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\xcb\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xf0\xcb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\xcb\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\xcc\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x08\xcc\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\xcc\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x30\xcc\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\
+\xcc\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\xcc\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x50\xcc\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\xcc\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x60\xcc\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x78\xcc\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\xcc\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x98\xcc\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa0\xcc\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\xcc\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xb0\xcc\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\xcc\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xd0\xcc\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe0\
+\xcc\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\xcc\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xf8\xcc\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\0\xcd\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\xcd\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x10\xcd\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\xcd\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x38\xcd\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x48\xcd\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\xcd\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x58\xcd\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\xcd\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x68\xcd\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\
+\xcd\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\xcd\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xa0\xcd\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\xcd\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\xcd\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xb8\xcd\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\xcd\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xd8\xcd\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe8\xcd\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\xcd\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\0\xce\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\xce\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x19\xbc\0\0\x10\xce\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x18\
+\xce\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\xce\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x40\xce\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x50\xce\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\xce\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x60\xce\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\xce\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x70\xce\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\xce\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\xce\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xa8\xce\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\xce\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\xce\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\
+\xce\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\xce\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xe0\xce\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\xce\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\xcf\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\
+\x08\xcf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\xcf\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x18\xcf\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x20\xcf\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\xcf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x48\xcf\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\xcf\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x60\xcf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x68\
+\xcf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\xcf\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x78\xcf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\xcf\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\xcf\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xb0\xcf\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\xcf\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xc0\xcf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\xcf\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\xcf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xe8\xcf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\xcf\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x08\xd0\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x10\
+\xd0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\xd0\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x20\xd0\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\xd0\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\xd0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x50\xd0\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\xd0\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x68\xd0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x70\xd0\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\xd0\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x80\xd0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\xd0\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\xd0\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xb8\
+\xd0\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\xd0\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xc8\xd0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\xd0\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\xd0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xf0\xd0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\xd1\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x10\xd1\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x18\xd1\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\xd1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x28\xd1\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\xd1\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x48\xd1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x58\
+\xd1\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\xd1\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x70\xd1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\xd1\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\xd1\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x88\xd1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\xd1\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xb0\xd1\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\xd1\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\xd1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xd0\xd1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\xd1\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\xd1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\
+\xd1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\xd2\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x10\xd2\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x18\xd2\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\xd2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x28\xd2\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\xd2\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x48\xd2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x68\xd2\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\xd2\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x80\xd2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\xd2\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x90\xd2\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x98\
+\xd2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\xd2\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xc0\xd2\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\xd2\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\xd2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xe0\xd2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\xd2\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xf0\xd2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\xd3\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\xd3\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x28\xd3\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\xd3\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x38\xd3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\
+\xd3\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\xd3\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x60\xd3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\xd3\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\xd3\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x88\xd3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\xd3\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x98\xd3\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\xd3\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\xd3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xc8\xd3\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\xd3\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xe0\xd3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe8\
+\xd3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\xd3\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xf8\xd3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\xd4\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\xd4\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x30\xd4\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\xd4\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x40\xd4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\xd4\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\xd4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x68\xd4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\xd4\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x88\xd4\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x90\
+\xd4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\xd4\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xa0\xd4\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\xd4\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\xd4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xd0\xd4\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\xd4\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xe8\xd4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\xd4\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\xd4\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\0\xd5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\xd5\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x0a\xbc\0\0\x28\xd5\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x38\
+\xd5\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\xd5\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x48\xd5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\xd5\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\xd5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x70\xd5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\xd5\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x90\xd5\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\xd5\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\xd5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xa8\xd5\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\xd5\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xc8\xd5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd8\
+\xd5\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\xd5\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xf0\xd5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\xd5\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\xd6\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\
+\x08\xd6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\xd6\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x30\xd6\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\xd6\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\xd6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x50\xd6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\xd6\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x60\xd6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\
+\xd6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\xd6\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x98\xd6\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa0\xd6\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\xd6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xb0\xd6\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\xd6\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xd0\xd6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe0\xd6\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\xd6\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xf8\xd6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\0\xd7\0\0\xe1\x01\0\0\
+\xf6\x04\0\0\x19\xbc\0\0\x08\xd7\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x10\
+\xd7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\xd7\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x38\xd7\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x48\xd7\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x50\xd7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x58\xd7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\xd7\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x68\xd7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\xd7\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\xd7\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xa0\xd7\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\xd7\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xb0\xd7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\
+\xd7\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\xd7\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xd8\xd7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe8\xd7\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\xd7\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\0\xd8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\xd8\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x10\xd8\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x18\xd8\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\xd8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x40\xd8\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x50\xd8\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x58\xd8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x60\
+\xd8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\xd8\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x70\xd8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\xd8\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\xd8\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xa8\xd8\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\xd8\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xb8\xd8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\xd8\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\xd8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xe0\xd8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\xd8\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\0\xd9\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x08\
+\xd9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\xd9\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x18\xd9\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x20\xd9\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\xd9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x48\xd9\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\xd9\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x60\xd9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x68\xd9\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\xd9\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x78\xd9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\xd9\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\xd9\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xb0\
+\xd9\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\xd9\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xc0\xd9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\xd9\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\xd9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xe8\xd9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\xd9\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x08\xda\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x10\xda\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\xda\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x20\xda\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\xda\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x40\xda\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x50\
+\xda\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\xda\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x68\xda\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x70\xda\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\xda\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x80\xda\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\xda\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xa8\xda\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xb8\xda\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\xda\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xc8\xda\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\xda\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\xda\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\
+\xda\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\xdb\0\0\xe1\x01\0\0\xcc\x04\0\0\
+\x17\xb8\0\0\x10\xdb\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x18\xdb\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\xdb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x28\xdb\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\xdb\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x48\xdb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x58\xdb\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\xdb\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x70\xdb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\xdb\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x80\xdb\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x88\
+\xdb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\xdb\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xb0\xdb\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\xdb\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\xdb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xd0\xdb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\xdb\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xe0\xdb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\xdb\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\xdc\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x18\xdc\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\xdc\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x28\xdc\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\
+\xdc\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\xdc\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x50\xdc\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x60\xdc\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\xdc\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x78\xdc\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\xdc\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x88\xdc\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x90\xdc\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\xdc\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xb8\xdc\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\xdc\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xc8\xdc\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd0\
+\xdc\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\xdc\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xe0\xdc\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\xdc\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\xdd\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x28\xdd\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\xdd\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x38\xdd\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\xdd\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\xdd\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x60\xdd\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\xdd\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x80\xdd\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x88\
+\xdd\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\xdd\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x98\xdd\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa0\xdd\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\xdd\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xc8\xdd\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\xdd\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xe0\xdd\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xe8\xdd\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\xdd\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\xf8\xdd\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\xde\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x20\xde\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x30\
+\xde\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\xde\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x40\xde\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\xde\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\xde\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x68\xde\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\xde\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x88\xde\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x90\xde\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\xde\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xa0\xde\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\xde\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xc0\xde\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd0\
+\xde\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\xde\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\xe8\xde\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\xde\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\xde\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\0\xdf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\xdf\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x28\xdf\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x38\xdf\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\xdf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x48\xdf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\xdf\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x58\xdf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\
+\xdf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\xdf\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x90\xdf\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x98\xdf\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\xdf\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xa8\xdf\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\xdf\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xc8\xdf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xd8\xdf\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\xdf\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\xf0\xdf\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\xdf\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\0\xe0\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x08\
+\xe0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\xe0\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x30\xe0\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\xe0\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\xe0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x50\xe0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\xe0\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x60\xe0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\xe0\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\xe0\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x98\xe0\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa0\xe0\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\xe0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\
+\xe0\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\xe0\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xd0\xe0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe0\xe0\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\xe0\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xf8\xe0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\0\xe1\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x08\xe1\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x10\xe1\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\xe1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x38\xe1\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x48\xe1\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x50\xe1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x58\
+\xe1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x60\xe1\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x68\xe1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\xe1\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x90\xe1\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xa0\xe1\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa8\xe1\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xb0\xe1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\xe1\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc0\xe1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xd8\xe1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xe8\xe1\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xf8\xe1\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\0\
+\xe2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\xe2\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x10\xe2\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x18\xe2\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\xe2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x40\xe2\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x50\xe2\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x58\xe2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x60\xe2\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\xe2\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x70\xe2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\xe2\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x98\xe2\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xa8\
+\xe2\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\xe2\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xb8\xe2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\xe2\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\xe2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xe0\xe2\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf0\xe2\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\0\xe3\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x08\xe3\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\xe3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x18\xe3\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x20\xe3\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x38\xe3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x48\
+\xe3\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\xe3\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x60\xe3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x68\xe3\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\xe3\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x78\xe3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\xe3\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xa0\xe3\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xb0\xe3\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\xe3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xc0\xe3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\xe3\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\xe3\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\
+\xe3\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\xe3\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x08\xe4\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x10\xe4\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\xe4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x20\xe4\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x28\xe4\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x40\xe4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x50\xe4\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\xe4\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x68\xe4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x70\xe4\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x78\xe4\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x80\
+\xe4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\xe4\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xa8\xe4\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xb8\xe4\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\xe4\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xc8\xe4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\xe4\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\xd8\xe4\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\xe4\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\xe5\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x10\xe5\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x18\xe5\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x20\xe5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\
+\xe5\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\xe5\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x48\xe5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x58\xe5\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\xe5\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x70\xe5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x78\xe5\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x80\xe5\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x88\xe5\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\xe5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xb0\xe5\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xc0\xe5\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xc8\xe5\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xd0\
+\xe5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\xe5\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\xe0\xe5\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\xe5\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\xe6\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x18\xe6\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x20\xe6\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x28\xe6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\xe6\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\xe6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x50\xe6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x60\xe6\0\0\xe1\x01\0\
+\0\0\0\0\0\0\0\0\0\x68\xe6\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\xe6\0\0\
+\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x80\xe6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x88\xe6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\xe6\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x98\xe6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\
+\xe6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xc0\xe6\0\0\xe1\x01\0\0\0\0\0\0\0\
+\0\0\0\xd0\xe6\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\xe6\0\0\xe1\x01\0\0\
+\xcc\x04\0\0\x08\xb8\0\0\xe8\xe6\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf0\
+\xe6\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\xe6\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\0\xe7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\xe7\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\xe7\0\0\xe1\x01\0\0\0\0\0\0\0\0\0\0\x30\
+\xe7\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x40\xe7\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x48\xe7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x50\xe7\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\xe7\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x60\xe7\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\xe7\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x88\xe7\0\0\xe1\x01\0\0\0\0\0\0\0\0\0\0\x90\xe7\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x98\xe7\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\xa0\xe7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\xe7\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xb0\xe7\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\xe7\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\xe7\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xe8\xe7\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf8\xe7\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\0\xe8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x08\
+\xe8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\xe8\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x18\xe8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x30\xe8\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x40\xe8\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x50\xe8\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\xe8\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x60\xe8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\xe8\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x70\xe8\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x88\xe8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x98\xe8\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\xa8\xe8\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb0\
+\xe8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xb8\xe8\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xc0\xe8\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xc8\xe8\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\xe8\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xf0\xe8\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\0\xe9\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x08\xe9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x10\xe9\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\xe9\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x20\xe9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x38\xe9\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x48\xe9\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x58\
+\xe9\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x60\xe9\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x68\xe9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x70\xe9\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x78\xe9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x90\xe9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa0\xe9\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\xb0\xe9\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xb8\xe9\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc0\xe9\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\xc8\xe9\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd0\xe9\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xe8\xe9\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xf8\
+\xe9\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x08\xea\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x10\xea\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x18\xea\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\xea\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\x28\xea\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x40\xea\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\x50\xea\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x60\xea\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x68\xea\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\x70\xea\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x78\xea\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\x80\xea\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\
+\xea\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xa8\xea\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\xb8\xea\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc0\xea\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xc8\xea\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\xd0\xea\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xd8\xea\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xf0\xea\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\0\xeb\0\0\
+\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x10\xeb\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x18\xeb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x20\xeb\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x28\xeb\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x30\
+\xeb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x48\xeb\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\x58\xeb\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x68\xeb\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x70\xeb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\x78\xeb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x80\xeb\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\x88\xeb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa0\xeb\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb0\xeb\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\xc0\xeb\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xc8\xeb\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\xd0\xeb\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd8\
+\xeb\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe0\xeb\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xf8\xeb\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x08\xec\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x18\xec\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x20\xec\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x28\xec\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x30\xec\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x38\xec\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\xec\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\x60\xec\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x70\xec\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\x78\xec\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x80\
+\xec\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x88\xec\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x1b\xbc\0\0\x90\xec\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xa8\xec\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\xb8\xec\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\xc8\xec\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd0\xec\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\xd8\xec\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe0\xec\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xe8\xec\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\0\xed\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x10\xed\0\0\xe1\x01\0\0\
+\xcc\x04\0\0\x17\xb8\0\0\x20\xed\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x28\
+\xed\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x30\xed\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x38\xed\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x40\xed\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\xed\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\x68\xed\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x78\xed\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\x80\xed\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x88\xed\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x90\xed\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x98\xed\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb0\xed\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\xc0\xed\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd0\
+\xed\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xd8\xed\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\xe0\xed\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xe8\xed\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xf0\xed\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x08\xee\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x18\xee\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x17\xb8\0\0\x28\xee\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x30\xee\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x38\xee\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x40\xee\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x48\xee\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\x60\xee\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x70\
+\xee\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x80\xee\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x08\xb8\0\0\x88\xee\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x90\xee\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x98\xee\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\
+\0\xa0\xee\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xb8\xee\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0a\xbc\0\0\xc8\xee\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xd8\xee\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe0\xee\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\
+\xbc\0\0\xe8\xee\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf0\xee\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x1b\xbc\0\0\xf8\xee\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x10\
+\xef\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x20\xef\0\0\xe1\x01\0\0\xcc\x04\0\
+\0\x17\xb8\0\0\x30\xef\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x38\xef\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x40\xef\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\
+\0\x48\xef\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x50\xef\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\x68\xef\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x78\xef\0\
+\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x88\xef\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\
+\xb8\0\0\x90\xef\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\x98\xef\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x19\xbc\0\0\xa0\xef\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xa8\
+\xef\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc0\xef\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0a\xbc\0\0\xd0\xef\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe0\xef\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xe8\xef\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\
+\0\xf0\xef\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xf8\xef\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x1b\xbc\0\0\0\xf0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x18\xf0\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x28\xf0\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\
+\xb8\0\0\x38\xf0\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x40\xf0\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0d\xbc\0\0\x48\xf0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x50\
+\xf0\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x58\xf0\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\x70\xf0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x80\xf0\0\0\xe1\
+\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x90\xf0\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\
+\0\x98\xf0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa0\xf0\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x19\xbc\0\0\xa8\xf0\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb0\xf0\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xc8\xf0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\
+\xbc\0\0\xd8\xf0\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xe8\xf0\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x08\xb8\0\0\xf0\xf0\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xf8\
+\xf0\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\0\xf1\0\0\xe1\x01\0\0\xf6\x04\0\0\
+\x1b\xbc\0\0\x08\xf1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x20\xf1\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x30\xf1\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\
+\0\x40\xf1\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x48\xf1\0\0\xe1\x01\0\0\xf6\
+\x04\0\0\x0d\xbc\0\0\x50\xf1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x58\xf1\0\
+\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x60\xf1\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\
+\xbc\0\0\x78\xf1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\0\x88\xf1\0\0\xe1\x01\0\
+\0\xcc\x04\0\0\x17\xb8\0\0\x98\xf1\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\xa0\
+\xf1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\xa8\xf1\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x19\xbc\0\0\xb0\xf1\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\xb8\xf1\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\xd0\xf1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0a\xbc\0\
+\0\xe0\xf1\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\xf0\xf1\0\0\xe1\x01\0\0\xcc\
+\x04\0\0\x08\xb8\0\0\xf8\xf1\0\0\xe1\x01\0\0\xf6\x04\0\0\x0d\xbc\0\0\0\xf2\0\0\
+\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x08\xf2\0\0\xe1\x01\0\0\xf6\x04\0\0\x1b\
+\xbc\0\0\x10\xf2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x28\xf2\0\0\xe1\x01\0\
+\0\xf6\x04\0\0\x0a\xbc\0\0\x48\xf2\0\0\xe1\x01\0\0\xcc\x04\0\0\x17\xb8\0\0\x50\
+\xf2\0\0\xe1\x01\0\0\xcc\x04\0\0\x08\xb8\0\0\x58\xf2\0\0\xe1\x01\0\0\xf6\x04\0\
+\0\x0d\xbc\0\0\x60\xf2\0\0\xe1\x01\0\0\xf6\x04\0\0\x19\xbc\0\0\x68\xf2\0\0\xe1\
+\x01\0\0\xf6\x04\0\0\x1b\xbc\0\0\x78\xf2\0\0\xe1\x01\0\0\x7d\x07\0\0\x03\xec\
+\x01\0\x98\xf2\0\0\xe1\x01\0\0\x21\x08\0\0\x08\xfc\x01\0\xc0\xf2\0\0\xe1\x01\0\
+\0\x21\x08\0\0\x08\xfc\x01\0\xc8\xf2\0\0\xe1\x01\0\0\x74\x08\0\0\x10\x08\x02\0\
+\xd0\xf2\0\0\xe1\x01\0\0\x74\x08\0\0\x19\x08\x02\0\xd8\xf2\0\0\xe1\x01\0\0\x74\
+\x08\0\0\x09\x08\x02\0\xe8\xf2\0\0\xe1\x01\0\0\x91\x08\0\0\x0f\x0c\x02\0\xf0\
+\xf2\0\0\xe1\x01\0\0\x7d\x07\0\0\x03\xec\x01\0\x40\xf3\0\0\xe1\x01\0\0\x21\x08\
+\0\0\x08\xfc\x01\0\x68\xf3\0\0\xe1\x01\0\0\x21\x08\0\0\x08\xfc\x01\0\x70\xf3\0\
+\0\xe1\x01\0\0\x74\x08\0\0\x10\x08\x02\0\x78\xf3\0\0\xe1\x01\0\0\x74\x08\0\0\
+\x19\x08\x02\0\x90\xf3\0\0\xe1\x01\0\0\x74\x08\0\0\x09\x08\x02\0\x98\xf3\0\0\
+\xe1\x01\0\0\x91\x08\0\0\x0f\x0c\x02\0\xa0\xf3\0\0\xe1\x01\0\0\x7d\x07\0\0\x03\
+\xec\x01\0\0\xf4\0\0\xe1\x01\0\0\x21\x08\0\0\x08\xfc\x01\0\x38\xf4\0\0\xe1\x01\
+\0\0\x21\x08\0\0\x08\xfc\x01\0\x40\xf4\0\0\xe1\x01\0\0\x74\x08\0\0\x10\x08\x02\
+\0\x48\xf4\0\0\xe1\x01\0\0\x74\x08\0\0\x19\x08\x02\0\x60\xf4\0\0\xe1\x01\0\0\
+\x74\x08\0\0\x09\x08\x02\0\x68\xf4\0\0\xe1\x01\0\0\x91\x08\0\0\x0f\x0c\x02\0\
+\x70\xf4\0\0\xe1\x01\0\0\x7d\x07\0\0\x03\xec\x01\0\xd0\xf4\0\0\xe1\x01\0\0\x21\
+\x08\0\0\x08\xfc\x01\0\x08\xf5\0\0\xe1\x01\0\0\x21\x08\0\0\x08\xfc\x01\0\x10\
+\xf5\0\0\xe1\x01\0\0\x74\x08\0\0\x10\x08\x02\0\x18\xf5\0\0\xe1\x01\0\0\x74\x08\
+\0\0\x19\x08\x02\0\x30\xf5\0\0\xe1\x01\0\0\x74\x08\0\0\x09\x08\x02\0\x38\xf5\0\
+\0\xe1\x01\0\0\x91\x08\0\0\x0f\x0c\x02\0\x50\xf5\0\0\xe1\x01\0\0\x7d\x07\0\0\
+\x03\xec\x01\0\xa0\xf5\0\0\xe1\x01\0\0\0\0\0\0\0\0\0\0\xc8\xf5\0\0\xe1\x01\0\0\
+\xb2\x03\0\0\x02\x0c\x04\0\x10\xf6\0\0\xe1\x01\0\0\xa9\x08\0\0\x06\x10\x04\0\
+\x20\xf6\0\0\xe1\x01\0\0\xb6\x08\0\0\x37\x18\x04\0\x70\xf6\0\0\xe1\x01\0\0\xf8\
+\x08\0\0\x1d\x64\x03\0\x78\xf6\0\0\xe1\x01\0\0\xf8\x08\0\0\x22\x64\x03\0\x80\
+\xf6\0\0\xe1\x01\0\0\xb6\x08\0\0\x16\x18\x04\0\x90\xf6\0\0\xe1\x01\0\0\x21\x09\
+\0\0\x03\x1c\x04\0\xb8\xf6\0\0\xe1\x01\0\0\x51\x09\0\0\x01\x2c\x04\0\0\0\0\0\
+\x0c\0\0\0\xff\xff\xff\xff\x04\0\x08\0\x08\x7c\x0b\0\x14\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\xc8\xf6\0\0\0\0\0\0\x42\x53\0\0\x05\0\x08\0\x04\x01\0\0\x08\x01\x01\
+\xfb\x0e\x0d\0\x01\x01\x01\x01\0\0\0\x01\0\0\x01\x01\x01\x1f\x05\0\0\0\0\x34\0\
+\0\0\x4d\0\0\0\x5e\0\0\0\x71\0\0\0\x03\x01\x1f\x02\x0f\x05\x1e\x0a\x76\0\0\0\0\
+\x7d\x90\x07\x95\xdc\xc9\x67\x4f\xcf\xbb\x6f\x3f\x2b\xd2\xe8\xc8\x80\0\0\0\x01\
+\xb8\x10\xf2\x70\x73\x3e\x10\x63\x19\xb6\x7e\xf5\x12\xc6\x24\x6e\x8b\0\0\0\x02\
+\x09\xcf\xcd\x71\x69\xc2\x4b\xec\x44\x8f\x30\x58\x2e\x8c\x6d\xb9\x9d\0\0\0\x03\
+\x45\xef\x27\x66\x4f\x0d\x65\x59\xb5\x38\x8d\xb0\x30\x2c\xf8\xe1\xa3\0\0\0\x04\
+\x66\xf9\xea\x68\xa9\x45\xdb\x13\xa1\xc0\x2a\xae\xb4\x07\x1f\x55\xad\0\0\0\x03\
+\xfc\xee\x41\x5b\xb1\x9d\xb8\xac\xb9\x68\xee\xda\x6f\x02\xfa\x29\xb2\0\0\0\x03\
+\xbf\x9f\xbc\x0e\x8f\x60\x92\x7f\xef\x9d\x89\x17\x53\x53\x75\xa6\xba\0\0\0\x03\
+\x14\x97\x78\xac\xe3\x0a\x1f\xf2\x08\xad\xc8\x78\x3f\xd0\x4b\x29\xbf\0\0\0\x03\
+\xd2\x88\xe3\x08\xe1\x42\xe5\x1c\x48\xe7\x42\x2f\x4f\xbb\xaa\x3f\xc6\0\0\0\x03\
+\x8b\xeb\xb7\x80\xb4\x5d\x3f\xe9\x32\xcc\x1d\x93\x4f\xa5\xf5\xfe\x04\0\0\x09\
+\x02\0\0\0\0\0\0\0\0\x03\xf0\x01\x01\x05\x07\x0a\x30\x05\x34\xa3\x05\x0a\x06\
+\x20\x05\0\x03\x88\x7e\x2e\x05\x02\x06\x03\xf9\x01\x20\x06\x03\x87\x7e\x2e\x05\
+\x0b\x06\x03\xfc\x01\x2e\x05\x06\x3d\x05\x03\x21\x06\x03\x82\x7e\x4a\x05\x2c\
+\x06\x03\xcb\x01\x3c\x05\x0b\x30\x05\x06\x06\x20\x03\xb3\x7e\x2e\x05\x02\x06\
+\x03\x83\x02\x20\x06\x03\xfd\x7d\x58\x05\x22\x06\x03\xce\x01\x3c\x06\x03\xb2\
+\x7e\x66\x03\xce\x01\x3c\x05\x06\x06\x03\xf9\x7e\x2e\x06\x3c\x05\0\x06\x03\x87\
+\x01\x20\x05\x0f\x03\x83\x7f\x66\x2d\x05\x10\x33\x05\x06\x06\x20\x03\xab\x7f\
+\x20\x05\x17\x06\x03\x2e\x4a\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\
+\x05\x1b\x20\x05\x19\x20\x05\x17\x06\x3b\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x2e\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x2e\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x03\x51\x2e\x05\x22\x06\x03\xd0\x01\x2e\x06\x03\xb0\x7e\x66\x03\xd0\x01\
+\x3c\x05\x06\x06\x03\x53\x2e\x06\x3c\x05\0\x06\x03\x2d\x20\x05\x1a\x03\x59\x66\
+\x06\x03\xd7\x7e\x2e\x06\x03\xa8\x01\x20\x06\x03\xd8\x7e\x2e\x06\x03\xa9\x01\
+\x20\x2d\x06\x03\xd8\x7e\x2e\x06\x03\xa9\x01\x20\x06\x03\xd7\x7e\x2e\x06\x03\
+\xa8\x01\x20\x2f\x06\x03\xd7\x7e\x2e\x06\x03\xa8\x01\x20\x05\x10\x32\x05\x06\
+\x06\x20\x03\xd4\x7e\x20\x05\x17\x06\x03\x2e\x2e\x05\x08\x06\x4a\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x17\x06\x3b\x05\x08\x06\x3c\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x3c\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x20\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x3c\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x3c\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x20\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x4a\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x2e\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x3c\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x3c\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x3c\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x3c\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x3c\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x2e\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x3c\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\0\x03\x51\x20\x05\x0f\x06\x03\x3b\x74\x05\x18\x06\x20\x05\x1d\x06\x03\x1e\
+\x20\x05\x24\x21\x05\x0e\x41\x05\x12\x06\x20\x05\x0e\x3c\x05\x07\x06\x21\x06\
+\x03\xa0\x7f\x4a\x03\xe0\0\x20\x03\xa0\x7f\x20\x05\x17\x06\x03\x2e\x3c\x05\x08\
+\x06\x3c\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x03\x51\x3c\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x3c\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x2e\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x3c\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x2e\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x2e\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x2e\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x1c\x06\x03\xb0\x01\x4a\x06\x03\xd0\x7e\x20\x05\x03\
+\x06\x03\xfb\0\x20\x05\x25\x03\x39\x3c\x06\x03\xcc\x7e\x2e\x05\x07\x06\x03\xb9\
+\x01\x3c\x06\x4a\x03\xc7\x7e\x20\x05\x17\x06\x03\x2e\x3c\x05\x08\x06\x3c\x05\
+\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x17\x06\x3b\x05\x08\
+\x06\x3c\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x4a\x05\x0d\x06\x21\x05\x19\
+\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x3c\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x20\x05\x0d\
+\x06\x21\x05\x19\x06\x2e\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x4a\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x20\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x3c\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x2e\x05\x08\x06\x20\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x3c\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x2e\x05\x08\x06\x20\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x3c\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x3c\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x3c\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x3c\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x3c\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x2e\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x3c\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x2e\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x2e\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x2e\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\
+\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\
+\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\
+\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\
+\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\
+\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\
+\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\
+\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\
+\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\
+\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\
+\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\
+\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\
+\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\
+\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\
+\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\
+\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\
+\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\
+\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\
+\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\
+\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\
+\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\
+\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\
+\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\
+\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\
+\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\
+\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\
+\x2e\x20\x05\x08\x06\x2e\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\
+\x20\x05\x0a\x3c\x03\x51\x20\x05\x17\x06\x03\x2e\x20\x05\x08\x06\x2e\x05\x0d\
+\x06\x21\x05\x19\x06\x20\x05\x1b\x20\x05\x19\x20\x05\x0a\x3c\x03\x51\x20\x05\
+\x17\x06\x03\x2e\x3c\x05\x08\x06\x20\x05\x0d\x06\x21\x05\x19\x06\x20\x05\x1b\
+\x20\x05\x03\x06\x03\xcc\0\x2e\x06\x03\x85\x7f\x2e\x05\x08\x06\x03\xff\0\x2e\
+\x06\x58\x05\x10\x06\x23\x05\x19\x06\x20\x05\x09\x20\x05\x0f\x06\x2f\x05\x03\
+\x03\x78\x20\x06\x03\x85\x7f\x20\x03\xfb\0\x20\x03\x85\x7f\x3c\x03\xfb\0\x20\
+\x03\x85\x7f\x2e\x05\x08\x06\x03\xff\0\x2e\x06\x58\x05\x10\x06\x23\x05\x19\x06\
+\x20\x05\x09\x3c\x05\x0f\x06\x21\x05\x03\x03\x78\x20\x06\x03\x85\x7f\x20\x03\
+\xfb\0\x20\x03\x85\x7f\x20\x03\xfb\0\x20\x03\x85\x7f\x2e\x03\xfb\0\x2e\x03\x85\
+\x7f\x20\x03\xfb\0\x20\x03\x85\x7f\x20\x05\x08\x06\x03\xff\0\x20\x06\x74\x05\
+\x10\x06\x23\x05\x19\x06\x20\x05\x09\x3c\x05\x0f\x06\x21\x05\x03\x03\x78\x20\
+\x06\x03\x85\x7f\x20\x03\xfb\0\x20\x03\x85\x7f\x20\x03\xfb\0\x20\x03\x85\x7f\
+\x2e\x03\xfb\0\x2e\x03\x85\x7f\x20\x03\xfb\0\x20\x03\x85\x7f\x20\x05\x08\x06\
+\x03\xff\0\x20\x06\x74\x05\x10\x06\x23\x05\x19\x06\x20\x05\x09\x3c\x05\x0f\x06\
+\x21\x06\x03\xfd\x7e\x20\x05\x03\x06\x03\xfb\0\x2e\x06\x03\x85\x7f\x20\x05\x02\
+\x06\x03\x83\x02\xd6\x06\x03\xfd\x7d\x66\x03\x83\x02\x20\x05\x06\x06\x2f\x06\
+\x03\xfc\x7d\x20\x05\x37\x06\x03\x86\x02\x20\x05\x1d\x03\x53\x9e\x05\x22\x06\
+\x20\x05\x16\x06\x03\x2d\x20\x05\x03\x2f\x06\x03\xf9\x7d\x4a\x05\x01\x06\x03\
+\x8b\x02\x20\x02\x02\0\x01\x01\x2f\x68\x6f\x6d\x65\x2f\x73\x68\x65\x6d\x6d\x69\
+\x6e\x67\x65\x72\x2f\x44\x50\x44\x4b\x2f\x74\x61\x70\x2f\x66\x69\x78\x69\x74\
+\x2f\x64\x72\x69\x76\x65\x72\x73\x2f\x6e\x65\x74\x2f\x74\x61\x70\x2f\x62\x70\
+\x66\0\x2f\x75\x73\x72\x2f\x69\x6e\x63\x6c\x75\x64\x65\x2f\x61\x73\x6d\x2d\x67\
+\x65\x6e\x65\x72\x69\x63\0\x2f\x75\x73\x72\x2f\x69\x6e\x63\x6c\x75\x64\x65\x2f\
+\x62\x70\x66\0\x2f\x75\x73\x72\x2f\x69\x6e\x63\x6c\x75\x64\x65\x2f\x6c\x69\x6e\
+\x75\x78\0\x2e\x2f\x2e\x2e\0\x74\x61\x70\x5f\x72\x73\x73\x2e\x63\0\x69\x6e\x74\
+\x2d\x6c\x6c\x36\x34\x2e\x68\0\x62\x70\x66\x5f\x68\x65\x6c\x70\x65\x72\x5f\x64\
+\x65\x66\x73\x2e\x68\0\x62\x70\x66\x2e\x68\0\x74\x61\x70\x5f\x72\x73\x73\x2e\
+\x68\0\x69\x6e\x2e\x68\0\x74\x79\x70\x65\x73\x2e\x68\0\x69\x70\x2e\x68\0\x69\
+\x70\x76\x36\x2e\x68\0\x69\x6e\x36\x2e\x68\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\x11\x01\0\0\x04\0\xf1\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\x03\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x73\x11\0\0\0\0\x03\
+\0\xf0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x22\0\0\0\x01\0\x07\0\0\0\0\0\0\0\0\0\x1b\
+\0\0\0\0\0\0\0\x6a\x16\0\0\0\0\x03\0\xb8\xf6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x49\
+\x0b\0\0\0\0\x03\0\x58\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x53\x0f\0\0\0\0\x03\0\
+\x78\x18\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xaa\x16\0\0\x01\0\x07\0\x1b\0\0\0\0\0\0\0\
+\x09\0\0\0\0\0\0\0\x1c\x14\0\0\0\0\x03\0\xc8\xf5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x09\x11\0\0\0\0\x03\0\xb0\x6f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3c\x01\0\0\0\0\x03\
+\0\xb0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x62\x16\0\0\0\0\x03\0\x10\x03\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x35\x11\0\0\0\0\x03\0\x70\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x29\x0c\0\0\0\0\x03\0\xd0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x28\x07\0\0\0\0\x03\
+\0\x30\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x25\x02\0\0\0\0\x03\0\x90\x04\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x3f\x16\0\0\0\0\x03\0\xf0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x12\x11\0\0\0\0\x03\0\x50\x05\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x06\x0c\0\0\0\0\x03\
+\0\xb0\x05\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x05\x07\0\0\0\0\x03\0\x10\x06\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x0b\x02\0\0\0\0\x03\0\x70\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x1c\x16\0\0\0\0\x03\0\xd0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xef\x10\0\0\0\0\x03\
+\0\x30\x07\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf5\x0b\0\0\0\0\x03\0\x90\x07\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xeb\x06\0\0\0\0\x03\0\xf0\x07\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xe8\x01\0\0\0\0\x03\0\x50\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x16\0\0\0\0\x03\
+\0\xb0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xcc\x10\0\0\0\0\x03\0\x10\x09\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xd2\x0b\0\0\0\0\x03\0\x70\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xd1\x06\0\0\0\0\x03\0\xd0\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc5\x01\0\0\0\0\x03\
+\0\x30\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xdf\x15\0\0\0\0\x03\0\x90\x0a\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xb2\x10\0\0\0\0\x03\0\xf0\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xb8\x0b\0\0\0\0\x03\0\x50\x0b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb7\x06\0\0\0\0\x03\
+\0\xb0\x0b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xab\x01\0\0\0\0\x03\0\x10\x0c\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xc5\x15\0\0\0\0\x03\0\x70\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x98\x10\0\0\0\0\x03\0\xd0\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9e\x0b\0\0\0\0\x03\
+\0\x30\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9d\x06\0\0\0\0\x03\0\x90\x0d\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x91\x01\0\0\0\0\x03\0\xe8\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xab\x15\0\0\0\0\x03\0\x48\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7e\x10\0\0\0\0\x03\
+\0\xa0\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x84\x0b\0\0\0\0\x03\0\xf8\x0e\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x83\x06\0\0\0\0\x03\0\x50\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x77\x01\0\0\0\0\x03\0\xa8\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x91\x15\0\0\0\0\x03\
+\0\0\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x64\x10\0\0\0\0\x03\0\x58\x10\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x6a\x0b\0\0\0\0\x03\0\xb0\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x69\
+\x06\0\0\0\0\x03\0\x08\x11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5d\x01\0\0\0\0\x03\0\
+\x60\x11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x77\x15\0\0\0\0\x03\0\xb8\x11\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x4a\x10\0\0\0\0\x03\0\x10\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x50\
+\x0b\0\0\0\0\x03\0\x68\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4f\x06\0\0\0\0\x03\0\
+\xc0\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x43\x01\0\0\0\0\x03\0\x18\x13\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xa1\x16\0\0\0\0\x03\0\x70\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6a\
+\x11\0\0\0\0\x03\0\xc8\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5e\x0c\0\0\0\0\x03\0\
+\x20\x14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5d\x07\0\0\0\0\x03\0\x78\x14\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x5a\x02\0\0\0\0\x03\0\xd0\x14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x86\
+\x16\0\0\0\0\x03\0\x28\x15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4f\x11\0\0\0\0\x03\0\
+\x80\x15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x43\x0c\0\0\0\0\x03\0\xd8\x15\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x42\x07\0\0\0\0\x03\0\x30\x16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3f\
+\x02\0\0\0\0\x03\0\x88\x16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x59\x16\0\0\0\0\x03\0\
+\xe0\x16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2c\x11\0\0\0\0\x03\0\x38\x17\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x20\x0c\0\0\0\0\x03\0\x90\x17\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1f\
+\x07\0\0\0\0\x03\0\xe8\x17\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1c\x02\0\0\0\0\x03\0\
+\x40\x18\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x36\x16\0\0\0\0\x03\0\x78\x6f\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x42\x14\0\0\0\0\x03\0\x80\x90\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x58\
+\x05\0\0\0\0\x03\0\x50\x1a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x58\x19\0\0\0\0\x03\0\
+\xb0\x1a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\x13\0\0\0\0\x03\0\x10\x1b\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xf5\x0e\0\0\0\0\x03\0\x68\x1b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf4\
+\x09\0\0\0\0\x03\0\xc0\x1b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xfa\x04\0\0\0\0\x03\0\
+\x18\x1c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xfa\x18\0\0\0\0\x03\0\x70\x1c\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xa1\x13\0\0\0\0\x03\0\xc8\x1c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x97\
+\x0e\0\0\0\0\x03\0\x20\x1d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x96\x09\0\0\0\0\x03\0\
+\x78\x1d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9c\x04\0\0\0\0\x03\0\xd0\x1d\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x9c\x18\0\0\0\0\x03\0\x28\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x43\
+\x13\0\0\0\0\x03\0\x80\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x39\x0e\0\0\0\0\x03\0\
+\xd8\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x38\x09\0\0\0\0\x03\0\x30\x1f\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x35\x04\0\0\0\0\x03\0\x88\x1f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3e\
+\x18\0\0\0\0\x03\0\xe0\x1f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe5\x12\0\0\0\0\x03\0\
+\x38\x20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd2\x0d\0\0\0\0\x03\0\x90\x20\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xd1\x08\0\0\0\0\x03\0\xe8\x20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xce\
+\x03\0\0\0\0\x03\0\x40\x21\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd7\x17\0\0\0\0\x03\0\
+\x98\x21\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7e\x12\0\0\0\0\x03\0\xf0\x21\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x6b\x0d\0\0\0\0\x03\0\x48\x22\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6a\
+\x08\0\0\0\0\x03\0\xa0\x22\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x67\x03\0\0\0\0\x03\0\
+\xf8\x22\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x70\x17\0\0\0\0\x03\0\x50\x23\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x17\x12\0\0\0\0\x03\0\xa8\x23\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\
+\x0d\0\0\0\0\x03\0\0\x24\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\x08\0\0\0\0\x03\0\x58\
+\x24\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x03\0\xa8\x24\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\x09\x17\0\0\0\0\x03\0\x10\x25\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb0\x11\0\
+\0\0\0\x03\0\x70\x25\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9d\x0c\0\0\0\0\x03\0\xc8\x25\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9c\x07\0\0\0\0\x03\0\x20\x26\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\x99\x02\0\0\0\0\x03\0\x78\x26\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x72\x1a\0\0\
+\0\0\x03\0\xd0\x26\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x22\x15\0\0\0\0\x03\0\x28\x27\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\x0f\x10\0\0\0\0\x03\0\x80\x27\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\x0e\x0b\0\0\0\0\x03\0\xd8\x27\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x14\x06\0\0\0\
+\0\x03\0\x30\x28\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x14\x1a\0\0\0\0\x03\0\x88\x28\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\xc4\x14\0\0\0\0\x03\0\xe0\x28\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\xb1\x0f\0\0\0\0\x03\0\x38\x29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb0\x0a\0\0\0\0\
+\x03\0\x90\x29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb6\x05\0\0\0\0\x03\0\xe8\x29\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\xb6\x19\0\0\0\0\x03\0\x40\x2a\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\x66\x14\0\0\0\0\x03\0\x98\x2a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4a\x0f\0\0\0\0\
+\x03\0\xf0\x2a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x52\x0a\0\0\0\0\x03\0\x48\x2b\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x4f\x05\0\0\0\0\x03\0\xa0\x2b\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\x4f\x19\0\0\0\0\x03\0\xf8\x2b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf6\x13\0\0\0\0\
+\x03\0\x50\x2c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xec\x0e\0\0\0\0\x03\0\xa8\x2c\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\xeb\x09\0\0\0\0\x03\0\0\x2d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xf1\x04\0\0\0\0\x03\0\x58\x2d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf1\x18\0\0\0\0\x03\
+\0\xb0\x2d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x98\x13\0\0\0\0\x03\0\x08\x2e\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x8e\x0e\0\0\0\0\x03\0\x60\x2e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x8d\x09\0\0\0\0\x03\0\xb8\x2e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x93\x04\0\0\0\0\x03\
+\0\x10\x2f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x93\x18\0\0\0\0\x03\0\x60\x2f\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x3a\x13\0\0\0\0\x03\0\xd0\x2f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x30\x0e\0\0\0\0\x03\0\x28\x30\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2f\x09\0\0\0\0\x03\
+\0\x80\x30\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2c\x04\0\0\0\0\x03\0\xd8\x30\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x35\x18\0\0\0\0\x03\0\x30\x31\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xdc\x12\0\0\0\0\x03\0\x88\x31\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc9\x0d\0\0\0\0\x03\
+\0\xe0\x31\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc8\x08\0\0\0\0\x03\0\x38\x32\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xc5\x03\0\0\0\0\x03\0\x90\x32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xce\x17\0\0\0\0\x03\0\xe8\x32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x75\x12\0\0\0\0\x03\
+\0\x40\x33\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x62\x0d\0\0\0\0\x03\0\x98\x33\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x61\x08\0\0\0\0\x03\0\xf0\x33\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x5e\x03\0\0\0\0\x03\0\x48\x34\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x67\x17\0\0\0\0\x03\
+\0\xa0\x34\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0e\x12\0\0\0\0\x03\0\xf8\x34\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xfb\x0c\0\0\0\0\x03\0\x50\x35\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xfa\x07\0\0\0\0\x03\0\xa8\x35\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf7\x02\0\0\0\0\x03\
+\0\0\x36\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\0\x03\0\x58\x36\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\xa7\x11\0\0\0\0\x03\0\xb0\x36\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x94\
+\x0c\0\0\0\0\x03\0\x08\x37\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x93\x07\0\0\0\0\x03\0\
+\x60\x37\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\x02\0\0\0\0\x03\0\xb8\x37\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x69\x1a\0\0\0\0\x03\0\x10\x38\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x19\
+\x15\0\0\0\0\x03\0\x68\x38\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x06\x10\0\0\0\0\x03\0\
+\xc0\x38\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x05\x0b\0\0\0\0\x03\0\x18\x39\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x0b\x06\0\0\0\0\x03\0\x70\x39\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0b\
+\x1a\0\0\0\0\x03\0\xc8\x39\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbb\x14\0\0\0\0\x03\0\
+\x20\x3a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa8\x0f\0\0\0\0\x03\0\x88\x3a\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xa7\x0a\0\0\0\0\x03\0\xe0\x3a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xad\
+\x05\0\0\0\0\x03\0\x38\x3b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xad\x19\0\0\0\0\x03\0\
+\x90\x3b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5d\x14\0\0\0\0\x03\0\xe8\x3b\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x41\x0f\0\0\0\0\x03\0\x40\x3c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x49\
+\x0a\0\0\0\0\x03\0\x98\x3c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x46\x05\0\0\0\0\x03\0\
+\xf0\x3c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x46\x19\0\0\0\0\x03\0\x48\x3d\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xed\x13\0\0\0\0\x03\0\xa0\x3d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe3\
+\x0e\0\0\0\0\x03\0\xf8\x3d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe2\x09\0\0\0\0\x03\0\
+\x50\x3e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe8\x04\0\0\0\0\x03\0\xa8\x3e\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xe8\x18\0\0\0\0\x03\0\0\x3f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8f\
+\x13\0\0\0\0\x03\0\x58\x3f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x85\x0e\0\0\0\0\x03\0\
+\xb0\x3f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x84\x09\0\0\0\0\x03\0\x08\x40\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x8a\x04\0\0\0\0\x03\0\x60\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8a\
+\x18\0\0\0\0\x03\0\xb8\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x31\x13\0\0\0\0\x03\0\
+\x10\x41\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x27\x0e\0\0\0\0\x03\0\x68\x41\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x26\x09\0\0\0\0\x03\0\xc0\x41\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x23\
+\x04\0\0\0\0\x03\0\x18\x42\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2c\x18\0\0\0\0\x03\0\
+\x70\x42\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd3\x12\0\0\0\0\x03\0\xc8\x42\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xc0\x0d\0\0\0\0\x03\0\x20\x43\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbf\
+\x08\0\0\0\0\x03\0\x78\x43\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbc\x03\0\0\0\0\x03\0\
+\xd0\x43\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc5\x17\0\0\0\0\x03\0\x28\x44\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x6c\x12\0\0\0\0\x03\0\x80\x44\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x59\
+\x0d\0\0\0\0\x03\0\xd0\x44\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x58\x08\0\0\0\0\x03\0\
+\x38\x45\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x55\x03\0\0\0\0\x03\0\x90\x45\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x5e\x17\0\0\0\0\x03\0\xe8\x45\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x05\
+\x12\0\0\0\0\x03\0\x40\x46\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf2\x0c\0\0\0\0\x03\0\
+\x98\x46\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf1\x07\0\0\0\0\x03\0\xf0\x46\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xee\x02\0\0\0\0\x03\0\x48\x47\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf7\
+\x16\0\0\0\0\x03\0\xa0\x47\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9e\x11\0\0\0\0\x03\0\
+\xf8\x47\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8b\x0c\0\0\0\0\x03\0\x50\x48\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x8a\x07\0\0\0\0\x03\0\xa8\x48\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x87\
+\x02\0\0\0\0\x03\0\0\x49\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x60\x1a\0\0\0\0\x03\0\x58\
+\x49\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x15\0\0\0\0\x03\0\xb0\x49\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xfd\x0f\0\0\0\0\x03\0\x08\x4a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xfc\x0a\
+\0\0\0\0\x03\0\x60\x4a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x06\0\0\0\0\x03\0\xb8\
+\x4a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x1a\0\0\0\0\x03\0\x10\x4b\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xb2\x14\0\0\0\0\x03\0\x68\x4b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9f\x0f\
+\0\0\0\0\x03\0\xc0\x4b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9e\x0a\0\0\0\0\x03\0\x18\
+\x4c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa4\x05\0\0\0\0\x03\0\x70\x4c\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xa4\x19\0\0\0\0\x03\0\xc8\x4c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x54\x14\
+\0\0\0\0\x03\0\x20\x4d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x38\x0f\0\0\0\0\x03\0\x78\
+\x4d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\x0a\0\0\0\0\x03\0\xd0\x4d\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x3d\x05\0\0\0\0\x03\0\x28\x4e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3d\x19\
+\0\0\0\0\x03\0\x80\x4e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe4\x13\0\0\0\0\x03\0\xd8\
+\x4e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xda\x0e\0\0\0\0\x03\0\x30\x4f\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xd9\x09\0\0\0\0\x03\0\x80\x4f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xdf\x04\
+\0\0\0\0\x03\0\xe8\x4f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xdf\x18\0\0\0\0\x03\0\x40\
+\x50\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x86\x13\0\0\0\0\x03\0\x98\x50\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x7c\x0e\0\0\0\0\x03\0\xf0\x50\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7b\x09\
+\0\0\0\0\x03\0\x48\x51\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81\x04\0\0\0\0\x03\0\xa0\
+\x51\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81\x18\0\0\0\0\x03\0\xf8\x51\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x28\x13\0\0\0\0\x03\0\x50\x52\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x0e\
+\0\0\0\0\x03\0\xa8\x52\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1d\x09\0\0\0\0\x03\0\0\x53\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1a\x04\0\0\0\0\x03\0\x58\x53\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\x23\x18\0\0\0\0\x03\0\xb0\x53\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xca\x12\0\0\
+\0\0\x03\0\x08\x54\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb7\x0d\0\0\0\0\x03\0\x60\x54\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\xb6\x08\0\0\0\0\x03\0\xb8\x54\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\xb3\x03\0\0\0\0\x03\0\x10\x55\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbc\x17\0\0\0\
+\0\x03\0\x68\x55\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x63\x12\0\0\0\0\x03\0\xc0\x55\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\x50\x0d\0\0\0\0\x03\0\x18\x56\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\x4f\x08\0\0\0\0\x03\0\x70\x56\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4c\x03\0\0\0\0\
+\x03\0\xc8\x56\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x55\x17\0\0\0\0\x03\0\x20\x57\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\xfc\x11\0\0\0\0\x03\0\x78\x57\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\xe9\x0c\0\0\0\0\x03\0\xd0\x57\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe8\x07\0\0\0\0\
+\x03\0\x28\x58\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe5\x02\0\0\0\0\x03\0\x80\x58\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\xee\x16\0\0\0\0\x03\0\xd8\x58\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\x95\x11\0\0\0\0\x03\0\x30\x59\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x82\x0c\0\0\0\0\
+\x03\0\x88\x59\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81\x07\0\0\0\0\x03\0\xe0\x59\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x7e\x02\0\0\0\0\x03\0\x30\x5a\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\x57\x1a\0\0\0\0\x03\0\x98\x5a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x07\x15\0\0\0\0\
+\x03\0\xf8\x5a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf4\x0f\0\0\0\0\x03\0\x50\x5b\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\xf3\x0a\0\0\0\0\x03\0\xa8\x5b\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\xf9\x05\0\0\0\0\x03\0\0\x5c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf9\x19\0\0\0\0\x03\
+\0\x58\x5c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa9\x14\0\0\0\0\x03\0\xb0\x5c\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x96\x0f\0\0\0\0\x03\0\x08\x5d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x95\x0a\0\0\0\0\x03\0\x60\x5d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9b\x05\0\0\0\0\x03\
+\0\xb8\x5d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9b\x19\0\0\0\0\x03\0\x10\x5e\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x4b\x14\0\0\0\0\x03\0\x68\x5e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x2f\x0f\0\0\0\0\x03\0\xc0\x5e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x37\x0a\0\0\0\0\x03\
+\0\x18\x5f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x34\x05\0\0\0\0\x03\0\x70\x5f\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x34\x19\0\0\0\0\x03\0\xc8\x5f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xdb\x13\0\0\0\0\x03\0\x20\x60\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd1\x0e\0\0\0\0\x03\
+\0\x78\x60\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd0\x09\0\0\0\0\x03\0\xd0\x60\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xd6\x04\0\0\0\0\x03\0\x28\x61\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xd6\x18\0\0\0\0\x03\0\x80\x61\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7d\x13\0\0\0\0\x03\
+\0\xd8\x61\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x73\x0e\0\0\0\0\x03\0\x30\x62\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x72\x09\0\0\0\0\x03\0\x88\x62\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x78\x04\0\0\0\0\x03\0\xe0\x62\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x78\x18\0\0\0\0\x03\
+\0\x38\x63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1f\x13\0\0\0\0\x03\0\x90\x63\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x15\x0e\0\0\0\0\x03\0\xe8\x63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x14\x09\0\0\0\0\x03\0\x40\x64\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x11\x04\0\0\0\0\x03\
+\0\x98\x64\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1a\x18\0\0\0\0\x03\0\xe8\x64\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xc1\x12\0\0\0\0\x03\0\x48\x65\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xae\x0d\0\0\0\0\x03\0\xa0\x65\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xad\x08\0\0\0\0\x03\
+\0\xf8\x65\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xaa\x03\0\0\0\0\x03\0\x50\x66\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xb3\x17\0\0\0\0\x03\0\xa8\x66\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x5a\x12\0\0\0\0\x03\0\0\x67\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x47\x0d\0\0\0\0\x03\0\
+\x58\x67\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x46\x08\0\0\0\0\x03\0\xb0\x67\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x43\x03\0\0\0\0\x03\0\x08\x68\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4c\
+\x17\0\0\0\0\x03\0\x60\x68\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf3\x11\0\0\0\0\x03\0\
+\xb8\x68\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe0\x0c\0\0\0\0\x03\0\x10\x69\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xdf\x07\0\0\0\0\x03\0\x68\x69\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xdc\
+\x02\0\0\0\0\x03\0\xc0\x69\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe5\x16\0\0\0\0\x03\0\
+\x18\x6a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8c\x11\0\0\0\0\x03\0\x70\x6a\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x79\x0c\0\0\0\0\x03\0\xc8\x6a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x78\
+\x07\0\0\0\0\x03\0\x20\x6b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x75\x02\0\0\0\0\x03\0\
+\x78\x6b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4e\x1a\0\0\0\0\x03\0\xd0\x6b\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xfe\x14\0\0\0\0\x03\0\x28\x6c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xeb\
+\x0f\0\0\0\0\x03\0\x80\x6c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xea\x0a\0\0\0\0\x03\0\
+\xd8\x6c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf0\x05\0\0\0\0\x03\0\x30\x6d\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xf0\x19\0\0\0\0\x03\0\x88\x6d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa0\
+\x14\0\0\0\0\x03\0\xe0\x6d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8d\x0f\0\0\0\0\x03\0\
+\x38\x6e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8c\x0a\0\0\0\0\x03\0\x90\x6e\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x92\x05\0\0\0\0\x03\0\xe8\x6e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x92\
+\x19\0\0\0\0\x03\0\x40\x6f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x11\x0a\0\0\0\0\x03\0\
+\xe0\x6f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1a\x11\0\0\0\0\x03\0\x70\x90\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x02\x02\0\0\0\0\x03\0\xa8\x70\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x13\
+\x16\0\0\0\0\x03\0\0\x71\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe6\x10\0\0\0\0\x03\0\x58\
+\x71\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xec\x0b\0\0\0\0\x03\0\xb0\x71\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xe2\x06\0\0\0\0\x03\0\x08\x72\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xdf\x01\
+\0\0\0\0\x03\0\x60\x72\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf9\x15\0\0\0\0\x03\0\xb8\
+\x72\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc3\x10\0\0\0\0\x03\0\x10\x73\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xc9\x0b\0\0\0\0\x03\0\x68\x73\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc8\x06\
+\0\0\0\0\x03\0\xc0\x73\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbc\x01\0\0\0\0\x03\0\x18\
+\x74\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd6\x15\0\0\0\0\x03\0\x70\x74\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xa9\x10\0\0\0\0\x03\0\xc8\x74\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xaf\x0b\
+\0\0\0\0\x03\0\x20\x75\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xae\x06\0\0\0\0\x03\0\x78\
+\x75\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa2\x01\0\0\0\0\x03\0\xd0\x75\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xbc\x15\0\0\0\0\x03\0\x28\x76\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8f\x10\
+\0\0\0\0\x03\0\x80\x76\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x95\x0b\0\0\0\0\x03\0\xd8\
+\x76\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x94\x06\0\0\0\0\x03\0\x30\x77\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x88\x01\0\0\0\0\x03\0\x88\x77\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa2\x15\
+\0\0\0\0\x03\0\xe0\x77\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x75\x10\0\0\0\0\x03\0\x38\
+\x78\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7b\x0b\0\0\0\0\x03\0\x90\x78\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x7a\x06\0\0\0\0\x03\0\xe8\x78\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6e\x01\
+\0\0\0\0\x03\0\x40\x79\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x88\x15\0\0\0\0\x03\0\x98\
+\x79\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5b\x10\0\0\0\0\x03\0\xf0\x79\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x61\x0b\0\0\0\0\x03\0\x48\x7a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x60\x06\
+\0\0\0\0\x03\0\xa0\x7a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x54\x01\0\0\0\0\x03\0\xf0\
+\x7a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x98\x16\0\0\0\0\x03\0\x58\x7b\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x61\x11\0\0\0\0\x03\0\xb0\x7b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x55\x0c\
+\0\0\0\0\x03\0\x08\x7c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x54\x07\0\0\0\0\x03\0\x60\
+\x7c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x51\x02\0\0\0\0\x03\0\xb8\x7c\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x7d\x16\0\0\0\0\x03\0\x10\x7d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x46\x11\
+\0\0\0\0\x03\0\x68\x7d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3a\x0c\0\0\0\0\x03\0\xc0\
+\x7d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x39\x07\0\0\0\0\x03\0\x18\x7e\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x36\x02\0\0\0\0\x03\0\x70\x7e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x50\x16\
+\0\0\0\0\x03\0\xc8\x7e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x23\x11\0\0\0\0\x03\0\x20\
+\x7f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x17\x0c\0\0\0\0\x03\0\x78\x7f\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x16\x07\0\0\0\0\x03\0\xd0\x7f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x13\x02\
+\0\0\0\0\x03\0\x28\x80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2d\x16\0\0\0\0\x03\0\x80\
+\x80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x11\0\0\0\0\x03\0\xd8\x80\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\xfd\x0b\0\0\0\0\x03\0\x30\x81\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xfc\x06\0\
+\0\0\0\x03\0\x88\x81\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf9\x01\0\0\0\0\x03\0\xe0\x81\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0a\x16\0\0\0\0\x03\0\x38\x82\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\xdd\x10\0\0\0\0\x03\0\x90\x82\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe3\x0b\0\0\
+\0\0\x03\0\xe8\x82\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd9\x06\0\0\0\0\x03\0\x40\x83\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\xd6\x01\0\0\0\0\x03\0\x98\x83\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\xf0\x15\0\0\0\0\x03\0\xf0\x83\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xba\x10\0\0\0\
+\0\x03\0\x48\x84\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc0\x0b\0\0\0\0\x03\0\xa8\x84\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\xbf\x06\0\0\0\0\x03\0\x10\x85\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\xb3\x01\0\0\0\0\x03\0\x70\x85\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xcd\x15\0\0\0\0\
+\x03\0\xc8\x85\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa0\x10\0\0\0\0\x03\0\x28\x86\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\xa6\x0b\0\0\0\0\x03\0\x80\x86\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\xa5\x06\0\0\0\0\x03\0\xd8\x86\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x99\x01\0\0\0\0\
+\x03\0\x30\x87\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb3\x15\0\0\0\0\x03\0\x88\x87\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x86\x10\0\0\0\0\x03\0\xe0\x87\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\x8c\x0b\0\0\0\0\x03\0\x38\x88\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8b\x06\0\0\0\0\
+\x03\0\x90\x88\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7f\x01\0\0\0\0\x03\0\xe8\x88\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x99\x15\0\0\0\0\x03\0\x40\x89\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\x6c\x10\0\0\0\0\x03\0\x98\x89\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x72\x0b\0\0\0\0\
+\x03\0\xf0\x89\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x71\x06\0\0\0\0\x03\0\x48\x8a\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x65\x01\0\0\0\0\x03\0\xa0\x8a\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\x7f\x15\0\0\0\0\x03\0\xf8\x8a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x52\x10\0\0\0\0\
+\x03\0\x50\x8b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x58\x0b\0\0\0\0\x03\0\xa8\x8b\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x57\x06\0\0\0\0\x03\0\0\x8c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x4b\x01\0\0\0\0\x03\0\x58\x8c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8f\x16\0\0\0\0\x03\
+\0\xb0\x8c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x58\x11\0\0\0\0\x03\0\x08\x8d\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x4c\x0c\0\0\0\0\x03\0\x60\x8d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x4b\x07\0\0\0\0\x03\0\xb8\x8d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x48\x02\0\0\0\0\x03\
+\0\x10\x8e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x74\x16\0\0\0\0\x03\0\x68\x8e\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x3d\x11\0\0\0\0\x03\0\xc0\x8e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x31\x0c\0\0\0\0\x03\0\x18\x8f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x30\x07\0\0\0\0\x03\
+\0\x70\x8f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2d\x02\0\0\0\0\x03\0\xc8\x8f\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x47\x16\0\0\0\0\x03\0\x20\x90\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x0e\x0c\0\0\0\0\x03\0\x78\xf2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0d\x07\0\0\0\0\x03\
+\0\x88\xf2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xcd\x01\0\0\0\0\x03\0\xb0\x90\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xe7\x15\0\0\0\0\x03\0\xc0\x90\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x0c\x0e\0\0\0\0\x03\0\x70\x91\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0b\x09\0\0\0\0\x03\
+\0\xd8\x91\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\x04\0\0\0\0\x03\0\x48\x92\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x11\x18\0\0\0\0\x03\0\xb0\x92\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xb8\x12\0\0\0\0\x03\0\x10\x93\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa5\x0d\0\0\0\0\x03\
+\0\x70\x93\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa4\x08\0\0\0\0\x03\0\xd0\x93\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xa1\x03\0\0\0\0\x03\0\x30\x94\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xaa\x17\0\0\0\0\x03\0\x90\x94\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x51\x12\0\0\0\0\x03\
+\0\xf0\x94\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3e\x0d\0\0\0\0\x03\0\x50\x95\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x3d\x08\0\0\0\0\x03\0\xb0\x95\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x3a\x03\0\0\0\0\x03\0\x10\x96\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x43\x17\0\0\0\0\x03\
+\0\x70\x96\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xea\x11\0\0\0\0\x03\0\xd0\x96\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xd7\x0c\0\0\0\0\x03\0\x30\x97\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xd6\x07\0\0\0\0\x03\0\x90\x97\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd3\x02\0\0\0\0\x03\
+\0\xf0\x97\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xdc\x16\0\0\0\0\x03\0\x50\x98\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x83\x11\0\0\0\0\x03\0\xb0\x98\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x70\x0c\0\0\0\0\x03\0\x10\x99\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6f\x07\0\0\0\0\x03\
+\0\x70\x99\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6c\x02\0\0\0\0\x03\0\xd0\x99\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x45\x1a\0\0\0\0\x03\0\x30\x9a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xf5\x14\0\0\0\0\x03\0\x90\x9a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe2\x0f\0\0\0\0\x03\
+\0\xf0\x9a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe1\x0a\0\0\0\0\x03\0\x50\x9b\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xe7\x05\0\0\0\0\x03\0\xb0\x9b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xe7\x19\0\0\0\0\x03\0\x10\x9c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x97\x14\0\0\0\0\x03\
+\0\x70\x9c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x84\x0f\0\0\0\0\x03\0\xc8\x9c\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x83\x0a\0\0\0\0\x03\0\x38\x9d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x89\x05\0\0\0\0\x03\0\x90\x9d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x89\x19\0\0\0\0\x03\
+\0\xe8\x9d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x39\x14\0\0\0\0\x03\0\x40\x9e\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x26\x0f\0\0\0\0\x03\0\x98\x9e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x2e\x0a\0\0\0\0\x03\0\xf0\x9e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2b\x05\0\0\0\0\x03\
+\0\x48\x9f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2b\x19\0\0\0\0\x03\0\xa0\x9f\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xd2\x13\0\0\0\0\x03\0\xf8\x9f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xc8\x0e\0\0\0\0\x03\0\x50\xa0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc7\x09\0\0\0\0\x03\
+\0\xa8\xa0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xcd\x04\0\0\0\0\x03\0\0\xa1\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xcd\x18\0\0\0\0\x03\0\x58\xa1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x74\
+\x13\0\0\0\0\x03\0\xb0\xa1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6a\x0e\0\0\0\0\x03\0\
+\x08\xa2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x69\x09\0\0\0\0\x03\0\x60\xa2\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x66\x04\0\0\0\0\x03\0\xb8\xa2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6f\
+\x18\0\0\0\0\x03\0\x10\xa3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x13\0\0\0\0\x03\0\
+\x68\xa3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\x0e\0\0\0\0\x03\0\xc0\xa3\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x02\x09\0\0\0\0\x03\0\x18\xa4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\
+\x03\0\0\0\0\x03\0\x70\xa4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\x18\0\0\0\0\x03\0\
+\xc8\xa4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xaf\x12\0\0\0\0\x03\0\x20\xa5\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x9c\x0d\0\0\0\0\x03\0\x78\xa5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9b\
+\x08\0\0\0\0\x03\0\xd0\xa5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x98\x03\0\0\0\0\x03\0\
+\x28\xa6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa1\x17\0\0\0\0\x03\0\x80\xa6\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x48\x12\0\0\0\0\x03\0\xd8\xa6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x35\
+\x0d\0\0\0\0\x03\0\x30\xa7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x34\x08\0\0\0\0\x03\0\
+\x80\xa7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x31\x03\0\0\0\0\x03\0\xe8\xa7\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x3a\x17\0\0\0\0\x03\0\x40\xa8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe1\
+\x11\0\0\0\0\x03\0\x98\xa8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xce\x0c\0\0\0\0\x03\0\
+\xf0\xa8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xcd\x07\0\0\0\0\x03\0\x48\xa9\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xca\x02\0\0\0\0\x03\0\xa0\xa9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd3\
+\x16\0\0\0\0\x03\0\xf8\xa9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7a\x11\0\0\0\0\x03\0\
+\x50\xaa\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x67\x0c\0\0\0\0\x03\0\xa8\xaa\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x66\x07\0\0\0\0\x03\0\0\xab\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x63\
+\x02\0\0\0\0\x03\0\x58\xab\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa3\x1a\0\0\0\0\x03\0\
+\xb0\xab\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x53\x15\0\0\0\0\x03\0\x08\xac\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x40\x10\0\0\0\0\x03\0\x60\xac\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3f\
+\x0b\0\0\0\0\x03\0\xb8\xac\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x45\x06\0\0\0\0\x03\0\
+\x10\xad\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3b\x1a\0\0\0\0\x03\0\x68\xad\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xeb\x14\0\0\0\0\x03\0\xc0\xad\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd8\
+\x0f\0\0\0\0\x03\0\x18\xae\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd7\x0a\0\0\0\0\x03\0\
+\x70\xae\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xdd\x05\0\0\0\0\x03\0\xc8\xae\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xdd\x19\0\0\0\0\x03\0\x20\xaf\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8d\
+\x14\0\0\0\0\x03\0\x78\xaf\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7a\x0f\0\0\0\0\x03\0\
+\xd0\xaf\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x79\x0a\0\0\0\0\x03\0\x28\xb0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x7f\x05\0\0\0\0\x03\0\x80\xb0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7f\
+\x19\0\0\0\0\x03\0\xd8\xb0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2f\x14\0\0\0\0\x03\0\
+\x30\xb1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1c\x0f\0\0\0\0\x03\0\x88\xb1\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x24\x0a\0\0\0\0\x03\0\xe0\xb1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x21\
+\x05\0\0\0\0\x03\0\x38\xb2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x21\x19\0\0\0\0\x03\0\
+\xa0\xb2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc8\x13\0\0\0\0\x03\0\xf8\xb2\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xbe\x0e\0\0\0\0\x03\0\x50\xb3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbd\
+\x09\0\0\0\0\x03\0\xa8\xb3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc3\x04\0\0\0\0\x03\0\0\
+\xb4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc3\x18\0\0\0\0\x03\0\x58\xb4\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x6a\x13\0\0\0\0\x03\0\xb0\xb4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x60\x0e\
+\0\0\0\0\x03\0\x08\xb5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5f\x09\0\0\0\0\x03\0\x60\
+\xb5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5c\x04\0\0\0\0\x03\0\xb8\xb5\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x65\x18\0\0\0\0\x03\0\x10\xb6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0c\x13\
+\0\0\0\0\x03\0\x68\xb6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf9\x0d\0\0\0\0\x03\0\xc0\
+\xb6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf8\x08\0\0\0\0\x03\0\x18\xb7\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xf5\x03\0\0\0\0\x03\0\x70\xb7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xfe\x17\
+\0\0\0\0\x03\0\xc8\xb7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa5\x12\0\0\0\0\x03\0\x20\
+\xb8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x92\x0d\0\0\0\0\x03\0\x78\xb8\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x91\x08\0\0\0\0\x03\0\xd0\xb8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8e\x03\
+\0\0\0\0\x03\0\x28\xb9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x97\x17\0\0\0\0\x03\0\x80\
+\xb9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3e\x12\0\0\0\0\x03\0\xd8\xb9\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x2b\x0d\0\0\0\0\x03\0\x30\xba\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2a\x08\
+\0\0\0\0\x03\0\x88\xba\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x27\x03\0\0\0\0\x03\0\xe0\
+\xba\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x30\x17\0\0\0\0\x03\0\x38\xbb\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xd7\x11\0\0\0\0\x03\0\x90\xbb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc4\x0c\
+\0\0\0\0\x03\0\xe8\xbb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc3\x07\0\0\0\0\x03\0\x40\
+\xbc\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc0\x02\0\0\0\0\x03\0\x98\xbc\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x99\x1a\0\0\0\0\x03\0\xf0\xbc\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x49\x15\
+\0\0\0\0\x03\0\x58\xbd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x36\x10\0\0\0\0\x03\0\xb0\
+\xbd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x35\x0b\0\0\0\0\x03\0\x08\xbe\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x3b\x06\0\0\0\0\x03\0\x60\xbe\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x31\x1a\
+\0\0\0\0\x03\0\xb8\xbe\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe1\x14\0\0\0\0\x03\0\x10\
+\xbf\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xce\x0f\0\0\0\0\x03\0\x68\xbf\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xcd\x0a\0\0\0\0\x03\0\xc0\xbf\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd3\x05\
+\0\0\0\0\x03\0\x18\xc0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd3\x19\0\0\0\0\x03\0\x70\
+\xc0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x83\x14\0\0\0\0\x03\0\xc8\xc0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x70\x0f\0\0\0\0\x03\0\x20\xc1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6f\x0a\
+\0\0\0\0\x03\0\x78\xc1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x75\x05\0\0\0\0\x03\0\xd0\
+\xc1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x75\x19\0\0\0\0\x03\0\x28\xc2\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x25\x14\0\0\0\0\x03\0\x80\xc2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x12\x0f\
+\0\0\0\0\x03\0\xd8\xc2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1a\x0a\0\0\0\0\x03\0\x30\
+\xc3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x17\x05\0\0\0\0\x03\0\x88\xc3\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x17\x19\0\0\0\0\x03\0\xe0\xc3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbe\x13\
+\0\0\0\0\x03\0\x38\xc4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb4\x0e\0\0\0\0\x03\0\x90\
+\xc4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb3\x09\0\0\0\0\x03\0\xe8\xc4\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xb9\x04\0\0\0\0\x03\0\x40\xc5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb9\x18\
+\0\0\0\0\x03\0\x98\xc5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x60\x13\0\0\0\0\x03\0\xf0\
+\xc5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x56\x0e\0\0\0\0\x03\0\x48\xc6\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x55\x09\0\0\0\0\x03\0\xa0\xc6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x52\x04\
+\0\0\0\0\x03\0\xf8\xc6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5b\x18\0\0\0\0\x03\0\x50\
+\xc7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x13\0\0\0\0\x03\0\xa0\xc7\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xef\x0d\0\0\0\0\x03\0\x08\xc8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xee\x08\
+\0\0\0\0\x03\0\x68\xc8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xeb\x03\0\0\0\0\x03\0\xc0\
+\xc8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf4\x17\0\0\0\0\x03\0\x18\xc9\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x9b\x12\0\0\0\0\x03\0\x70\xc9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x88\x0d\
+\0\0\0\0\x03\0\xc8\xc9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x87\x08\0\0\0\0\x03\0\x20\
+\xca\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x84\x03\0\0\0\0\x03\0\x78\xca\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x8d\x17\0\0\0\0\x03\0\xd0\xca\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x34\x12\
+\0\0\0\0\x03\0\x28\xcb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x21\x0d\0\0\0\0\x03\0\x80\
+\xcb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x20\x08\0\0\0\0\x03\0\xd8\xcb\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x1d\x03\0\0\0\0\x03\0\x30\xcc\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x26\x17\
+\0\0\0\0\x03\0\x88\xcc\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xcd\x11\0\0\0\0\x03\0\xe0\
+\xcc\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xba\x0c\0\0\0\0\x03\0\x38\xcd\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xb9\x07\0\0\0\0\x03\0\x90\xcd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb6\x02\
+\0\0\0\0\x03\0\xe8\xcd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8f\x1a\0\0\0\0\x03\0\x40\
+\xce\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3f\x15\0\0\0\0\x03\0\x98\xce\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x2c\x10\0\0\0\0\x03\0\xf0\xce\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2b\x0b\
+\0\0\0\0\x03\0\x48\xcf\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x31\x06\0\0\0\0\x03\0\xa0\
+\xcf\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x27\x1a\0\0\0\0\x03\0\xf8\xcf\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xd7\x14\0\0\0\0\x03\0\x50\xd0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc4\x0f\
+\0\0\0\0\x03\0\xa8\xd0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc3\x0a\0\0\0\0\x03\0\0\xd1\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc9\x05\0\0\0\0\x03\0\x58\xd1\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\xc9\x19\0\0\0\0\x03\0\xb0\xd1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x79\x14\0\0\
+\0\0\x03\0\x08\xd2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x66\x0f\0\0\0\0\x03\0\x58\xd2\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\x65\x0a\0\0\0\0\x03\0\xc0\xd2\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\x6b\x05\0\0\0\0\x03\0\x18\xd3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6b\x19\0\0\0\
+\0\x03\0\x70\xd3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x12\x14\0\0\0\0\x03\0\xc8\xd3\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\x08\x0f\0\0\0\0\x03\0\x20\xd4\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\x07\x0a\0\0\0\0\x03\0\x78\xd4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0d\x05\0\0\0\0\
+\x03\0\xd0\xd4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0d\x19\0\0\0\0\x03\0\x28\xd5\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\xb4\x13\0\0\0\0\x03\0\x80\xd5\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\xaa\x0e\0\0\0\0\x03\0\xd8\xd5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa9\x09\0\0\0\0\
+\x03\0\x30\xd6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xaf\x04\0\0\0\0\x03\0\x88\xd6\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\xaf\x18\0\0\0\0\x03\0\xe0\xd6\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\x56\x13\0\0\0\0\x03\0\x38\xd7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4c\x0e\0\0\0\0\
+\x03\0\x90\xd7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4b\x09\0\0\0\0\x03\0\xe8\xd7\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x48\x04\0\0\0\0\x03\0\x40\xd8\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\x51\x18\0\0\0\0\x03\0\x98\xd8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf8\x12\0\0\0\0\
+\x03\0\xf0\xd8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe5\x0d\0\0\0\0\x03\0\x48\xd9\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\xe4\x08\0\0\0\0\x03\0\xa0\xd9\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\xe1\x03\0\0\0\0\x03\0\xf8\xd9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xea\x17\0\0\0\0\
+\x03\0\x50\xda\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x91\x12\0\0\0\0\x03\0\xa8\xda\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x7e\x0d\0\0\0\0\x03\0\0\xdb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x7d\x08\0\0\0\0\x03\0\x58\xdb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7a\x03\0\0\0\0\x03\
+\0\xb0\xdb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x83\x17\0\0\0\0\x03\0\x08\xdc\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x2a\x12\0\0\0\0\x03\0\x60\xdc\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x17\x0d\0\0\0\0\x03\0\xb8\xdc\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x08\0\0\0\0\x03\
+\0\x08\xdd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x13\x03\0\0\0\0\x03\0\x70\xdd\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x1c\x17\0\0\0\0\x03\0\xc8\xdd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xc3\x11\0\0\0\0\x03\0\x20\xde\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb0\x0c\0\0\0\0\x03\
+\0\x78\xde\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xaf\x07\0\0\0\0\x03\0\xd0\xde\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xac\x02\0\0\0\0\x03\0\x28\xdf\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x85\x1a\0\0\0\0\x03\0\x80\xdf\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x35\x15\0\0\0\0\x03\
+\0\xd8\xdf\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x22\x10\0\0\0\0\x03\0\x30\xe0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x21\x0b\0\0\0\0\x03\0\x88\xe0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x27\x06\0\0\0\0\x03\0\xe0\xe0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1d\x1a\0\0\0\0\x03\
+\0\x38\xe1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xcd\x14\0\0\0\0\x03\0\x90\xe1\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\xba\x0f\0\0\0\0\x03\0\xe8\xe1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xb9\x0a\0\0\0\0\x03\0\x40\xe2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbf\x05\0\0\0\0\x03\
+\0\x98\xe2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbf\x19\0\0\0\0\x03\0\xf0\xe2\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x6f\x14\0\0\0\0\x03\0\x48\xe3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x5c\x0f\0\0\0\0\x03\0\xa0\xe3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5b\x0a\0\0\0\0\x03\
+\0\xf8\xe3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x61\x05\0\0\0\0\x03\0\x50\xe4\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\x61\x19\0\0\0\0\x03\0\xa8\xe4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x08\x14\0\0\0\0\x03\0\0\xe5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xfe\x0e\0\0\0\0\x03\0\
+\x58\xe5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xfd\x09\0\0\0\0\x03\0\xb0\xe5\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x03\x05\0\0\0\0\x03\0\x08\xe6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\
+\x19\0\0\0\0\x03\0\x60\xe6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xaa\x13\0\0\0\0\x03\0\
+\xc0\xe6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa0\x0e\0\0\0\0\x03\0\x28\xe7\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x9f\x09\0\0\0\0\x03\0\x88\xe7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa5\
+\x04\0\0\0\0\x03\0\xe0\xe7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa5\x18\0\0\0\0\x03\0\
+\x40\xe8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4c\x13\0\0\0\0\x03\0\x98\xe8\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x42\x0e\0\0\0\0\x03\0\xf0\xe8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x41\
+\x09\0\0\0\0\x03\0\x48\xe9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3e\x04\0\0\0\0\x03\0\
+\xa0\xe9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x47\x18\0\0\0\0\x03\0\xf8\xe9\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\xee\x12\0\0\0\0\x03\0\x50\xea\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xdb\
+\x0d\0\0\0\0\x03\0\xa8\xea\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xda\x08\0\0\0\0\x03\0\0\
+\xeb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd7\x03\0\0\0\0\x03\0\x58\xeb\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xe0\x17\0\0\0\0\x03\0\xb0\xeb\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x87\x12\
+\0\0\0\0\x03\0\x08\xec\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x74\x0d\0\0\0\0\x03\0\x60\
+\xec\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x73\x08\0\0\0\0\x03\0\xb8\xec\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x70\x03\0\0\0\0\x03\0\x10\xed\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x79\x17\
+\0\0\0\0\x03\0\x68\xed\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x20\x12\0\0\0\0\x03\0\xc0\
+\xed\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0d\x0d\0\0\0\0\x03\0\x18\xee\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x0c\x08\0\0\0\0\x03\0\x70\xee\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x09\x03\
+\0\0\0\0\x03\0\xc8\xee\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x12\x17\0\0\0\0\x03\0\x20\
+\xef\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb9\x11\0\0\0\0\x03\0\x78\xef\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xa6\x0c\0\0\0\0\x03\0\xd0\xef\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa5\x07\
+\0\0\0\0\x03\0\x28\xf0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa2\x02\0\0\0\0\x03\0\x80\
+\xf0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7b\x1a\0\0\0\0\x03\0\xd8\xf0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x2b\x15\0\0\0\0\x03\0\x30\xf1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x10\
+\0\0\0\0\x03\0\x88\xf1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x17\x0b\0\0\0\0\x03\0\xe0\
+\xf1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1d\x06\0\0\0\0\x03\0\x38\xf2\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x6f\x04\0\0\0\0\x03\0\x98\xf5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x24\x16\
+\0\0\0\0\x03\0\x18\xf3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf7\x10\0\0\0\0\x03\0\x30\
+\xf3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf3\x06\0\0\0\0\x03\0\xd0\xf3\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xf0\x01\0\0\0\0\x03\0\xf8\xf3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd4\x10\
+\0\0\0\0\x03\0\xa0\xf4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xda\x0b\0\0\0\0\x03\0\xc8\
+\xf4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5d\x15\0\0\x01\0\x07\0\x24\0\0\0\0\0\0\0\x0a\
+\0\0\0\0\0\0\0\0\0\0\0\x03\0\x07\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\
+\0\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\x0a\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x03\0\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\
+\0\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\x10\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x03\0\x11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\
+\0\x17\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\x19\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x03\0\x1b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc9\0\0\0\
+\x12\0\x03\0\0\0\0\0\0\0\0\0\xc8\xf6\0\0\0\0\0\0\xb1\0\0\0\x11\0\x06\0\0\0\0\0\
+\0\0\0\0\x20\0\0\0\0\0\0\0\xe7\0\0\0\x11\0\x08\0\0\0\0\0\0\0\0\0\x0d\0\0\0\0\0\
+\0\0\xa0\0\0\0\0\0\0\0\x01\0\0\0\xcc\x02\0\0\xc0\0\0\0\0\0\0\0\x01\0\0\0\xc1\
+\x02\0\0\x28\x01\0\0\0\0\0\0\x01\0\0\0\xc1\x02\0\0\xc8\xf5\0\0\0\0\0\0\x01\0\0\
+\0\xc1\x02\0\0\x90\xf6\0\0\0\0\0\0\x01\0\0\0\xc1\x02\0\0\x08\0\0\0\0\0\0\0\x03\
+\0\0\0\xc3\x02\0\0\x11\0\0\0\0\0\0\0\x03\0\0\0\xc5\x02\0\0\x15\0\0\0\0\0\0\0\
+\x03\0\0\0\xc9\x02\0\0\x1f\0\0\0\0\0\0\0\x03\0\0\0\xc7\x02\0\0\x23\0\0\0\0\0\0\
+\0\x03\0\0\0\xc4\x02\0\0\x27\0\0\0\0\0\0\0\x03\0\0\0\xc2\x02\0\0\x08\0\0\0\0\0\
+\0\0\x03\0\0\0\xc6\x02\0\0\x0c\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x10\0\0\0\0\
+\0\0\0\x03\0\0\0\xc6\x02\0\0\x14\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x18\0\0\0\
+\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x1c\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x20\0\0\
+\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x24\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x28\0\
+\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x2c\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x30\
+\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x34\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\
+\x38\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x3c\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\
+\0\x40\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x44\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\
+\0\0\x48\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x4c\0\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\x50\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x54\0\0\0\0\0\0\0\x03\0\0\0\
+\xc6\x02\0\0\x58\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x5c\0\0\0\0\0\0\0\x03\0\0\
+\0\xc6\x02\0\0\x60\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x64\0\0\0\0\0\0\0\x03\0\
+\0\0\xc6\x02\0\0\x68\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x6c\0\0\0\0\0\0\0\x03\
+\0\0\0\xc6\x02\0\0\x70\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x74\0\0\0\0\0\0\0\
+\x03\0\0\0\xc6\x02\0\0\x78\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x7c\0\0\0\0\0\0\
+\0\x03\0\0\0\xc6\x02\0\0\x80\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x84\0\0\0\0\0\
+\0\0\x03\0\0\0\xc6\x02\0\0\x88\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x8c\0\0\0\0\
+\0\0\0\x03\0\0\0\xc6\x02\0\0\x90\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x94\0\0\0\
+\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x98\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x9c\0\0\
+\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xa0\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xa4\0\
+\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xa8\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xac\
+\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xb0\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\
+\xb4\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xb8\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\
+\0\xbc\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xc0\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\
+\0\0\xc4\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xc8\0\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\xcc\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xd0\0\0\0\0\0\0\0\x03\0\0\0\
+\xc6\x02\0\0\xd4\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xd8\0\0\0\0\0\0\0\x03\0\0\
+\0\xc6\x02\0\0\xdc\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xe0\0\0\0\0\0\0\0\x03\0\
+\0\0\xc6\x02\0\0\xe4\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xe8\0\0\0\0\0\0\0\x03\
+\0\0\0\xc6\x02\0\0\xec\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xf0\0\0\0\0\0\0\0\
+\x03\0\0\0\xc6\x02\0\0\xf4\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xf8\0\0\0\0\0\0\
+\0\x03\0\0\0\xc6\x02\0\0\xfc\0\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\0\x01\0\0\0\0\
+\0\0\x03\0\0\0\xc6\x02\0\0\x04\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x08\x01\0\
+\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x0c\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x10\
+\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x14\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\
+\0\x18\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x1c\x01\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\x20\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x24\x01\0\0\0\0\0\0\x03\0\0\
+\0\xc6\x02\0\0\x28\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x2c\x01\0\0\0\0\0\0\
+\x03\0\0\0\xc6\x02\0\0\x30\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x34\x01\0\0\0\
+\0\0\0\x03\0\0\0\xc6\x02\0\0\x38\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x3c\x01\
+\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x40\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\
+\x44\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x48\x01\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\x4c\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x50\x01\0\0\0\0\0\0\x03\0\0\
+\0\xc6\x02\0\0\x54\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x58\x01\0\0\0\0\0\0\
+\x03\0\0\0\xc6\x02\0\0\x5c\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x60\x01\0\0\0\
+\0\0\0\x03\0\0\0\xc6\x02\0\0\x64\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x68\x01\
+\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x6c\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\
+\x70\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x74\x01\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\x78\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x7c\x01\0\0\0\0\0\0\x03\0\0\
+\0\xc6\x02\0\0\x80\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x84\x01\0\0\0\0\0\0\
+\x03\0\0\0\xc6\x02\0\0\x88\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x8c\x01\0\0\0\
+\0\0\0\x03\0\0\0\xc6\x02\0\0\x90\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x94\x01\
+\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x98\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\
+\x9c\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xa0\x01\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\xa4\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xa8\x01\0\0\0\0\0\0\x03\0\0\
+\0\xc6\x02\0\0\xac\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xb0\x01\0\0\0\0\0\0\
+\x03\0\0\0\xc6\x02\0\0\xb4\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xb8\x01\0\0\0\
+\0\0\0\x03\0\0\0\xc6\x02\0\0\xbc\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xc0\x01\
+\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xc4\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\
+\xc8\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xcc\x01\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\xd0\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xd4\x01\0\0\0\0\0\0\x03\0\0\
+\0\xc6\x02\0\0\xd8\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xdc\x01\0\0\0\0\0\0\
+\x03\0\0\0\xc6\x02\0\0\xe0\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xe4\x01\0\0\0\
+\0\0\0\x03\0\0\0\xc6\x02\0\0\xe8\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xec\x01\
+\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xf0\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\
+\xf4\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xf8\x01\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\xfc\x01\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\0\x02\0\0\0\0\0\0\x03\0\0\0\
+\xc6\x02\0\0\x04\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x08\x02\0\0\0\0\0\0\x03\
+\0\0\0\xc6\x02\0\0\x0c\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x10\x02\0\0\0\0\0\
+\0\x03\0\0\0\xc6\x02\0\0\x14\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x18\x02\0\0\
+\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x1c\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x20\
+\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x24\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\
+\0\x28\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x2c\x02\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\x30\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x34\x02\0\0\0\0\0\0\x03\0\0\
+\0\xc6\x02\0\0\x38\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x3c\x02\0\0\0\0\0\0\
+\x03\0\0\0\xc6\x02\0\0\x40\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x44\x02\0\0\0\
+\0\0\0\x03\0\0\0\xc6\x02\0\0\x48\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x4c\x02\
+\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x50\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\
+\x54\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x58\x02\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\x5c\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x60\x02\0\0\0\0\0\0\x03\0\0\
+\0\xc6\x02\0\0\x64\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x68\x02\0\0\0\0\0\0\
+\x03\0\0\0\xc6\x02\0\0\x6c\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x70\x02\0\0\0\
+\0\0\0\x03\0\0\0\xc6\x02\0\0\x74\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x78\x02\
+\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x7c\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\
+\x80\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x84\x02\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\x88\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x8c\x02\0\0\0\0\0\0\x03\0\0\
+\0\xc6\x02\0\0\x90\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x94\x02\0\0\0\0\0\0\
+\x03\0\0\0\xc6\x02\0\0\x98\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x9c\x02\0\0\0\
+\0\0\0\x03\0\0\0\xc6\x02\0\0\xa0\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xa4\x02\
+\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xa8\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\
+\xac\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xb0\x02\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\xb4\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xb8\x02\0\0\0\0\0\0\x03\0\0\
+\0\xc6\x02\0\0\xbc\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xc0\x02\0\0\0\0\0\0\
+\x03\0\0\0\xc6\x02\0\0\xc4\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xc8\x02\0\0\0\
+\0\0\0\x03\0\0\0\xc6\x02\0\0\xcc\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xd0\x02\
+\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xd4\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\
+\xd8\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xdc\x02\0\0\0\0\0\0\x03\0\0\0\xc6\
+\x02\0\0\xe0\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xe4\x02\0\0\0\0\0\0\x03\0\0\
+\0\xc6\x02\0\0\xe8\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xec\x02\0\0\0\0\0\0\
+\x03\0\0\0\xc6\x02\0\0\xf0\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xf4\x02\0\0\0\
+\0\0\0\x03\0\0\0\xc6\x02\0\0\xf8\x02\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\xfc\x02\
+\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\0\x03\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x04\
+\x03\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x08\x03\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\
+\0\x0c\x03\0\0\0\0\0\0\x03\0\0\0\xc6\x02\0\0\x08\0\0\0\0\0\0\0\x02\0\0\0\xc1\
+\x02\0\0\x10\0\0\0\0\0\0\0\x02\0\0\0\xc1\x02\0\0\x18\0\0\0\0\0\0\0\x02\0\0\0\
+\xc1\x02\0\0\x20\0\0\0\0\0\0\0\x02\0\0\0\xcd\x02\0\0\x28\0\0\0\0\0\0\0\x02\0\0\
+\0\xcc\x02\0\0\x30\0\0\0\0\0\0\0\x02\0\0\0\x02\0\0\0\x38\0\0\0\0\0\0\0\x02\0\0\
+\0\x02\0\0\0\x40\0\0\0\0\0\0\0\x02\0\0\0\x02\0\0\0\x48\0\0\0\0\0\0\0\x02\0\0\0\
+\x02\0\0\0\x50\0\0\0\0\0\0\0\x02\0\0\0\x02\0\0\0\x58\0\0\0\0\0\0\0\x02\0\0\0\
+\x02\0\0\0\x7c\x04\0\0\0\0\0\0\x04\0\0\0\xcc\x02\0\0\x94\x04\0\0\0\0\0\0\x03\0\
+\0\0\xc1\x02\0\0\xa0\x04\0\0\0\0\0\0\x03\0\0\0\xc1\x02\0\0\xac\x04\0\0\0\0\0\0\
+\x03\0\0\0\xc1\x02\0\0\xc4\x04\0\0\0\0\0\0\x04\0\0\0\xcd\x02\0\0\x2c\0\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x40\0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\0\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x60\0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\0\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\0\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xa0\0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\0\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xc0\0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\0\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xe0\0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\0\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x01\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x01\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x20\x01\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x01\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x40\x01\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x01\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x60\x01\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x01\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x80\x01\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x01\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x01\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x01\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x01\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x01\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x01\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\
+\x01\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x02\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\
+\x02\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x02\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x30\x02\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x02\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x50\x02\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x02\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x70\x02\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x02\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x90\x02\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x02\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xb0\x02\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x02\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xd0\x02\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x02\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xf0\x02\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x03\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x10\x03\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x03\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x03\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x03\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x50\x03\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x03\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x70\x03\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x03\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x90\x03\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x03\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x03\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x03\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x03\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x03\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x03\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x04\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x04\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x04\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x04\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\
+\x04\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x04\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x60\x04\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x04\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x80\x04\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x04\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xa0\x04\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x04\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x04\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x04\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xe0\x04\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x04\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\0\x05\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x05\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x20\x05\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x05\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x40\x05\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x05\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x60\x05\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x05\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x05\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x05\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xa0\x05\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x05\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xc0\x05\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x05\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x05\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x05\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x06\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x06\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x06\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x06\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x06\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x06\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x06\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\
+\x06\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x06\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x90\x06\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x06\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xb0\x06\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x06\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xd0\x06\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x06\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x06\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x07\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x10\x07\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x07\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x30\x07\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x07\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x50\x07\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x07\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x70\x07\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x07\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x90\x07\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x07\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xb0\x07\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x07\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x07\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x07\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xf0\x07\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x08\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x10\x08\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x08\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x30\x08\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x08\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x08\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x08\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x08\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x08\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x08\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\
+\x08\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x08\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xc0\x08\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x08\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xe0\x08\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x08\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\0\x09\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x09\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x20\x09\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x09\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x09\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x09\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x60\x09\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x09\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x80\x09\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x09\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xa0\x09\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x09\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xc0\x09\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x09\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xe0\x09\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x09\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\0\x0a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x0a\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x20\x0a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x0a\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x40\x0a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x0a\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x60\x0a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x0a\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x0a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x0a\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x0a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x0a\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x0a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\
+\x0a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x0a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xf0\x0a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x0b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x10\x0b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x0b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x30\x0b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x0b\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x50\x0b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x0b\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x70\x0b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x0b\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x0b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x0b\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xb0\x0b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x0b\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xd0\x0b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x0b\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xf0\x0b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x0c\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x10\x0c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x0c\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x30\x0c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x0c\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x0c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x0c\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x70\x0c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x0c\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x90\x0c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x0c\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x0c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x0c\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x0c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x0c\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x0c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x0d\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x0d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\
+\x0d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x0d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x40\x0d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x0d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x60\x0d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x0d\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x80\x0d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x0d\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xa0\x0d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x0d\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xc0\x0d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x0d\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x0d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x0d\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\0\x0e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x0e\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x20\x0e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x0e\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x40\x0e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x0e\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x60\x0e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x0e\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x80\x0e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x0e\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xa0\x0e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x0e\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x0e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x0e\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x0e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x0e\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x0f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x0f\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x0f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x0f\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x0f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x0f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x0f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x70\x0f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x0f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x90\x0f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x0f\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xb0\x0f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x0f\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xd0\x0f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x0f\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xf0\x0f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x10\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x10\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x10\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x30\x10\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x10\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x50\x10\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x10\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x70\x10\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x10\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x90\x10\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x10\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xb0\x10\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x10\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xd0\x10\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x10\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x10\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x11\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x10\x11\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x11\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x11\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x11\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x11\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x11\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x11\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\
+\x11\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x11\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x11\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x11\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xc0\x11\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x11\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xe0\x11\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x11\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\0\x12\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x12\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x20\x12\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x12\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x40\x12\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x12\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x12\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x12\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x80\x12\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x12\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xa0\x12\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x12\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xc0\x12\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x12\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xe0\x12\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x12\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\0\x13\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x13\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x13\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x13\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x40\x13\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x13\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x13\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x13\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x13\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x13\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x13\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\
+\x13\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x13\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x13\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x13\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xf0\x13\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x14\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x10\x14\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x14\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x30\x14\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x14\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x50\x14\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x14\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x70\x14\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x14\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x90\x14\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x14\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xb0\x14\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x14\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xd0\x14\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x14\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xf0\x14\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x15\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x10\x15\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x15\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x30\x15\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x15\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x50\x15\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x15\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x70\x15\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x15\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x15\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x15\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x15\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x15\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x15\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\
+\x15\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x15\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\
+\x16\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x16\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x16\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x16\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x40\x16\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x16\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x60\x16\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x16\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x80\x16\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x16\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xa0\x16\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x16\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xc0\x16\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x16\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xe0\x16\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x16\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\0\x17\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x17\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x20\x17\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x17\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x40\x17\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x17\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x60\x17\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x17\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x80\x17\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x17\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x17\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x17\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x17\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x17\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x17\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x17\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x18\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x18\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x18\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\
+\x18\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x18\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x50\x18\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x18\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x18\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x18\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x90\x18\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x18\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xb0\x18\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x18\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xd0\x18\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x18\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xf0\x18\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x19\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x10\x19\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x19\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x30\x19\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x19\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x50\x19\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x19\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x70\x19\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x19\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x90\x19\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x19\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xb0\x19\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x19\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x19\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x19\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x19\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x1a\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x1a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x1a\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x1a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x1a\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x1a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\
+\x1a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x1a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x80\x1a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x1a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xa0\x1a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x1a\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xc0\x1a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x1a\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xe0\x1a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x1a\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\0\x1b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x1b\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x20\x1b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x1b\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x40\x1b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x1b\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x60\x1b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x1b\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x80\x1b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x1b\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xa0\x1b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x1b\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xc0\x1b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x1b\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xe0\x1b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x1b\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\0\x1c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x1c\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x20\x1c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x1c\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x1c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x1c\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x1c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x1c\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x1c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\
+\x1c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x1c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xb0\x1c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x1c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xd0\x1c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x1c\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xf0\x1c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x1d\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x10\x1d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x1d\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x30\x1d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x1d\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x50\x1d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x1d\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x70\x1d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x1d\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x90\x1d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x1d\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x1d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x1d\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xd0\x1d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x1d\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xf0\x1d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x1e\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x10\x1e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x1e\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x30\x1e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x1e\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x50\x1e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x1e\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x1e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x1e\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x1e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x1e\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x1e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\
+\x1e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x1e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xe0\x1e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x1e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\0\x1f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x1f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x20\x1f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x1f\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x40\x1f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x1f\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x60\x1f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x1f\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x80\x1f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x1f\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xa0\x1f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x1f\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xc0\x1f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x1f\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xe0\x1f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x1f\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x20\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x20\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x20\x20\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x20\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x40\x20\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x20\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x60\x20\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x20\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x80\x20\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x20\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x20\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x20\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x20\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x20\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x20\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\
+\x20\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x21\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\
+\x21\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x21\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x30\x21\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x21\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x50\x21\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x21\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x70\x21\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x21\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x90\x21\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x21\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xb0\x21\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x21\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xd0\x21\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x21\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xf0\x21\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x22\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x10\x22\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x22\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x22\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x22\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x50\x22\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x22\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x70\x22\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x22\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x90\x22\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x22\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x22\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x22\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x22\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x22\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x22\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x23\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x23\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x23\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x23\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\
+\x23\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x23\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x60\x23\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x23\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x80\x23\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x23\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xa0\x23\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x23\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x23\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x23\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xe0\x23\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x23\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\0\x24\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x24\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x20\x24\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x24\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x40\x24\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x24\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x60\x24\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x24\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x24\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x24\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xa0\x24\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x24\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xc0\x24\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x24\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x24\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x24\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x25\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x25\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x25\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x25\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x25\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x25\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x25\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\
+\x25\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x25\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x90\x25\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x25\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xb0\x25\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x25\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xd0\x25\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x25\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x25\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x26\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x10\x26\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x26\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x30\x26\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x26\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x50\x26\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x26\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x70\x26\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x26\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x90\x26\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x26\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xb0\x26\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x26\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x26\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x26\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xf0\x26\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x27\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x10\x27\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x27\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x30\x27\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x27\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x27\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x27\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x27\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x27\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x27\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\
+\x27\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x27\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xc0\x27\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x27\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xe0\x27\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x27\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\0\x28\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x28\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x20\x28\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x28\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x28\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x28\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x60\x28\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x28\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x80\x28\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x28\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xa0\x28\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x28\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xc0\x28\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x28\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xe0\x28\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x28\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\0\x29\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x29\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x20\x29\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x29\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x40\x29\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x29\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x60\x29\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x29\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x29\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x29\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x29\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x29\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x29\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\
+\x29\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x29\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xf0\x29\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x2a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x10\x2a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x2a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x30\x2a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x2a\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x50\x2a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x2a\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x70\x2a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x2a\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x2a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x2a\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xb0\x2a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x2a\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xd0\x2a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x2a\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xf0\x2a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x2b\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x10\x2b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x2b\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x30\x2b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x2b\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x2b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x2b\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x70\x2b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x2b\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x90\x2b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x2b\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x2b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x2b\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x2b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x2b\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x2b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x2c\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x2c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\
+\x2c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x2c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x40\x2c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x2c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x60\x2c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x2c\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x80\x2c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x2c\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xa0\x2c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x2c\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xc0\x2c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x2c\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x2c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x2c\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\0\x2d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x2d\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x20\x2d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x2d\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x40\x2d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x2d\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x60\x2d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x2d\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x80\x2d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x2d\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xa0\x2d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x2d\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x2d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x2d\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x2d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x2d\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x2e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x2e\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x2e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x2e\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x2e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x2e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x2e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x70\x2e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x2e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x90\x2e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x2e\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xb0\x2e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x2e\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xd0\x2e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x2e\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xf0\x2e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x2f\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x2f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x2f\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x30\x2f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x2f\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x50\x2f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x2f\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x70\x2f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x2f\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x90\x2f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x2f\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xb0\x2f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x2f\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xd0\x2f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x2f\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x2f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x30\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x10\x30\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x30\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x30\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x30\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x30\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x30\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x30\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\
+\x30\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x30\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x30\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x30\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xc0\x30\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x30\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xe0\x30\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x30\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\0\x31\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x31\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x20\x31\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x31\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x40\x31\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x31\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x31\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x31\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x80\x31\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x31\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xa0\x31\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x31\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xc0\x31\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x31\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xe0\x31\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x31\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\0\x32\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x32\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x32\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x32\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x40\x32\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x32\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x32\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x32\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x32\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x32\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x32\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\
+\x32\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x32\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x32\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x32\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xf0\x32\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x33\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x10\x33\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x33\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x30\x33\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x33\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x50\x33\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x33\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x70\x33\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x33\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x90\x33\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x33\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xb0\x33\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x33\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xd0\x33\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x33\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xf0\x33\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x34\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x10\x34\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x34\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x30\x34\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x34\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x50\x34\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x34\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x70\x34\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x34\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x34\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x34\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x34\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x34\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x34\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\
+\x34\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x34\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\
+\x35\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x35\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x35\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x35\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x40\x35\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x35\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x60\x35\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x35\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x80\x35\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x35\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xa0\x35\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x35\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xc0\x35\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x35\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xe0\x35\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x35\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\0\x36\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x36\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x20\x36\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x36\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x40\x36\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x36\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x60\x36\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x36\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x80\x36\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x36\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x36\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x36\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x36\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x36\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x36\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x36\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x37\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x37\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x37\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\
+\x37\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x37\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x50\x37\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x37\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x37\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x37\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x90\x37\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x37\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xb0\x37\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x37\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xd0\x37\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x37\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xf0\x37\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x38\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x10\x38\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x38\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x30\x38\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x38\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x50\x38\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x38\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x70\x38\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x38\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x90\x38\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x38\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xb0\x38\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x38\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x38\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x38\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x38\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x39\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x39\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x39\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x39\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x39\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x39\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\
+\x39\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x39\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x80\x39\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x39\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xa0\x39\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x39\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xc0\x39\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x39\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xe0\x39\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x39\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\0\x3a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x3a\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x20\x3a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x3a\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x40\x3a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x3a\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x60\x3a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x3a\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x80\x3a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x3a\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xa0\x3a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x3a\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xc0\x3a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x3a\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xe0\x3a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x3a\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\0\x3b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x3b\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x20\x3b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x3b\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x3b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x3b\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x3b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x3b\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x3b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\
+\x3b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x3b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xb0\x3b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x3b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xd0\x3b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x3b\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xf0\x3b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x3c\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x10\x3c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x3c\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x30\x3c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x3c\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x50\x3c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x3c\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x70\x3c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x3c\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x90\x3c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x3c\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x3c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x3c\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xd0\x3c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x3c\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xf0\x3c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x3d\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x10\x3d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x3d\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x30\x3d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x3d\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x50\x3d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x3d\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x3d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x3d\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x3d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x3d\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x3d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\
+\x3d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x3d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xe0\x3d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x3d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\0\x3e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x3e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x20\x3e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x3e\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x40\x3e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x3e\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x60\x3e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x3e\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x80\x3e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x3e\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xa0\x3e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x3e\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xc0\x3e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x3e\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xe0\x3e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x3e\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x3f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x3f\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x20\x3f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x3f\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x40\x3f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x3f\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x60\x3f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x3f\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x80\x3f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x3f\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x3f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x3f\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x3f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x3f\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x3f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\
+\x3f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x40\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\
+\x40\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x40\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x30\x40\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x40\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x50\x40\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x40\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x70\x40\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x40\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x90\x40\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x40\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xb0\x40\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x40\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xd0\x40\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x40\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xf0\x40\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x41\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x10\x41\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x41\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x41\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x41\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x50\x41\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x41\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x70\x41\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x41\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x90\x41\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x41\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x41\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x41\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x41\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x41\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x41\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x42\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x42\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x42\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x42\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\
+\x42\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x42\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x60\x42\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x42\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x80\x42\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x42\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xa0\x42\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x42\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x42\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x42\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xe0\x42\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x42\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\0\x43\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x43\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x20\x43\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x43\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x40\x43\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x43\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x60\x43\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x43\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x43\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x43\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xa0\x43\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x43\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xc0\x43\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x43\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x43\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x43\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x44\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x44\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x44\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x44\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x44\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x44\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x44\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\
+\x44\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x44\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x90\x44\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x44\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xb0\x44\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x44\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xd0\x44\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x44\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x44\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x45\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x10\x45\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x45\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x30\x45\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x45\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x50\x45\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x45\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x70\x45\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x45\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x90\x45\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x45\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xb0\x45\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x45\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x45\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x45\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xf0\x45\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x46\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x10\x46\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x46\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x30\x46\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x46\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x46\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x46\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x46\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x46\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x46\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\
+\x46\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x46\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xc0\x46\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x46\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xe0\x46\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x46\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\0\x47\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x47\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x20\x47\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x47\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x47\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x47\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x60\x47\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x47\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x80\x47\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x47\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xa0\x47\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x47\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xc0\x47\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x47\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xe0\x47\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x47\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\0\x48\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x48\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x20\x48\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x48\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x40\x48\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x48\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x60\x48\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x48\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x48\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x48\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x48\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x48\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x48\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\
+\x48\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x48\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xf0\x48\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x49\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x10\x49\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x49\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x30\x49\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x49\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x50\x49\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x49\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x70\x49\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x49\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x49\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x49\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xb0\x49\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x49\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xd0\x49\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x49\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xf0\x49\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x4a\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x10\x4a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x4a\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x30\x4a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x4a\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x4a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x4a\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x70\x4a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x4a\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x90\x4a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x4a\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x4a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x4a\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x4a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x4a\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x4a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x4b\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x4b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\
+\x4b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x4b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x40\x4b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x4b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x60\x4b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x4b\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x80\x4b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x4b\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xa0\x4b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x4b\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xc0\x4b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x4b\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x4b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x4b\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\0\x4c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x4c\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x20\x4c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x4c\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x40\x4c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x4c\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x60\x4c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x4c\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x80\x4c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x4c\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xa0\x4c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x4c\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x4c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x4c\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x4c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x4c\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x4d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x4d\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x4d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x4d\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x4d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x4d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x4d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x70\x4d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x4d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x90\x4d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x4d\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xb0\x4d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x4d\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xd0\x4d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x4d\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xf0\x4d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x4e\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x4e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x4e\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x30\x4e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x4e\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x50\x4e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x4e\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x70\x4e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x4e\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x90\x4e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x4e\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xb0\x4e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x4e\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xd0\x4e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x4e\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x4e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x4f\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x10\x4f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x4f\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x4f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x4f\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x4f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x4f\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x4f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\
+\x4f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x4f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x4f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x4f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xc0\x4f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x4f\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xe0\x4f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x4f\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\0\x50\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x50\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x20\x50\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x50\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x40\x50\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x50\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x50\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x50\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x80\x50\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x50\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xa0\x50\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x50\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xc0\x50\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x50\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xe0\x50\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x50\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\0\x51\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x51\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x51\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x51\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x40\x51\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x51\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x51\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x51\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x51\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x51\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x51\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\
+\x51\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x51\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x51\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x51\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xf0\x51\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x52\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x10\x52\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x52\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x30\x52\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x52\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x50\x52\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x52\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x70\x52\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x52\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x90\x52\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x52\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xb0\x52\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x52\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xd0\x52\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x52\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xf0\x52\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x53\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x10\x53\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x53\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x30\x53\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x53\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x50\x53\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x53\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x70\x53\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x53\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x53\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x53\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x53\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x53\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x53\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\
+\x53\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x53\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\
+\x54\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x54\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x54\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x54\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x40\x54\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x54\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x60\x54\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x54\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x80\x54\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x54\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xa0\x54\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x54\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xc0\x54\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x54\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xe0\x54\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x54\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\0\x55\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x55\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x20\x55\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x55\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x40\x55\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x55\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x60\x55\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x55\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x80\x55\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x55\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x55\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x55\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x55\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x55\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x55\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x55\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x56\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x56\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x56\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\
+\x56\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x56\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x50\x56\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x56\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x56\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x56\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x90\x56\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x56\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xb0\x56\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x56\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xd0\x56\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x56\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xf0\x56\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x57\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x10\x57\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x57\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x30\x57\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x57\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x50\x57\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x57\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x70\x57\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x57\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x90\x57\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x57\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xb0\x57\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x57\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x57\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x57\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x57\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x58\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x58\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x58\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x58\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x58\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x58\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\
+\x58\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x58\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x80\x58\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x58\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xa0\x58\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x58\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xc0\x58\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x58\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xe0\x58\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x58\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\0\x59\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x59\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x20\x59\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x59\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x40\x59\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x59\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x60\x59\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x59\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x80\x59\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x59\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xa0\x59\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x59\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xc0\x59\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x59\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xe0\x59\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x59\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\0\x5a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x5a\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x20\x5a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x5a\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x5a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x5a\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x5a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x5a\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x5a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\
+\x5a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x5a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xb0\x5a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x5a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xd0\x5a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x5a\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xf0\x5a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x5b\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x10\x5b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x5b\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x30\x5b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x5b\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x50\x5b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x5b\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x70\x5b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x5b\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x90\x5b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x5b\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x5b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x5b\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xd0\x5b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x5b\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xf0\x5b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x5c\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x10\x5c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x5c\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x30\x5c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x5c\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x50\x5c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x5c\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x5c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x5c\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x5c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x5c\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x5c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\
+\x5c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x5c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xe0\x5c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x5c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\0\x5d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x5d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x20\x5d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x5d\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x40\x5d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x5d\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x60\x5d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x5d\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x80\x5d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x5d\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xa0\x5d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x5d\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xc0\x5d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x5d\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xe0\x5d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x5d\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x5e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x5e\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x20\x5e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x5e\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x40\x5e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x5e\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x60\x5e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x5e\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x80\x5e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x5e\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x5e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x5e\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x5e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x5e\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x5e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\
+\x5e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x5f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\
+\x5f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x5f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x30\x5f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x5f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x50\x5f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x5f\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x70\x5f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x5f\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x90\x5f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x5f\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xb0\x5f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x5f\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xd0\x5f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x5f\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xf0\x5f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x60\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x10\x60\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x60\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x60\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x60\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x50\x60\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x60\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x70\x60\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x60\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x90\x60\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x60\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x60\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x60\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x60\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x60\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x60\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x61\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x61\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x61\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x61\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\
+\x61\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x61\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x60\x61\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x61\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x80\x61\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x61\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xa0\x61\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x61\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x61\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x61\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xe0\x61\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x61\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\0\x62\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x62\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x20\x62\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x62\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x40\x62\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x62\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x60\x62\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x62\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x62\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x62\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xa0\x62\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x62\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xc0\x62\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x62\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x62\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x62\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x63\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x63\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x63\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x63\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x63\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x63\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x63\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\
+\x63\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x63\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x90\x63\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x63\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xb0\x63\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x63\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xd0\x63\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x63\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x63\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x64\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x10\x64\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x64\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x30\x64\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x64\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x50\x64\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x64\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x70\x64\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x64\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x90\x64\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x64\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xb0\x64\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x64\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x64\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x64\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xf0\x64\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x65\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x10\x65\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x65\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x30\x65\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x65\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x65\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x65\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x65\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x65\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x65\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\
+\x65\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x65\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xc0\x65\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x65\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xe0\x65\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x65\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\0\x66\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x66\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x20\x66\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x66\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x66\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x66\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x60\x66\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x66\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x80\x66\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x66\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xa0\x66\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x66\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xc0\x66\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x66\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xe0\x66\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x66\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\0\x67\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x67\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x20\x67\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x67\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x40\x67\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x67\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x60\x67\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x67\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x67\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x67\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x67\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x67\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x67\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\
+\x67\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x67\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xf0\x67\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x68\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x10\x68\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x68\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x30\x68\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x68\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x50\x68\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x68\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x70\x68\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x68\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x68\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x68\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xb0\x68\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x68\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xd0\x68\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x68\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xf0\x68\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x69\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x10\x69\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x69\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x30\x69\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x69\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x69\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x69\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x70\x69\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x69\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x90\x69\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x69\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x69\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x69\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x69\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x69\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x69\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x6a\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x6a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\
+\x6a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x6a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x40\x6a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x6a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x60\x6a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x6a\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x80\x6a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x6a\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xa0\x6a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x6a\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xc0\x6a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x6a\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x6a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x6a\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\0\x6b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x6b\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x20\x6b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x6b\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x40\x6b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x6b\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x60\x6b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x6b\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x80\x6b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x6b\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xa0\x6b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x6b\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x6b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x6b\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x6b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x6b\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x6c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x6c\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x6c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x6c\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x6c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x6c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x6c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x70\x6c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x6c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x90\x6c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x6c\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xb0\x6c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x6c\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xd0\x6c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x6c\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xf0\x6c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x6d\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x6d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x6d\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x30\x6d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x6d\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x50\x6d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x6d\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x70\x6d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x6d\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x90\x6d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x6d\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xb0\x6d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x6d\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xd0\x6d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x6d\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x6d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x6e\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x10\x6e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x6e\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x6e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x6e\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x6e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x6e\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x6e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\
+\x6e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x6e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x6e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x6e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xc0\x6e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x6e\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xe0\x6e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x6e\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\0\x6f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x6f\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x20\x6f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x6f\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x40\x6f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x6f\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x6f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x6f\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x80\x6f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x6f\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xa0\x6f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x6f\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xc0\x6f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x6f\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xe0\x6f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x6f\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\0\x70\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x70\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x70\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x70\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x40\x70\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x70\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x70\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x70\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x70\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x70\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x70\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\
+\x70\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x70\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x70\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x70\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xf0\x70\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x71\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x10\x71\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x71\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x30\x71\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x71\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x50\x71\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x71\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x70\x71\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x71\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x90\x71\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x71\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xb0\x71\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x71\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xd0\x71\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x71\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xf0\x71\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x72\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x10\x72\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x72\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x30\x72\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x72\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x50\x72\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x72\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x70\x72\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x72\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x72\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x72\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x72\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x72\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x72\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\
+\x72\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x72\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\
+\x73\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x73\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x73\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x73\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x40\x73\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x73\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x60\x73\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x73\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x80\x73\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x73\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xa0\x73\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x73\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xc0\x73\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x73\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xe0\x73\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x73\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\0\x74\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x74\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x20\x74\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x74\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x40\x74\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x74\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x60\x74\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x74\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x80\x74\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x74\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x74\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x74\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x74\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x74\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x74\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x74\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x75\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x75\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x75\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\
+\x75\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x75\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x50\x75\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x75\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x75\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x75\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x90\x75\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x75\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xb0\x75\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x75\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xd0\x75\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x75\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xf0\x75\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x76\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x10\x76\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x76\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x30\x76\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x76\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x50\x76\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x76\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x70\x76\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x76\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x90\x76\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x76\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xb0\x76\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x76\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x76\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x76\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x76\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x77\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x77\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x77\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x77\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x77\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x77\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\
+\x77\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x77\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x80\x77\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x77\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xa0\x77\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x77\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xc0\x77\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x77\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xe0\x77\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x77\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\0\x78\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x78\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x20\x78\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x78\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x40\x78\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x78\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x60\x78\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x78\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x80\x78\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x78\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xa0\x78\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x78\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xc0\x78\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x78\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xe0\x78\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x78\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\0\x79\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x79\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x20\x79\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x79\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x79\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x79\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x79\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x79\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x79\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\
+\x79\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x79\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xb0\x79\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x79\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xd0\x79\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x79\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xf0\x79\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x7a\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x10\x7a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x7a\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x30\x7a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x7a\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x50\x7a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x7a\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x70\x7a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x7a\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x90\x7a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x7a\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x7a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x7a\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xd0\x7a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x7a\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xf0\x7a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x7b\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x10\x7b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x7b\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x30\x7b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x7b\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x50\x7b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x7b\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x7b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x7b\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x7b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x7b\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x7b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\
+\x7b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x7b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xe0\x7b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x7b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\0\x7c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x7c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x20\x7c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x7c\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x40\x7c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x7c\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x60\x7c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x7c\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x80\x7c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x7c\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xa0\x7c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x7c\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xc0\x7c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x7c\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xe0\x7c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x7c\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x7d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x7d\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x20\x7d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x7d\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x40\x7d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x7d\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x60\x7d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x7d\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x80\x7d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x7d\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x7d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x7d\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x7d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x7d\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x7d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\
+\x7d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x7e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\
+\x7e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x7e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x30\x7e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x7e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x50\x7e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x7e\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x70\x7e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x7e\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x90\x7e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x7e\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xb0\x7e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x7e\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xd0\x7e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x7e\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xf0\x7e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x7f\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x10\x7f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x7f\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x7f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x7f\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x50\x7f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x7f\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x70\x7f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x7f\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x90\x7f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x7f\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x7f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x7f\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x7f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x7f\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x7f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x80\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x80\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x80\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x80\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\
+\x80\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x80\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x60\x80\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x80\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x80\x80\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x80\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xa0\x80\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x80\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x80\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x80\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xe0\x80\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x80\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\0\x81\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x81\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x20\x81\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x81\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x40\x81\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x81\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x60\x81\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x81\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x81\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x81\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xa0\x81\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x81\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xc0\x81\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x81\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x81\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x81\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x82\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x82\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x82\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x82\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x82\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x82\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x82\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\
+\x82\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x82\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x90\x82\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x82\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xb0\x82\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x82\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xd0\x82\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x82\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x82\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x83\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x10\x83\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x83\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x30\x83\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x83\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x50\x83\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x83\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x70\x83\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x83\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x90\x83\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x83\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xb0\x83\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x83\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x83\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x83\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xf0\x83\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x84\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x10\x84\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x84\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x30\x84\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x84\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x84\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x84\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x84\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x84\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x84\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\
+\x84\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x84\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xc0\x84\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x84\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xe0\x84\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x84\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\0\x85\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x85\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x20\x85\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x85\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x85\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x85\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x60\x85\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x85\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x80\x85\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x85\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xa0\x85\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x85\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xc0\x85\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x85\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xe0\x85\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x85\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\0\x86\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x86\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x20\x86\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x86\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x40\x86\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x86\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x60\x86\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x86\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x86\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x86\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x86\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x86\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x86\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\
+\x86\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x86\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xf0\x86\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x87\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x10\x87\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x87\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x30\x87\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x87\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x50\x87\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x87\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x70\x87\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x87\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x87\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x87\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xb0\x87\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x87\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xd0\x87\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x87\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xf0\x87\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x88\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x10\x88\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x88\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x30\x88\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x88\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x88\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x88\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x70\x88\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x88\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x90\x88\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x88\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x88\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x88\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x88\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x88\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x88\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x89\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x89\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\
+\x89\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x89\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x40\x89\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x89\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x60\x89\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x89\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x80\x89\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x89\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xa0\x89\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x89\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xc0\x89\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x89\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x89\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x89\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\0\x8a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x8a\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x20\x8a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x8a\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x40\x8a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x8a\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x60\x8a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x8a\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x80\x8a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x8a\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xa0\x8a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x8a\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x8a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x8a\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x8a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x8a\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x8b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x8b\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x8b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x8b\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x8b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x8b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x8b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x70\x8b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x8b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x90\x8b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x8b\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xb0\x8b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x8b\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xd0\x8b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x8b\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xf0\x8b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x8c\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x8c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x8c\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x30\x8c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x8c\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x50\x8c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x8c\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x70\x8c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x8c\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x90\x8c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x8c\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xb0\x8c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x8c\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xd0\x8c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x8c\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x8c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x8d\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x10\x8d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x8d\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x8d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x8d\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x8d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x8d\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x8d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\
+\x8d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x8d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x8d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x8d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xc0\x8d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x8d\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xe0\x8d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x8d\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\0\x8e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x8e\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x20\x8e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x8e\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x40\x8e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x8e\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x8e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x8e\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x80\x8e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x8e\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xa0\x8e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x8e\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xc0\x8e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x8e\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xe0\x8e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x8e\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\0\x8f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x8f\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x8f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x8f\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x40\x8f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x8f\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x8f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x8f\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x8f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x8f\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x8f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\
+\x8f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x8f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x8f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x8f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xf0\x8f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x90\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x10\x90\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x90\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x30\x90\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x90\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x50\x90\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x90\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x70\x90\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x90\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x90\x90\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x90\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xb0\x90\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x90\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xd0\x90\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x90\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xf0\x90\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x91\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x10\x91\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x91\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x30\x91\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x91\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x50\x91\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x91\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x70\x91\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x91\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x91\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x91\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x91\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x91\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x91\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\
+\x91\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x91\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\
+\x92\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x92\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x92\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x92\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x40\x92\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x92\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x60\x92\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x92\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x80\x92\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x92\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xa0\x92\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x92\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xc0\x92\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x92\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xe0\x92\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x92\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\0\x93\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x93\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x20\x93\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x93\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x40\x93\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x93\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x60\x93\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x93\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x80\x93\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x93\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x93\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x93\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x93\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x93\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x93\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x93\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x94\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x94\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x94\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\
+\x94\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x94\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x50\x94\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x94\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x94\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x94\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x90\x94\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x94\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xb0\x94\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x94\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xd0\x94\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x94\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xf0\x94\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x95\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x10\x95\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x95\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x30\x95\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x95\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x50\x95\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x95\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x70\x95\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x95\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x90\x95\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x95\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xb0\x95\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x95\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x95\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x95\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x95\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x96\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x96\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x96\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x96\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x96\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x96\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\
+\x96\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x96\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x80\x96\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x96\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xa0\x96\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x96\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xc0\x96\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x96\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xe0\x96\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x96\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\0\x97\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x97\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x20\x97\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x97\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x40\x97\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x97\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x60\x97\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x97\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x80\x97\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x97\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xa0\x97\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x97\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xc0\x97\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x97\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xe0\x97\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x97\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\0\x98\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x98\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x20\x98\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x98\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x98\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x98\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x98\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x98\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x98\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\
+\x98\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x98\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xb0\x98\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x98\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xd0\x98\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x98\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xf0\x98\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x99\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x10\x99\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x99\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x30\x99\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x99\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x50\x99\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x99\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x70\x99\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x99\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x90\x99\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x99\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x99\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x99\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xd0\x99\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x99\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xf0\x99\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x9a\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x10\x9a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x9a\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x30\x9a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x9a\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x50\x9a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x9a\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x9a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x9a\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x9a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x9a\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x9a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\
+\x9a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x9a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xe0\x9a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x9a\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\0\x9b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x9b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x20\x9b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x9b\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x40\x9b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x9b\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x60\x9b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x9b\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x80\x9b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x9b\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xa0\x9b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x9b\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xc0\x9b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x9b\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xe0\x9b\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x9b\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x9c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x9c\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x20\x9c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x9c\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x40\x9c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x9c\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x60\x9c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x9c\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x80\x9c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x9c\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x9c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x9c\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x9c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x9c\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x9c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\
+\x9c\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x9d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\
+\x9d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x9d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x30\x9d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x9d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x50\x9d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x9d\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x70\x9d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x9d\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x90\x9d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x9d\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xb0\x9d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x9d\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xd0\x9d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x9d\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xf0\x9d\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x9e\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x10\x9e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x9e\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x9e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x9e\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x50\x9e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x9e\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x70\x9e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x9e\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x90\x9e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x9e\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x9e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x9e\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x9e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x9e\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x9e\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x9f\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x9f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x9f\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x9f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\
+\x9f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x9f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x60\x9f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x9f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x80\x9f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x9f\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xa0\x9f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x9f\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x9f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x9f\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xe0\x9f\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x9f\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\0\xa0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xa0\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x20\xa0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xa0\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x40\xa0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xa0\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x60\xa0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xa0\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\xa0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xa0\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xa0\xa0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xa0\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xc0\xa0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xa0\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xa0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xa0\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xa1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xa1\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xa1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xa1\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xa1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xa1\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xa1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\
+\xa1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xa1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x90\xa1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xa1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xb0\xa1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xa1\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xd0\xa1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xa1\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\xa1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xa2\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x10\xa2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xa2\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x30\xa2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xa2\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x50\xa2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xa2\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x70\xa2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xa2\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x90\xa2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xa2\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xb0\xa2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xa2\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\xa2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xa2\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xf0\xa2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xa3\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x10\xa3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xa3\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x30\xa3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xa3\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xa3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xa3\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xa3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xa3\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xa3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\
+\xa3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xa3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xc0\xa3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xa3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xe0\xa3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xa3\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\0\xa4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xa4\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x20\xa4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xa4\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\xa4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xa4\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x60\xa4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xa4\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x80\xa4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xa4\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xa0\xa4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xa4\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xc0\xa4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xa4\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xe0\xa4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xa4\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\0\xa5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xa5\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x20\xa5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xa5\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x40\xa5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xa5\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x60\xa5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xa5\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xa5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xa5\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xa5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xa5\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xa5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\
+\xa5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xa5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xf0\xa5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xa6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x10\xa6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xa6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x30\xa6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xa6\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x50\xa6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xa6\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x70\xa6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xa6\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\xa6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xa6\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xb0\xa6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xa6\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xd0\xa6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xa6\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xf0\xa6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xa7\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x10\xa7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xa7\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x30\xa7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xa7\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\xa7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xa7\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x70\xa7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xa7\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x90\xa7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xa7\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xa7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xa7\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xa7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xa7\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xa7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xa8\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xa8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\
+\xa8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xa8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x40\xa8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xa8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x60\xa8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xa8\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x80\xa8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xa8\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xa0\xa8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xa8\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xc0\xa8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xa8\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\xa8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xa8\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\0\xa9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xa9\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x20\xa9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xa9\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x40\xa9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xa9\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x60\xa9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xa9\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x80\xa9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xa9\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xa0\xa9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xa9\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xa9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xa9\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xa9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xa9\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xaa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xaa\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xaa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xaa\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xaa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\xaa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xaa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x70\xaa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xaa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x90\xaa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xaa\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xb0\xaa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xaa\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xd0\xaa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xaa\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xf0\xaa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xab\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\xab\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xab\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x30\xab\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xab\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x50\xab\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xab\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x70\xab\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xab\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x90\xab\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xab\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xb0\xab\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xab\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xd0\xab\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xab\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xab\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xac\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x10\xac\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xac\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xac\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xac\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xac\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xac\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xac\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\
+\xac\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xac\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\xac\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xac\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xc0\xac\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xac\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xe0\xac\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xac\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\0\xad\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xad\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x20\xad\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xad\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x40\xad\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xad\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\xad\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xad\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x80\xad\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xad\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xa0\xad\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xad\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xc0\xad\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xad\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xe0\xad\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xad\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\0\xae\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xae\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\xae\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xae\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x40\xae\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xae\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xae\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xae\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xae\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xae\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xae\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\
+\xae\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xae\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\xae\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xae\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xf0\xae\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xaf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x10\xaf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xaf\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x30\xaf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xaf\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x50\xaf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xaf\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x70\xaf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xaf\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x90\xaf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xaf\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xb0\xaf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xaf\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xd0\xaf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xaf\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xf0\xaf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xb0\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x10\xb0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xb0\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x30\xb0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xb0\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x50\xb0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xb0\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x70\xb0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xb0\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xb0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xb0\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xb0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xb0\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xb0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\
+\xb0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xb0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\
+\xb1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xb1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\xb1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xb1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x40\xb1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xb1\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x60\xb1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xb1\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x80\xb1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xb1\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xa0\xb1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xb1\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xc0\xb1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xb1\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xe0\xb1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xb1\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\0\xb2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xb2\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x20\xb2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xb2\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x40\xb2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xb2\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x60\xb2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xb2\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x80\xb2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xb2\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xb2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xb2\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xb2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xb2\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xb2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xb2\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xb3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xb3\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xb3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\
+\xb3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xb3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x50\xb3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xb3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\xb3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xb3\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x90\xb3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xb3\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xb0\xb3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xb3\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xd0\xb3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xb3\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xf0\xb3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xb4\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x10\xb4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xb4\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x30\xb4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xb4\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x50\xb4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xb4\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x70\xb4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xb4\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x90\xb4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xb4\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xb0\xb4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xb4\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xb4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xb4\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xb4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xb5\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xb5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xb5\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xb5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xb5\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xb5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\
+\xb5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xb5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x80\xb5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xb5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xa0\xb5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xb5\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xc0\xb5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xb5\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xe0\xb5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xb5\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\0\xb6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xb6\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x20\xb6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xb6\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x40\xb6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xb6\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x60\xb6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xb6\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x80\xb6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xb6\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xa0\xb6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xb6\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xc0\xb6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xb6\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xe0\xb6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xb6\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\0\xb7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xb7\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x20\xb7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xb7\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xb7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xb7\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xb7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xb7\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xb7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\
+\xb7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xb7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xb0\xb7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xb7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xd0\xb7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xb7\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xf0\xb7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xb8\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x10\xb8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xb8\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x30\xb8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xb8\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x50\xb8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xb8\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x70\xb8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xb8\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x90\xb8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xb8\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\xb8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xb8\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xd0\xb8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xb8\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xf0\xb8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xb9\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x10\xb9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xb9\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x30\xb9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xb9\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x50\xb9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xb9\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xb9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xb9\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xb9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xb9\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xb9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\
+\xb9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xb9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xe0\xb9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xb9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\0\xba\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xba\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x20\xba\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xba\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x40\xba\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xba\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x60\xba\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xba\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x80\xba\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xba\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xa0\xba\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xba\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xc0\xba\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xba\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xe0\xba\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xba\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\xbb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xbb\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x20\xbb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xbb\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x40\xbb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xbb\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x60\xbb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xbb\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x80\xbb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xbb\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xbb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xbb\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xbb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xbb\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xbb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\
+\xbb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xbc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\
+\xbc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xbc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x30\xbc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xbc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x50\xbc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xbc\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x70\xbc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xbc\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x90\xbc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xbc\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xb0\xbc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xbc\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xd0\xbc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xbc\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xf0\xbc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xbd\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x10\xbd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xbd\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\xbd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xbd\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x50\xbd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xbd\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x70\xbd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xbd\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x90\xbd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xbd\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xbd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xbd\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xbd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xbd\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xbd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xbe\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xbe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xbe\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xbe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\
+\xbe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xbe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x60\xbe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xbe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x80\xbe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xbe\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xa0\xbe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xbe\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\xbe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xbe\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xe0\xbe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xbe\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\0\xbf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xbf\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x20\xbf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xbf\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x40\xbf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xbf\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x60\xbf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xbf\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\xbf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xbf\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xa0\xbf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xbf\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xc0\xbf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xbf\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xbf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xbf\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xc0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xc0\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xc0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xc0\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xc0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xc0\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xc0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\
+\xc0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xc0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x90\xc0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xc0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xb0\xc0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xc0\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xd0\xc0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xc0\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\xc0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xc1\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x10\xc1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xc1\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x30\xc1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xc1\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x50\xc1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xc1\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x70\xc1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xc1\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x90\xc1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xc1\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xb0\xc1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xc1\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\xc1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xc1\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xf0\xc1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xc2\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x10\xc2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xc2\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x30\xc2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xc2\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xc2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xc2\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xc2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xc2\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xc2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\
+\xc2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xc2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xc0\xc2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xc2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xe0\xc2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xc2\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\0\xc3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xc3\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x20\xc3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xc3\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\xc3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xc3\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x60\xc3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xc3\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x80\xc3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xc3\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xa0\xc3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xc3\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xc0\xc3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xc3\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xe0\xc3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xc3\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\0\xc4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xc4\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x20\xc4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xc4\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x40\xc4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xc4\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x60\xc4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xc4\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xc4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xc4\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xc4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xc4\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xc4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\
+\xc4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xc4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xf0\xc4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xc5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x10\xc5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xc5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x30\xc5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xc5\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x50\xc5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xc5\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x70\xc5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xc5\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\xc5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xc5\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xb0\xc5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xc5\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xd0\xc5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xc5\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xf0\xc5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xc6\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x10\xc6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xc6\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x30\xc6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xc6\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\xc6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xc6\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x70\xc6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xc6\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x90\xc6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xc6\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xc6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xc6\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xc6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xc6\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xc6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xc7\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xc7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\
+\xc7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xc7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x40\xc7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xc7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x60\xc7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xc7\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x80\xc7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xc7\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xa0\xc7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xc7\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xc0\xc7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xc7\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\xc7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xc7\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\0\xc8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xc8\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x20\xc8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xc8\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x40\xc8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xc8\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x60\xc8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xc8\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x80\xc8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xc8\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xa0\xc8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xc8\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xc8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xc8\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xc8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xc8\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xc9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xc9\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xc9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xc9\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xc9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\xc9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xc9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x70\xc9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xc9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x90\xc9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xc9\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xb0\xc9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xc9\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xd0\xc9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xc9\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xf0\xc9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xca\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\xca\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xca\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x30\xca\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xca\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x50\xca\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xca\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x70\xca\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xca\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x90\xca\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xca\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xb0\xca\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xca\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xd0\xca\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xca\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xca\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xcb\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x10\xcb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xcb\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xcb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xcb\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xcb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xcb\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xcb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\
+\xcb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xcb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\xcb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xcb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xc0\xcb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xcb\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xe0\xcb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xcb\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\0\xcc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xcc\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x20\xcc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xcc\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x40\xcc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xcc\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\xcc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xcc\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x80\xcc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xcc\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xa0\xcc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xcc\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xc0\xcc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xcc\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xe0\xcc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xcc\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\0\xcd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xcd\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\xcd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xcd\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x40\xcd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xcd\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xcd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xcd\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xcd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xcd\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xcd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\
+\xcd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xcd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\xcd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xcd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xf0\xcd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xce\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x10\xce\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xce\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x30\xce\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xce\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x50\xce\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xce\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x70\xce\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xce\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x90\xce\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xce\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xb0\xce\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xce\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xd0\xce\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xce\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xf0\xce\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xcf\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x10\xcf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xcf\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x30\xcf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xcf\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x50\xcf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xcf\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x70\xcf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xcf\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xcf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xcf\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xcf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xcf\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xcf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\
+\xcf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xcf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\
+\xd0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xd0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\xd0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xd0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x40\xd0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xd0\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x60\xd0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xd0\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x80\xd0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xd0\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xa0\xd0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xd0\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xc0\xd0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xd0\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xe0\xd0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xd0\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\0\xd1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xd1\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x20\xd1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xd1\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x40\xd1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xd1\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x60\xd1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xd1\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x80\xd1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xd1\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xd1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xd1\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xd1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xd1\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xd1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xd1\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xd2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xd2\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xd2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\
+\xd2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xd2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x50\xd2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xd2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\xd2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xd2\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x90\xd2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xd2\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xb0\xd2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xd2\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xd0\xd2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xd2\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xf0\xd2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xd3\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x10\xd3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xd3\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x30\xd3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xd3\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x50\xd3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xd3\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x70\xd3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xd3\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x90\xd3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xd3\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xb0\xd3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xd3\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xd3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xd3\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xd3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xd4\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xd4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xd4\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xd4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xd4\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xd4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\
+\xd4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xd4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x80\xd4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xd4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xa0\xd4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xd4\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xc0\xd4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xd4\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xe0\xd4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xd4\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\0\xd5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xd5\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x20\xd5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xd5\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x40\xd5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xd5\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x60\xd5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xd5\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x80\xd5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xd5\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xa0\xd5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xd5\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xc0\xd5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xd5\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xe0\xd5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xd5\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\0\xd6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xd6\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x20\xd6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xd6\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xd6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xd6\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xd6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xd6\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xd6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\
+\xd6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xd6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xb0\xd6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xd6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xd0\xd6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xd6\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xf0\xd6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xd7\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x10\xd7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xd7\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x30\xd7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xd7\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x50\xd7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xd7\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x70\xd7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xd7\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x90\xd7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xd7\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\xd7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xd7\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xd0\xd7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xd7\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xf0\xd7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xd8\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x10\xd8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xd8\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x30\xd8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xd8\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x50\xd8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xd8\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xd8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xd8\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xd8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xd8\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xd8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\
+\xd8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xd8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xe0\xd8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xd8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\0\xd9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xd9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x20\xd9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xd9\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x40\xd9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xd9\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x60\xd9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xd9\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x80\xd9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xd9\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xa0\xd9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xd9\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xc0\xd9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xd9\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xe0\xd9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xd9\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\xda\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xda\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x20\xda\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xda\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x40\xda\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xda\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x60\xda\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xda\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x80\xda\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xda\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xda\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xda\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xda\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xda\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xda\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\
+\xda\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xdb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\
+\xdb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xdb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x30\xdb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xdb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x50\xdb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xdb\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x70\xdb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xdb\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x90\xdb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xdb\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xb0\xdb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xdb\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xd0\xdb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xdb\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xf0\xdb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xdc\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x10\xdc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xdc\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\xdc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xdc\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x50\xdc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xdc\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x70\xdc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xdc\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x90\xdc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xdc\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xdc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xdc\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xdc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xdc\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xdc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xdd\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xdd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xdd\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xdd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\
+\xdd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xdd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x60\xdd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xdd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x80\xdd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xdd\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xa0\xdd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xdd\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\xdd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xdd\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xe0\xdd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xdd\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\0\xde\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xde\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x20\xde\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xde\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x40\xde\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xde\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x60\xde\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xde\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\xde\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xde\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xa0\xde\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xde\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xc0\xde\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xde\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xde\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xde\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xdf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xdf\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xdf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xdf\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xdf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xdf\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xdf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\
+\xdf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xdf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x90\xdf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xdf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xb0\xdf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xdf\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xd0\xdf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xdf\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\xdf\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xe0\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x10\xe0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xe0\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x30\xe0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xe0\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x50\xe0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xe0\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x70\xe0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xe0\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x90\xe0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xe0\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xb0\xe0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xe0\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\xe0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xe0\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xf0\xe0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xe1\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x10\xe1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xe1\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x30\xe1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xe1\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xe1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xe1\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xe1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xe1\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xe1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\
+\xe1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xe1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xc0\xe1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xe1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xe0\xe1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xe1\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\0\xe2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xe2\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x20\xe2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xe2\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\xe2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xe2\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x60\xe2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xe2\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x80\xe2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xe2\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xa0\xe2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xe2\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xc0\xe2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xe2\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xe0\xe2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xe2\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\0\xe3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xe3\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x20\xe3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xe3\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x40\xe3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xe3\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x60\xe3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xe3\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xe3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xe3\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xe3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xe3\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xe3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\
+\xe3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xe3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xf0\xe3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xe4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x10\xe4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xe4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x30\xe4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xe4\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x50\xe4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xe4\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x70\xe4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xe4\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\xe4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xe4\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xb0\xe4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xe4\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xd0\xe4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xe4\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xf0\xe4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xe5\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x10\xe5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xe5\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x30\xe5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xe5\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\xe5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xe5\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x70\xe5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xe5\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x90\xe5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xe5\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xe5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xe5\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xe5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xe5\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xe5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xe6\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xe6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\
+\xe6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xe6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x40\xe6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xe6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x60\xe6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xe6\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x80\xe6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xe6\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xa0\xe6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xe6\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xc0\xe6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xe6\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\xe6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xe6\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\0\xe7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xe7\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x20\xe7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xe7\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x40\xe7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xe7\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x60\xe7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xe7\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x80\xe7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xe7\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xa0\xe7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xe7\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xe7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xe7\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xe7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xe7\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xe8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xe8\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xe8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xe8\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xe8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\xe8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xe8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x70\xe8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xe8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x90\xe8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xe8\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xb0\xe8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xe8\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xd0\xe8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xe8\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xf0\xe8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xe9\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\xe9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xe9\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x30\xe9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xe9\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x50\xe9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xe9\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x70\xe9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xe9\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x90\xe9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xe9\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xb0\xe9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xe9\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xd0\xe9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xe9\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xe9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xea\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x10\xea\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xea\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xea\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xea\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xea\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xea\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xea\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\
+\xea\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xea\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\xea\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xea\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xc0\xea\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xea\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xe0\xea\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xea\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\0\xeb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xeb\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x20\xeb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xeb\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x40\xeb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xeb\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\xeb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xeb\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x80\xeb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xeb\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xa0\xeb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xeb\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xc0\xeb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xeb\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xe0\xeb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xeb\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\0\xec\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xec\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\xec\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xec\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x40\xec\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xec\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xec\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xec\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xec\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xec\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xec\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\
+\xec\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xec\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\xec\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xec\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xf0\xec\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xed\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x10\xed\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xed\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x30\xed\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xed\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x50\xed\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xed\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x70\xed\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xed\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x90\xed\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xed\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xb0\xed\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xed\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xd0\xed\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xed\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xf0\xed\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xee\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x10\xee\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xee\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x30\xee\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xee\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x50\xee\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xee\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x70\xee\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xee\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xee\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xee\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xee\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xee\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xee\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\
+\xee\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xee\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\
+\xef\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xef\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\xef\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xef\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x40\xef\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xef\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x60\xef\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xef\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x80\xef\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xef\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xa0\xef\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xef\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xc0\xef\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xef\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xe0\xef\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xef\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\0\xf0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xf0\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x20\xf0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xf0\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x40\xf0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xf0\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x60\xf0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xf0\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x80\xf0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xf0\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xf0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xf0\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xf0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xf0\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xf0\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xf0\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xf1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xf1\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xf1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\
+\xf1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xf1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x50\xf1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xf1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\xf1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xf1\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x90\xf1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xf1\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xb0\xf1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xf1\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xd0\xf1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xf1\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xf0\xf1\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xf2\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x10\xf2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xf2\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x30\xf2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xf2\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x50\xf2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xf2\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x70\xf2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xf2\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x90\xf2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xf2\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xb0\xf2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xf2\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xf2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xf2\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xf2\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xf3\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xf3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xf3\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xf3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xf3\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xf3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\
+\xf3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xf3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x80\xf3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xf3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xa0\xf3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xf3\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xc0\xf3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xf3\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xe0\xf3\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xf3\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\0\xf4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xf4\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x20\xf4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xf4\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x40\xf4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xf4\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x60\xf4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xf4\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x80\xf4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xf4\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xa0\xf4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xf4\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xc0\xf4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xf4\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xe0\xf4\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xf4\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\0\xf5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xf5\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x20\xf5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xf5\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xf5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xf5\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xf5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xf5\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xf5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\
+\xf5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xf5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xb0\xf5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xf5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xd0\xf5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xf5\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xf0\xf5\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xf6\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x10\xf6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xf6\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x30\xf6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xf6\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x50\xf6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xf6\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x70\xf6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xf6\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x90\xf6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xf6\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\xf6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xf6\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xd0\xf6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xf6\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xf0\xf6\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xf7\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x10\xf7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xf7\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x30\xf7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xf7\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x50\xf7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xf7\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xf7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xf7\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xf7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xf7\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xf7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\
+\xf7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xf7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xe0\xf7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xf7\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\0\xf8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xf8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x20\xf8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xf8\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x40\xf8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xf8\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x60\xf8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xf8\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x80\xf8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xf8\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xa0\xf8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xf8\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xc0\xf8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xf8\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xe0\xf8\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xf8\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\xf9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xf9\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x20\xf9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xf9\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x40\xf9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xf9\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x60\xf9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xf9\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x80\xf9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xf9\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xf9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xf9\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xf9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xf9\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xf9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\
+\xf9\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xfa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\
+\xfa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xfa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x30\xfa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xfa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x50\xfa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xfa\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\x70\xfa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xfa\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x90\xfa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xfa\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xb0\xfa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xfa\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xd0\xfa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xfa\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\xf0\xfa\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xfb\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x10\xfb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xfb\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\xfb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xfb\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x50\xfb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xfb\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x70\xfb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xfb\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x90\xfb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xfb\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xfb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xfb\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xfb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xfb\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xfb\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xfc\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xfc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xfc\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xfc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\
+\xfc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xfc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x60\xfc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xfc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x80\xfc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xfc\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xa0\xfc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xfc\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\xfc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xfc\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\xe0\xfc\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xfc\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\0\xfd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xfd\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x20\xfd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xfd\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x40\xfd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xfd\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x60\xfd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\xfd\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\xfd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\xfd\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xa0\xfd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\xfd\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xc0\xfd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\xfd\0\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xfd\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\xfd\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xfe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\xfe\0\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xfe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\xfe\0\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xfe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\xfe\
+\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xfe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\
+\xfe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xfe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x90\xfe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xfe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xb0\xfe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xfe\0\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\xd0\xfe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xfe\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\xfe\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\xff\0\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x10\xff\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\xff\0\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x30\xff\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\xff\0\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x50\xff\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\xff\0\0\0\0\0\0\x04\0\
+\0\0\x02\0\0\0\x70\xff\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\xff\0\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x90\xff\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\xff\0\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xb0\xff\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\xff\0\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\xff\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\xff\0\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\xf0\xff\0\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\0\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x10\0\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\0\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\x30\0\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\0\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\0\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\0\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\0\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\0\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\0\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\
+\0\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\0\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xc0\0\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\0\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\xe0\0\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\0\x01\0\0\0\0\0\x04\0\0\0\x02\0\
+\0\0\0\x01\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x01\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x20\x01\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x01\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x40\x01\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x01\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x60\x01\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x01\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x01\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x01\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x01\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xb0\x01\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x01\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xd0\x01\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x01\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xf0\x01\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x02\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x10\x02\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x02\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x30\x02\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x02\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x02\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x02\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x02\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x80\x02\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x02\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xa0\x02\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x02\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xc0\x02\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x02\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\xe0\x02\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x02\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\0\x03\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x03\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x03\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\
+\x03\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x03\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x50\x03\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x03\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x70\x03\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x03\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x90\x03\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x03\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xb0\x03\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x03\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x03\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x03\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x03\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\
+\x04\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x04\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x20\x04\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x04\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x40\x04\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x04\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x60\x04\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x04\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x80\x04\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x04\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x04\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x04\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x04\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x04\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x04\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x04\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x05\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x05\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x05\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x05\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x05\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x05\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x05\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x05\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x05\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x05\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x05\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x05\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x05\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x05\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x05\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x05\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x06\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x06\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x06\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x06\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x06\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x06\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x06\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x06\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x06\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x06\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x06\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x06\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x06\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x06\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x06\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x06\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x07\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x07\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x07\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x07\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x07\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x07\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x07\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x07\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x07\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x07\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x07\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x07\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x07\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x07\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x07\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x07\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x08\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x08\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x08\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x08\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x08\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x08\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x08\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x08\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x08\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x08\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x08\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x08\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x08\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x08\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x08\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x08\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x09\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x09\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x09\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x09\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x09\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x09\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x09\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x09\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x09\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x09\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x09\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x09\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x09\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x09\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x09\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x09\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x0a\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x0a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x0a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x0a\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x0a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x0a\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x0a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x0a\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x0a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x0a\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x0a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x0a\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x0a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x0a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x0a\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x0a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x0b\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x0b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x0b\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x0b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x0b\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x0b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x0b\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x0b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x0b\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x0b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x0b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x0b\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x0b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x0b\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x0b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x0b\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x0c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x0c\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x0c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x0c\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x0c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x0c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x0c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x0c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x0c\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x0c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x0c\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x0c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x0c\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x0c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x0c\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x0c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x0d\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x0d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x0d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x0d\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x0d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x0d\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x0d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x0d\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x0d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x0d\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x0d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x0d\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x0d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x0d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x0d\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x0d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x0e\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x0e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x0e\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x0e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x0e\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x0e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x0e\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x0e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x0e\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x0e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x0e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x0e\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x0e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x0e\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x0e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x0e\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x0f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x0f\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x0f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x0f\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x0f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x0f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x0f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x0f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x0f\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x0f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x0f\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x0f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x0f\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x0f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x0f\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x0f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x10\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x10\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x10\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x10\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x10\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x10\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x10\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x10\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x10\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x10\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x10\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x10\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x10\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x10\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x10\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x10\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x11\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x11\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x11\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x11\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x11\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x11\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x11\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x11\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x11\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x11\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x11\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x11\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x11\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x11\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x11\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x11\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x12\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x12\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x12\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x12\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x12\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x12\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x12\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x12\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x12\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x12\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x12\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x12\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x12\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x12\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x12\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x12\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x13\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x13\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x13\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x13\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x13\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x13\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x13\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x13\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x13\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x13\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x13\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x13\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x13\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x13\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x13\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x13\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x14\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x14\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x14\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x14\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x14\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x14\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x14\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x14\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x14\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x14\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x14\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x14\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x14\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x14\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x14\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x14\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x15\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x15\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x15\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x15\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x15\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x15\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x15\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x15\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x15\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x15\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x15\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x15\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x15\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x15\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x15\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x15\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x16\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x16\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x16\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x16\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x16\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x16\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x16\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x16\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x16\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x16\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x16\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x16\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x16\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x16\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x16\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x16\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x17\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x17\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x17\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x17\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x17\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x17\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x17\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x17\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x17\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x17\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x17\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x17\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x17\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x17\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x17\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x17\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x18\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x18\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x18\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x18\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x18\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x18\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x18\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x18\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x18\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x18\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x18\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x18\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x18\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x18\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x18\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x18\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x19\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x19\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x19\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x19\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x19\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x19\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x19\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x19\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x19\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x19\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x19\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x19\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x19\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x19\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x19\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x19\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x1a\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x1a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x1a\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x1a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x1a\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x1a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x1a\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x1a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x1a\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x1a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x1a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x1a\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x1a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x1a\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x1a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x1a\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x1b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x1b\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x1b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x1b\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x1b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x1b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x1b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x1b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x1b\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x1b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x1b\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x1b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x1b\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x1b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x1b\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x1b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x1c\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x1c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x1c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x1c\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x1c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x1c\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x1c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x1c\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x1c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x1c\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x1c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x1c\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x1c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x1c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x1c\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x1c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x1d\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x1d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x1d\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x1d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x1d\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x1d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x1d\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x1d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x1d\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x1d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x1d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x1d\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x1d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x1d\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x1d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x1d\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x1e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x1e\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x1e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x1e\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x1e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x1e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x1e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x1e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x1e\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x1e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x1e\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x1e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x1e\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x1e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x1e\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x1e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x1f\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x1f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x1f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x1f\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x1f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x1f\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x1f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x1f\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x1f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x1f\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x1f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x1f\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x1f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x1f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x1f\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x1f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x20\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x20\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x20\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x20\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x20\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x20\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x20\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x20\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x20\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x20\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x20\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x20\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x20\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x20\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x20\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x20\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x21\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x21\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x21\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x21\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x21\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x21\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x21\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x21\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x21\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x21\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x21\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x21\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x21\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x21\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x21\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x21\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x22\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x22\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x22\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x22\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x22\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x22\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x22\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x22\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x22\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x22\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x22\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x22\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x22\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x22\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x22\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x22\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x23\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x23\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x23\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x23\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x23\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x23\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x23\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x23\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x23\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x23\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x23\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x23\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x23\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x23\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x23\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x23\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x24\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x24\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x24\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x24\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x24\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x24\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x24\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x24\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x24\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x24\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x24\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x24\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x24\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x24\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x24\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x24\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x25\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x25\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x25\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x25\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x25\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x25\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x25\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x25\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x25\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x25\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x25\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x25\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x25\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x25\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x25\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x25\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x26\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x26\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x26\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x26\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x26\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x26\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x26\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x26\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x26\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x26\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x26\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x26\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x26\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x26\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x26\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x26\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x27\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x27\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x27\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x27\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x27\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x27\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x27\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x27\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x27\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x27\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x27\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x27\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x27\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x27\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x27\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x27\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x28\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x28\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x28\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x28\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x28\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x28\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x28\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x28\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x28\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x28\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x28\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x28\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x28\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x28\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x28\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x28\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x29\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x29\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x29\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x29\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x29\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x29\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x29\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x29\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x29\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x29\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x29\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x29\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x29\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x29\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x29\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x29\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x2a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x2a\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x2a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x2a\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x2a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x2a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x2a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x2a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x2a\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x2a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x2a\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x2a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x2a\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x2a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x2a\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x2a\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x2b\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x2b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x2b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x2b\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x2b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x2b\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x2b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x2b\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x2b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x2b\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x2b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x2b\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x2b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x2b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x2b\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x2b\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x2c\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x2c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x2c\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x2c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x2c\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x2c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x2c\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x2c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x2c\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x2c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x2c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x2c\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x2c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x2c\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x2c\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x2c\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x2d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x2d\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x2d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x2d\x01\
+\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x2d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\
+\x2d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x2d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\
+\0\x70\x2d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x2d\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x90\x2d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x2d\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\xb0\x2d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x2d\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\xd0\x2d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x2d\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x2d\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x2e\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x2e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\x20\x2e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x30\x2e\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\x40\x2e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x50\x2e\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\x60\x2e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x2e\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\x80\x2e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x2e\x01\0\0\
+\0\0\0\x04\0\0\0\x02\0\0\0\xa0\x2e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x2e\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xc0\x2e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xd0\x2e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xe0\x2e\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xf0\x2e\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\0\x2f\x01\0\0\0\0\0\x04\0\0\0\
+\x02\0\0\0\x10\x2f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x20\x2f\x01\0\0\0\0\0\x04\
+\0\0\0\x02\0\0\0\x30\x2f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x40\x2f\x01\0\0\0\0\
+\0\x04\0\0\0\x02\0\0\0\x50\x2f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x60\x2f\x01\0\
+\0\0\0\0\x04\0\0\0\x02\0\0\0\x70\x2f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x80\x2f\
+\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x90\x2f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\
+\xa0\x2f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xb0\x2f\x01\0\0\0\0\0\x04\0\0\0\x02\
+\0\0\0\xc0\x2f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xd0\x2f\x01\0\0\0\0\0\x04\0\0\
+\0\x02\0\0\0\xe0\x2f\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\xf0\x2f\x01\0\0\0\0\0\
+\x04\0\0\0\x02\0\0\0\0\x30\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x10\x30\x01\0\0\0\
+\0\0\x04\0\0\0\x02\0\0\0\x20\x30\x01\0\0\0\0\0\x04\0\0\0\x02\0\0\0\x14\0\0\0\0\
+\0\0\0\x03\0\0\0\xc8\x02\0\0\x18\0\0\0\0\0\0\0\x02\0\0\0\x02\0\0\0\x22\0\0\0\0\
+\0\0\0\x03\0\0\0\xca\x02\0\0\x26\0\0\0\0\0\0\0\x03\0\0\0\xca\x02\0\0\x2a\0\0\0\
+\0\0\0\0\x03\0\0\0\xca\x02\0\0\x2e\0\0\0\0\0\0\0\x03\0\0\0\xca\x02\0\0\x32\0\0\
+\0\0\0\0\0\x03\0\0\0\xca\x02\0\0\x3e\0\0\0\0\0\0\0\x03\0\0\0\xca\x02\0\0\x53\0\
+\0\0\0\0\0\0\x03\0\0\0\xca\x02\0\0\x68\0\0\0\0\0\0\0\x03\0\0\0\xca\x02\0\0\x7d\
+\0\0\0\0\0\0\0\x03\0\0\0\xca\x02\0\0\x92\0\0\0\0\0\0\0\x03\0\0\0\xca\x02\0\0\
+\xa7\0\0\0\0\0\0\0\x03\0\0\0\xca\x02\0\0\xbc\0\0\0\0\0\0\0\x03\0\0\0\xca\x02\0\
+\0\xd1\0\0\0\0\0\0\0\x03\0\0\0\xca\x02\0\0\xe6\0\0\0\0\0\0\0\x03\0\0\0\xca\x02\
+\0\0\xfb\0\0\0\0\0\0\0\x03\0\0\0\xca\x02\0\0\x15\x01\0\0\0\0\0\0\x02\0\0\0\x02\
+\0\0\0\xcb\x05\xcc\x05\x04\x08\xc0\x05\xcd\x05\0\x2e\x64\x65\x62\x75\x67\x5f\
+\x61\x62\x62\x72\x65\x76\0\x2e\x74\x65\x78\x74\0\x2e\x72\x65\x6c\x2e\x42\x54\
+\x46\x2e\x65\x78\x74\0\x72\x73\x73\x5f\x66\x6c\x6f\x77\x5f\x61\x63\x74\x69\x6f\
+\x6e\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\0\x2e\x64\x65\x62\x75\x67\x5f\x72\x6e\x67\
+\x6c\x69\x73\x74\x73\0\x2e\x64\x65\x62\x75\x67\x5f\x6c\x6f\x63\x6c\x69\x73\x74\
+\x73\0\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x73\x74\x72\x5f\x6f\x66\x66\
+\x73\x65\x74\x73\0\x2e\x72\x65\x6c\x74\x63\x2f\x69\x6e\x67\x72\x65\x73\x73\0\
+\x2e\x6d\x61\x70\x73\0\x2e\x64\x65\x62\x75\x67\x5f\x73\x74\x72\0\x2e\x64\x65\
+\x62\x75\x67\x5f\x6c\x69\x6e\x65\x5f\x73\x74\x72\0\x2e\x72\x65\x6c\x2e\x64\x65\
+\x62\x75\x67\x5f\x61\x64\x64\x72\0\x72\x73\x73\x5f\x6d\x61\x70\0\x2e\x72\x65\
+\x6c\x2e\x64\x65\x62\x75\x67\x5f\x69\x6e\x66\x6f\0\x72\x73\x73\x5f\x66\x6c\x6f\
+\x77\x5f\x61\x63\x74\x69\x6f\x6e\0\x2e\x6c\x6c\x76\x6d\x5f\x61\x64\x64\x72\x73\
+\x69\x67\0\x5f\x6c\x69\x63\x65\x6e\x73\x65\0\x2e\x72\x65\x6c\x2e\x64\x65\x62\
+\x75\x67\x5f\x6c\x69\x6e\x65\0\x2e\x72\x65\x6c\x2e\x64\x65\x62\x75\x67\x5f\x66\
+\x72\x61\x6d\x65\0\x74\x61\x70\x5f\x72\x73\x73\x2e\x63\0\x2e\x73\x74\x72\x74\
+\x61\x62\0\x2e\x73\x79\x6d\x74\x61\x62\0\x2e\x72\x6f\x64\x61\x74\x61\0\x2e\x72\
+\x65\x6c\x2e\x42\x54\x46\0\x4c\x42\x42\x30\x5f\x39\0\x4c\x42\x42\x30\x5f\x39\
+\x39\0\x4c\x42\x42\x30\x5f\x32\x39\x39\0\x4c\x42\x42\x30\x5f\x31\x39\x39\0\x4c\
+\x42\x42\x30\x5f\x38\x39\0\x4c\x42\x42\x30\x5f\x32\x38\x39\0\x4c\x42\x42\x30\
+\x5f\x31\x38\x39\0\x4c\x42\x42\x30\x5f\x37\x39\0\x4c\x42\x42\x30\x5f\x32\x37\
+\x39\0\x4c\x42\x42\x30\x5f\x31\x37\x39\0\x4c\x42\x42\x30\x5f\x36\x39\0\x4c\x42\
+\x42\x30\x5f\x32\x36\x39\0\x4c\x42\x42\x30\x5f\x31\x36\x39\0\x4c\x42\x42\x30\
+\x5f\x35\x39\0\x4c\x42\x42\x30\x5f\x32\x35\x39\0\x4c\x42\x42\x30\x5f\x31\x35\
+\x39\0\x4c\x42\x42\x30\x5f\x34\x39\0\x4c\x42\x42\x30\x5f\x38\x34\x39\0\x4c\x42\
+\x42\x30\x5f\x32\x34\x39\0\x4c\x42\x42\x30\x5f\x31\x34\x39\0\x4c\x42\x42\x30\
+\x5f\x33\x39\0\x4c\x42\x42\x30\x5f\x38\x33\x39\0\x4c\x42\x42\x30\x5f\x32\x33\
+\x39\0\x4c\x42\x42\x30\x5f\x31\x33\x39\0\x4c\x42\x42\x30\x5f\x32\x39\0\x4c\x42\
+\x42\x30\x5f\x32\x32\x39\0\x4c\x42\x42\x30\x5f\x31\x32\x39\0\x4c\x42\x42\x30\
+\x5f\x31\x39\0\x4c\x42\x42\x30\x5f\x33\x31\x39\0\x4c\x42\x42\x30\x5f\x32\x31\
+\x39\0\x4c\x42\x42\x30\x5f\x31\x31\x39\0\x4c\x42\x42\x30\x5f\x33\x30\x39\0\x4c\
+\x42\x42\x30\x5f\x32\x30\x39\0\x4c\x42\x42\x30\x5f\x31\x30\x39\0\x4c\x42\x42\
+\x30\x5f\x39\x39\x38\0\x4c\x42\x42\x30\x5f\x38\x39\x38\0\x4c\x42\x42\x30\x5f\
+\x37\x39\x38\0\x4c\x42\x42\x30\x5f\x36\x39\x38\0\x4c\x42\x42\x30\x5f\x35\x39\
+\x38\0\x4c\x42\x42\x30\x5f\x34\x39\x38\0\x4c\x42\x42\x30\x5f\x33\x39\x38\0\x4c\
+\x42\x42\x30\x5f\x31\x33\x39\x38\0\x4c\x42\x42\x30\x5f\x31\x32\x39\x38\0\x4c\
+\x42\x42\x30\x5f\x31\x31\x39\x38\0\x4c\x42\x42\x30\x5f\x31\x30\x39\x38\0\x4c\
+\x42\x42\x30\x5f\x39\x38\x38\0\x4c\x42\x42\x30\x5f\x38\x38\x38\0\x4c\x42\x42\
+\x30\x5f\x37\x38\x38\0\x4c\x42\x42\x30\x5f\x36\x38\x38\0\x4c\x42\x42\x30\x5f\
+\x35\x38\x38\0\x4c\x42\x42\x30\x5f\x34\x38\x38\0\x4c\x42\x42\x30\x5f\x33\x38\
+\x38\0\x4c\x42\x42\x30\x5f\x31\x33\x38\x38\0\x4c\x42\x42\x30\x5f\x31\x32\x38\
+\x38\0\x4c\x42\x42\x30\x5f\x31\x31\x38\x38\0\x4c\x42\x42\x30\x5f\x31\x30\x38\
+\x38\0\x4c\x42\x42\x30\x5f\x39\x37\x38\0\x4c\x42\x42\x30\x5f\x38\x37\x38\0\x4c\
+\x42\x42\x30\x5f\x37\x37\x38\0\x4c\x42\x42\x30\x5f\x36\x37\x38\0\x4c\x42\x42\
+\x30\x5f\x35\x37\x38\0\x4c\x42\x42\x30\x5f\x34\x37\x38\0\x4c\x42\x42\x30\x5f\
+\x33\x37\x38\0\x4c\x42\x42\x30\x5f\x31\x33\x37\x38\0\x4c\x42\x42\x30\x5f\x31\
+\x32\x37\x38\0\x4c\x42\x42\x30\x5f\x31\x31\x37\x38\0\x4c\x42\x42\x30\x5f\x31\
+\x30\x37\x38\0\x4c\x42\x42\x30\x5f\x39\x36\x38\0\x4c\x42\x42\x30\x5f\x38\x36\
+\x38\0\x4c\x42\x42\x30\x5f\x37\x36\x38\0\x4c\x42\x42\x30\x5f\x36\x36\x38\0\x4c\
+\x42\x42\x30\x5f\x35\x36\x38\0\x4c\x42\x42\x30\x5f\x34\x36\x38\0\x4c\x42\x42\
+\x30\x5f\x33\x36\x38\0\x4c\x42\x42\x30\x5f\x31\x33\x36\x38\0\x4c\x42\x42\x30\
+\x5f\x31\x32\x36\x38\0\x4c\x42\x42\x30\x5f\x31\x31\x36\x38\0\x4c\x42\x42\x30\
+\x5f\x31\x30\x36\x38\0\x4c\x42\x42\x30\x5f\x39\x35\x38\0\x4c\x42\x42\x30\x5f\
+\x38\x35\x38\0\x4c\x42\x42\x30\x5f\x37\x35\x38\0\x4c\x42\x42\x30\x5f\x36\x35\
+\x38\0\x4c\x42\x42\x30\x5f\x35\x35\x38\0\x4c\x42\x42\x30\x5f\x34\x35\x38\0\x4c\
+\x42\x42\x30\x5f\x33\x35\x38\0\x4c\x42\x42\x30\x5f\x31\x33\x35\x38\0\x4c\x42\
+\x42\x30\x5f\x31\x32\x35\x38\0\x4c\x42\x42\x30\x5f\x31\x31\x35\x38\0\x4c\x42\
+\x42\x30\x5f\x31\x30\x35\x38\0\x4c\x42\x42\x30\x5f\x39\x34\x38\0\x4c\x42\x42\
+\x30\x5f\x38\x34\x38\0\x4c\x42\x42\x30\x5f\x37\x34\x38\0\x4c\x42\x42\x30\x5f\
+\x36\x34\x38\0\x4c\x42\x42\x30\x5f\x35\x34\x38\0\x4c\x42\x42\x30\x5f\x34\x34\
+\x38\0\x4c\x42\x42\x30\x5f\x33\x34\x38\0\x4c\x42\x42\x30\x5f\x31\x33\x34\x38\0\
+\x4c\x42\x42\x30\x5f\x31\x32\x34\x38\0\x4c\x42\x42\x30\x5f\x31\x31\x34\x38\0\
+\x4c\x42\x42\x30\x5f\x31\x30\x34\x38\0\x4c\x42\x42\x30\x5f\x39\x33\x38\0\x4c\
+\x42\x42\x30\x5f\x37\x33\x38\0\x4c\x42\x42\x30\x5f\x36\x33\x38\0\x4c\x42\x42\
+\x30\x5f\x35\x33\x38\0\x4c\x42\x42\x30\x5f\x34\x33\x38\0\x4c\x42\x42\x30\x5f\
+\x33\x33\x38\0\x4c\x42\x42\x30\x5f\x31\x33\x33\x38\0\x4c\x42\x42\x30\x5f\x31\
+\x32\x33\x38\0\x4c\x42\x42\x30\x5f\x31\x31\x33\x38\0\x4c\x42\x42\x30\x5f\x31\
+\x30\x33\x38\0\x4c\x42\x42\x30\x5f\x39\x32\x38\0\x4c\x42\x42\x30\x5f\x37\x32\
+\x38\0\x4c\x42\x42\x30\x5f\x36\x32\x38\0\x4c\x42\x42\x30\x5f\x35\x32\x38\0\x4c\
+\x42\x42\x30\x5f\x34\x32\x38\0\x4c\x42\x42\x30\x5f\x33\x32\x38\0\x4c\x42\x42\
+\x30\x5f\x31\x33\x32\x38\0\x4c\x42\x42\x30\x5f\x31\x32\x32\x38\0\x4c\x42\x42\
+\x30\x5f\x31\x31\x32\x38\0\x4c\x42\x42\x30\x5f\x31\x30\x32\x38\0\x4c\x42\x42\
+\x30\x5f\x39\x31\x38\0\x4c\x42\x42\x30\x5f\x38\x31\x38\0\x4c\x42\x42\x30\x5f\
+\x37\x31\x38\0\x4c\x42\x42\x30\x5f\x36\x31\x38\0\x4c\x42\x42\x30\x5f\x35\x31\
+\x38\0\x4c\x42\x42\x30\x5f\x34\x31\x38\0\x4c\x42\x42\x30\x5f\x31\x33\x31\x38\0\
+\x4c\x42\x42\x30\x5f\x31\x32\x31\x38\0\x4c\x42\x42\x30\x5f\x31\x31\x31\x38\0\
+\x4c\x42\x42\x30\x5f\x31\x30\x31\x38\0\x4c\x42\x42\x30\x5f\x39\x30\x38\0\x4c\
+\x42\x42\x30\x5f\x38\x30\x38\0\x4c\x42\x42\x30\x5f\x37\x30\x38\0\x4c\x42\x42\
+\x30\x5f\x36\x30\x38\0\x4c\x42\x42\x30\x5f\x35\x30\x38\0\x4c\x42\x42\x30\x5f\
+\x34\x30\x38\0\x4c\x42\x42\x30\x5f\x31\x34\x30\x38\0\x4c\x42\x42\x30\x5f\x31\
+\x33\x30\x38\0\x4c\x42\x42\x30\x5f\x31\x32\x30\x38\0\x4c\x42\x42\x30\x5f\x31\
+\x31\x30\x38\0\x4c\x42\x42\x30\x5f\x31\x30\x30\x38\0\x4c\x42\x42\x30\x5f\x39\
+\x37\0\x4c\x42\x42\x30\x5f\x32\x39\x37\0\x4c\x42\x42\x30\x5f\x31\x39\x37\0\x4c\
+\x42\x42\x30\x5f\x38\x37\0\x4c\x42\x42\x30\x5f\x32\x38\x37\0\x4c\x42\x42\x30\
+\x5f\x31\x38\x37\0\x4c\x42\x42\x30\x5f\x37\x37\0\x4c\x42\x42\x30\x5f\x32\x37\
+\x37\0\x4c\x42\x42\x30\x5f\x31\x37\x37\0\x4c\x42\x42\x30\x5f\x36\x37\0\x4c\x42\
+\x42\x30\x5f\x32\x36\x37\0\x4c\x42\x42\x30\x5f\x31\x36\x37\0\x4c\x42\x42\x30\
+\x5f\x35\x37\0\x4c\x42\x42\x30\x5f\x32\x35\x37\0\x4c\x42\x42\x30\x5f\x31\x35\
+\x37\0\x4c\x42\x42\x30\x5f\x34\x37\0\x4c\x42\x42\x30\x5f\x32\x34\x37\0\x4c\x42\
+\x42\x30\x5f\x31\x34\x37\0\x4c\x42\x42\x30\x5f\x33\x37\0\x4c\x42\x42\x30\x5f\
+\x38\x33\x37\0\x4c\x42\x42\x30\x5f\x32\x33\x37\0\x4c\x42\x42\x30\x5f\x32\x37\0\
+\x4c\x42\x42\x30\x5f\x38\x32\x37\0\x4c\x42\x42\x30\x5f\x32\x32\x37\0\x4c\x42\
+\x42\x30\x5f\x31\x32\x37\0\x4c\x42\x42\x30\x5f\x31\x37\0\x4c\x42\x42\x30\x5f\
+\x33\x31\x37\0\x4c\x42\x42\x30\x5f\x32\x31\x37\0\x4c\x42\x42\x30\x5f\x31\x31\
+\x37\0\x4c\x42\x42\x30\x5f\x33\x30\x37\0\x4c\x42\x42\x30\x5f\x32\x30\x37\0\x4c\
+\x42\x42\x30\x5f\x31\x30\x37\0\x4c\x42\x42\x30\x5f\x39\x39\x36\0\x4c\x42\x42\
+\x30\x5f\x38\x39\x36\0\x4c\x42\x42\x30\x5f\x37\x39\x36\0\x4c\x42\x42\x30\x5f\
+\x36\x39\x36\0\x4c\x42\x42\x30\x5f\x35\x39\x36\0\x4c\x42\x42\x30\x5f\x34\x39\
+\x36\0\x4c\x42\x42\x30\x5f\x33\x39\x36\0\x4c\x42\x42\x30\x5f\x31\x33\x39\x36\0\
+\x4c\x42\x42\x30\x5f\x31\x32\x39\x36\0\x4c\x42\x42\x30\x5f\x31\x31\x39\x36\0\
+\x4c\x42\x42\x30\x5f\x31\x30\x39\x36\0\x4c\x42\x42\x30\x5f\x39\x38\x36\0\x4c\
+\x42\x42\x30\x5f\x38\x38\x36\0\x4c\x42\x42\x30\x5f\x37\x38\x36\0\x4c\x42\x42\
+\x30\x5f\x36\x38\x36\0\x4c\x42\x42\x30\x5f\x35\x38\x36\0\x4c\x42\x42\x30\x5f\
+\x34\x38\x36\0\x4c\x42\x42\x30\x5f\x33\x38\x36\0\x4c\x42\x42\x30\x5f\x31\x33\
+\x38\x36\0\x4c\x42\x42\x30\x5f\x31\x32\x38\x36\0\x4c\x42\x42\x30\x5f\x31\x31\
+\x38\x36\0\x4c\x42\x42\x30\x5f\x31\x30\x38\x36\0\x4c\x42\x42\x30\x5f\x39\x37\
+\x36\0\x4c\x42\x42\x30\x5f\x38\x37\x36\0\x4c\x42\x42\x30\x5f\x37\x37\x36\0\x4c\
+\x42\x42\x30\x5f\x36\x37\x36\0\x4c\x42\x42\x30\x5f\x35\x37\x36\0\x4c\x42\x42\
+\x30\x5f\x34\x37\x36\0\x4c\x42\x42\x30\x5f\x33\x37\x36\0\x4c\x42\x42\x30\x5f\
+\x31\x33\x37\x36\0\x4c\x42\x42\x30\x5f\x31\x32\x37\x36\0\x4c\x42\x42\x30\x5f\
+\x31\x31\x37\x36\0\x4c\x42\x42\x30\x5f\x31\x30\x37\x36\0\x4c\x42\x42\x30\x5f\
+\x39\x36\x36\0\x4c\x42\x42\x30\x5f\x38\x36\x36\0\x4c\x42\x42\x30\x5f\x37\x36\
+\x36\0\x4c\x42\x42\x30\x5f\x36\x36\x36\0\x4c\x42\x42\x30\x5f\x35\x36\x36\0\x4c\
+\x42\x42\x30\x5f\x34\x36\x36\0\x4c\x42\x42\x30\x5f\x33\x36\x36\0\x4c\x42\x42\
+\x30\x5f\x31\x33\x36\x36\0\x4c\x42\x42\x30\x5f\x31\x32\x36\x36\0\x4c\x42\x42\
+\x30\x5f\x31\x31\x36\x36\0\x4c\x42\x42\x30\x5f\x31\x30\x36\x36\0\x4c\x42\x42\
+\x30\x5f\x39\x35\x36\0\x4c\x42\x42\x30\x5f\x38\x35\x36\0\x4c\x42\x42\x30\x5f\
+\x37\x35\x36\0\x4c\x42\x42\x30\x5f\x36\x35\x36\0\x4c\x42\x42\x30\x5f\x35\x35\
+\x36\0\x4c\x42\x42\x30\x5f\x34\x35\x36\0\x4c\x42\x42\x30\x5f\x33\x35\x36\0\x4c\
+\x42\x42\x30\x5f\x31\x33\x35\x36\0\x4c\x42\x42\x30\x5f\x31\x32\x35\x36\0\x4c\
+\x42\x42\x30\x5f\x31\x31\x35\x36\0\x4c\x42\x42\x30\x5f\x31\x30\x35\x36\0\x4c\
+\x42\x42\x30\x5f\x39\x34\x36\0\x4c\x42\x42\x30\x5f\x37\x34\x36\0\x4c\x42\x42\
+\x30\x5f\x36\x34\x36\0\x4c\x42\x42\x30\x5f\x35\x34\x36\0\x4c\x42\x42\x30\x5f\
+\x34\x34\x36\0\x4c\x42\x42\x30\x5f\x33\x34\x36\0\x4c\x42\x42\x30\x5f\x31\x33\
+\x34\x36\0\x4c\x42\x42\x30\x5f\x31\x32\x34\x36\0\x4c\x42\x42\x30\x5f\x31\x31\
+\x34\x36\0\x4c\x42\x42\x30\x5f\x31\x30\x34\x36\0\x4c\x42\x42\x30\x5f\x39\x33\
+\x36\0\x4c\x42\x42\x30\x5f\x37\x33\x36\0\x4c\x42\x42\x30\x5f\x36\x33\x36\0\x4c\
+\x42\x42\x30\x5f\x35\x33\x36\0\x4c\x42\x42\x30\x5f\x34\x33\x36\0\x4c\x42\x42\
+\x30\x5f\x33\x33\x36\0\x4c\x42\x42\x30\x5f\x31\x33\x33\x36\0\x4c\x42\x42\x30\
+\x5f\x31\x32\x33\x36\0\x4c\x42\x42\x30\x5f\x31\x33\x36\0\x4c\x42\x42\x30\x5f\
+\x31\x31\x33\x36\0\x4c\x42\x42\x30\x5f\x31\x30\x33\x36\0\x4c\x42\x42\x30\x5f\
+\x39\x32\x36\0\x4c\x42\x42\x30\x5f\x37\x32\x36\0\x4c\x42\x42\x30\x5f\x36\x32\
+\x36\0\x4c\x42\x42\x30\x5f\x35\x32\x36\0\x4c\x42\x42\x30\x5f\x34\x32\x36\0\x4c\
+\x42\x42\x30\x5f\x31\x33\x32\x36\0\x4c\x42\x42\x30\x5f\x31\x32\x32\x36\0\x4c\
+\x42\x42\x30\x5f\x31\x31\x32\x36\0\x4c\x42\x42\x30\x5f\x31\x30\x32\x36\0\x4c\
+\x42\x42\x30\x5f\x39\x31\x36\0\x4c\x42\x42\x30\x5f\x38\x31\x36\0\x4c\x42\x42\
+\x30\x5f\x37\x31\x36\0\x4c\x42\x42\x30\x5f\x36\x31\x36\0\x4c\x42\x42\x30\x5f\
+\x35\x31\x36\0\x4c\x42\x42\x30\x5f\x34\x31\x36\0\x4c\x42\x42\x30\x5f\x31\x33\
+\x31\x36\0\x4c\x42\x42\x30\x5f\x31\x32\x31\x36\0\x4c\x42\x42\x30\x5f\x31\x31\
+\x31\x36\0\x4c\x42\x42\x30\x5f\x31\x30\x31\x36\0\x4c\x42\x42\x30\x5f\x39\x30\
+\x36\0\x4c\x42\x42\x30\x5f\x38\x30\x36\0\x4c\x42\x42\x30\x5f\x37\x30\x36\0\x4c\
+\x42\x42\x30\x5f\x36\x30\x36\0\x4c\x42\x42\x30\x5f\x35\x30\x36\0\x4c\x42\x42\
+\x30\x5f\x34\x30\x36\0\x4c\x42\x42\x30\x5f\x31\x34\x30\x36\0\x4c\x42\x42\x30\
+\x5f\x31\x33\x30\x36\0\x4c\x42\x42\x30\x5f\x31\x32\x30\x36\0\x4c\x42\x42\x30\
+\x5f\x31\x31\x30\x36\0\x4c\x42\x42\x30\x5f\x31\x30\x30\x36\0\x4c\x42\x42\x30\
+\x5f\x35\0\x4c\x42\x42\x30\x5f\x39\x35\0\x4c\x42\x42\x30\x5f\x32\x39\x35\0\x4c\
+\x42\x42\x30\x5f\x31\x39\x35\0\x4c\x42\x42\x30\x5f\x38\x35\0\x4c\x42\x42\x30\
+\x5f\x32\x38\x35\0\x4c\x42\x42\x30\x5f\x31\x38\x35\0\x4c\x42\x42\x30\x5f\x37\
+\x35\0\x4c\x42\x42\x30\x5f\x32\x37\x35\0\x4c\x42\x42\x30\x5f\x31\x37\x35\0\x4c\
+\x42\x42\x30\x5f\x36\x35\0\x4c\x42\x42\x30\x5f\x32\x36\x35\0\x4c\x42\x42\x30\
+\x5f\x31\x36\x35\0\x4c\x42\x42\x30\x5f\x35\x35\0\x4c\x42\x42\x30\x5f\x32\x35\
+\x35\0\x4c\x42\x42\x30\x5f\x31\x35\x35\0\x4c\x42\x42\x30\x5f\x34\x35\0\x4c\x42\
+\x42\x30\x5f\x38\x34\x35\0\x4c\x42\x42\x30\x5f\x32\x34\x35\0\x4c\x42\x42\x30\
+\x5f\x31\x34\x35\0\x4c\x42\x42\x30\x5f\x33\x35\0\x4c\x42\x42\x30\x5f\x32\x33\
+\x35\0\x4c\x42\x42\x30\x5f\x32\x35\0\x4c\x42\x42\x30\x5f\x38\x32\x35\0\x4c\x42\
+\x42\x30\x5f\x32\x32\x35\0\x4c\x42\x42\x30\x5f\x31\x32\x35\0\x4c\x42\x42\x30\
+\x5f\x31\x35\0\x4c\x42\x42\x30\x5f\x33\x31\x35\0\x4c\x42\x42\x30\x5f\x32\x31\
+\x35\0\x4c\x42\x42\x30\x5f\x31\x31\x35\0\x4c\x42\x42\x30\x5f\x33\x30\x35\0\x4c\
+\x42\x42\x30\x5f\x32\x30\x35\0\x4c\x42\x42\x30\x5f\x31\x30\x35\0\x4c\x42\x42\
+\x30\x5f\x39\x39\x34\0\x4c\x42\x42\x30\x5f\x38\x39\x34\0\x4c\x42\x42\x30\x5f\
+\x37\x39\x34\0\x4c\x42\x42\x30\x5f\x36\x39\x34\0\x4c\x42\x42\x30\x5f\x35\x39\
+\x34\0\x4c\x42\x42\x30\x5f\x34\x39\x34\0\x4c\x42\x42\x30\x5f\x33\x39\x34\0\x4c\
+\x42\x42\x30\x5f\x31\x33\x39\x34\0\x4c\x42\x42\x30\x5f\x31\x32\x39\x34\0\x4c\
+\x42\x42\x30\x5f\x31\x31\x39\x34\0\x4c\x42\x42\x30\x5f\x31\x30\x39\x34\0\x4c\
+\x42\x42\x30\x5f\x39\x38\x34\0\x4c\x42\x42\x30\x5f\x38\x38\x34\0\x4c\x42\x42\
+\x30\x5f\x37\x38\x34\0\x4c\x42\x42\x30\x5f\x36\x38\x34\0\x4c\x42\x42\x30\x5f\
+\x35\x38\x34\0\x4c\x42\x42\x30\x5f\x34\x38\x34\0\x4c\x42\x42\x30\x5f\x33\x38\
+\x34\0\x4c\x42\x42\x30\x5f\x31\x33\x38\x34\0\x4c\x42\x42\x30\x5f\x31\x32\x38\
+\x34\0\x4c\x42\x42\x30\x5f\x31\x31\x38\x34\0\x4c\x42\x42\x30\x5f\x31\x30\x38\
+\x34\0\x4c\x42\x42\x30\x5f\x39\x37\x34\0\x4c\x42\x42\x30\x5f\x38\x37\x34\0\x4c\
+\x42\x42\x30\x5f\x37\x37\x34\0\x4c\x42\x42\x30\x5f\x36\x37\x34\0\x4c\x42\x42\
+\x30\x5f\x35\x37\x34\0\x4c\x42\x42\x30\x5f\x34\x37\x34\0\x4c\x42\x42\x30\x5f\
+\x33\x37\x34\0\x4c\x42\x42\x30\x5f\x31\x33\x37\x34\0\x4c\x42\x42\x30\x5f\x31\
+\x32\x37\x34\0\x4c\x42\x42\x30\x5f\x31\x31\x37\x34\0\x4c\x42\x42\x30\x5f\x31\
+\x30\x37\x34\0\x4c\x42\x42\x30\x5f\x39\x36\x34\0\x4c\x42\x42\x30\x5f\x38\x36\
+\x34\0\x4c\x42\x42\x30\x5f\x37\x36\x34\0\x4c\x42\x42\x30\x5f\x36\x36\x34\0\x4c\
+\x42\x42\x30\x5f\x35\x36\x34\0\x4c\x42\x42\x30\x5f\x34\x36\x34\0\x4c\x42\x42\
+\x30\x5f\x33\x36\x34\0\x4c\x42\x42\x30\x5f\x31\x33\x36\x34\0\x4c\x42\x42\x30\
+\x5f\x31\x32\x36\x34\0\x4c\x42\x42\x30\x5f\x31\x31\x36\x34\0\x4c\x42\x42\x30\
+\x5f\x31\x30\x36\x34\0\x4c\x42\x42\x30\x5f\x39\x35\x34\0\x4c\x42\x42\x30\x5f\
+\x38\x35\x34\0\x4c\x42\x42\x30\x5f\x37\x35\x34\0\x4c\x42\x42\x30\x5f\x36\x35\
+\x34\0\x4c\x42\x42\x30\x5f\x35\x35\x34\0\x4c\x42\x42\x30\x5f\x34\x35\x34\0\x4c\
+\x42\x42\x30\x5f\x33\x35\x34\0\x4c\x42\x42\x30\x5f\x31\x33\x35\x34\0\x4c\x42\
+\x42\x30\x5f\x31\x32\x35\x34\0\x4c\x42\x42\x30\x5f\x31\x31\x35\x34\0\x4c\x42\
+\x42\x30\x5f\x31\x30\x35\x34\0\x4c\x42\x42\x30\x5f\x39\x34\x34\0\x4c\x42\x42\
+\x30\x5f\x37\x34\x34\0\x4c\x42\x42\x30\x5f\x36\x34\x34\0\x4c\x42\x42\x30\x5f\
+\x35\x34\x34\0\x4c\x42\x42\x30\x5f\x34\x34\x34\0\x4c\x42\x42\x30\x5f\x33\x34\
+\x34\0\x4c\x42\x42\x30\x5f\x31\x33\x34\x34\0\x4c\x42\x42\x30\x5f\x31\x32\x34\
+\x34\0\x4c\x42\x42\x30\x5f\x31\x31\x34\x34\0\x4c\x42\x42\x30\x5f\x31\x30\x34\
+\x34\0\x4c\x42\x42\x30\x5f\x39\x33\x34\0\x4c\x42\x42\x30\x5f\x37\x33\x34\0\x4c\
+\x42\x42\x30\x5f\x36\x33\x34\0\x4c\x42\x42\x30\x5f\x35\x33\x34\0\x4c\x42\x42\
+\x30\x5f\x34\x33\x34\0\x4c\x42\x42\x30\x5f\x33\x33\x34\0\x4c\x42\x42\x30\x5f\
+\x31\x33\x33\x34\0\x4c\x42\x42\x30\x5f\x31\x32\x33\x34\0\x4c\x42\x42\x30\x5f\
+\x31\x31\x33\x34\0\x4c\x42\x42\x30\x5f\x31\x30\x33\x34\0\x4c\x42\x42\x30\x5f\
+\x39\x32\x34\0\x4c\x42\x42\x30\x5f\x37\x32\x34\0\x4c\x42\x42\x30\x5f\x36\x32\
+\x34\0\x4c\x42\x42\x30\x5f\x35\x32\x34\0\x4c\x42\x42\x30\x5f\x34\x32\x34\0\x4c\
+\x42\x42\x30\x5f\x33\x32\x34\0\x4c\x42\x42\x30\x5f\x31\x33\x32\x34\0\x4c\x42\
+\x42\x30\x5f\x31\x32\x32\x34\0\x4c\x42\x42\x30\x5f\x31\x31\x32\x34\0\x4c\x42\
+\x42\x30\x5f\x31\x30\x32\x34\0\x4c\x42\x42\x30\x5f\x39\x31\x34\0\x4c\x42\x42\
+\x30\x5f\x38\x31\x34\0\x4c\x42\x42\x30\x5f\x37\x31\x34\0\x4c\x42\x42\x30\x5f\
+\x36\x31\x34\0\x4c\x42\x42\x30\x5f\x35\x31\x34\0\x4c\x42\x42\x30\x5f\x34\x31\
+\x34\0\x4c\x42\x42\x30\x5f\x31\x33\x31\x34\0\x4c\x42\x42\x30\x5f\x31\x32\x31\
+\x34\0\x4c\x42\x42\x30\x5f\x31\x31\x31\x34\0\x4c\x42\x42\x30\x5f\x31\x30\x31\
+\x34\0\x4c\x42\x42\x30\x5f\x39\x30\x34\0\x4c\x42\x42\x30\x5f\x38\x30\x34\0\x4c\
+\x42\x42\x30\x5f\x37\x30\x34\0\x4c\x42\x42\x30\x5f\x36\x30\x34\0\x4c\x42\x42\
+\x30\x5f\x35\x30\x34\0\x4c\x42\x42\x30\x5f\x34\x30\x34\0\x4c\x42\x42\x30\x5f\
+\x31\x34\x30\x34\0\x4c\x42\x42\x30\x5f\x31\x33\x30\x34\0\x4c\x42\x42\x30\x5f\
+\x31\x32\x30\x34\0\x4c\x42\x42\x30\x5f\x31\x31\x30\x34\0\x4c\x42\x42\x30\x5f\
+\x31\x30\x30\x34\0\x4c\x42\x42\x30\x5f\x39\x33\0\x4c\x42\x42\x30\x5f\x32\x39\
+\x33\0\x4c\x42\x42\x30\x5f\x31\x39\x33\0\x4c\x42\x42\x30\x5f\x38\x33\0\x4c\x42\
+\x42\x30\x5f\x32\x38\x33\0\x4c\x42\x42\x30\x5f\x31\x38\x33\0\x4c\x42\x42\x30\
+\x5f\x37\x33\0\x4c\x42\x42\x30\x5f\x32\x37\x33\0\x4c\x42\x42\x30\x5f\x31\x37\
+\x33\0\x4c\x42\x42\x30\x5f\x36\x33\0\x4c\x42\x42\x30\x5f\x32\x36\x33\0\x4c\x42\
+\x42\x30\x5f\x31\x36\x33\0\x4c\x42\x42\x30\x5f\x35\x33\0\x4c\x42\x42\x30\x5f\
+\x32\x35\x33\0\x4c\x42\x42\x30\x5f\x31\x35\x33\0\x4c\x42\x42\x30\x5f\x34\x33\0\
+\x4c\x42\x42\x30\x5f\x38\x34\x33\0\x4c\x42\x42\x30\x5f\x32\x34\x33\0\x4c\x42\
+\x42\x30\x5f\x31\x34\x33\0\x4c\x42\x42\x30\x5f\x33\x33\0\x4c\x42\x42\x30\x5f\
+\x38\x33\x33\0\x4c\x42\x42\x30\x5f\x32\x33\x33\0\x4c\x42\x42\x30\x5f\x31\x33\
+\x33\0\x4c\x42\x42\x30\x5f\x32\x33\0\x4c\x42\x42\x30\x5f\x33\x32\x33\0\x4c\x42\
+\x42\x30\x5f\x32\x32\x33\0\x4c\x42\x42\x30\x5f\x31\x32\x33\0\x4c\x42\x42\x30\
+\x5f\x31\x33\0\x4c\x42\x42\x30\x5f\x33\x31\x33\0\x4c\x42\x42\x30\x5f\x32\x31\
+\x33\0\x4c\x42\x42\x30\x5f\x31\x31\x33\0\x4c\x42\x42\x30\x5f\x33\x30\x33\0\x4c\
+\x42\x42\x30\x5f\x32\x30\x33\0\x4c\x42\x42\x30\x5f\x31\x30\x33\0\x4c\x42\x42\
+\x30\x5f\x32\0\x4c\x42\x42\x30\x5f\x39\x39\x32\0\x4c\x42\x42\x30\x5f\x38\x39\
+\x32\0\x4c\x42\x42\x30\x5f\x37\x39\x32\0\x4c\x42\x42\x30\x5f\x36\x39\x32\0\x4c\
+\x42\x42\x30\x5f\x35\x39\x32\0\x4c\x42\x42\x30\x5f\x34\x39\x32\0\x4c\x42\x42\
+\x30\x5f\x33\x39\x32\0\x4c\x42\x42\x30\x5f\x31\x33\x39\x32\0\x4c\x42\x42\x30\
+\x5f\x31\x32\x39\x32\0\x4c\x42\x42\x30\x5f\x31\x31\x39\x32\0\x4c\x42\x42\x30\
+\x5f\x31\x30\x39\x32\0\x4c\x42\x42\x30\x5f\x39\x38\x32\0\x4c\x42\x42\x30\x5f\
+\x38\x38\x32\0\x4c\x42\x42\x30\x5f\x37\x38\x32\0\x4c\x42\x42\x30\x5f\x36\x38\
+\x32\0\x4c\x42\x42\x30\x5f\x35\x38\x32\0\x4c\x42\x42\x30\x5f\x34\x38\x32\0\x4c\
+\x42\x42\x30\x5f\x33\x38\x32\0\x4c\x42\x42\x30\x5f\x31\x33\x38\x32\0\x4c\x42\
+\x42\x30\x5f\x31\x32\x38\x32\0\x4c\x42\x42\x30\x5f\x31\x31\x38\x32\0\x4c\x42\
+\x42\x30\x5f\x31\x30\x38\x32\0\x4c\x42\x42\x30\x5f\x39\x37\x32\0\x4c\x42\x42\
+\x30\x5f\x38\x37\x32\0\x4c\x42\x42\x30\x5f\x37\x37\x32\0\x4c\x42\x42\x30\x5f\
+\x36\x37\x32\0\x4c\x42\x42\x30\x5f\x35\x37\x32\0\x4c\x42\x42\x30\x5f\x34\x37\
+\x32\0\x4c\x42\x42\x30\x5f\x33\x37\x32\0\x4c\x42\x42\x30\x5f\x31\x33\x37\x32\0\
+\x4c\x42\x42\x30\x5f\x31\x32\x37\x32\0\x4c\x42\x42\x30\x5f\x31\x31\x37\x32\0\
+\x4c\x42\x42\x30\x5f\x31\x30\x37\x32\0\x4c\x42\x42\x30\x5f\x39\x36\x32\0\x4c\
+\x42\x42\x30\x5f\x38\x36\x32\0\x4c\x42\x42\x30\x5f\x37\x36\x32\0\x4c\x42\x42\
+\x30\x5f\x36\x36\x32\0\x4c\x42\x42\x30\x5f\x35\x36\x32\0\x4c\x42\x42\x30\x5f\
+\x34\x36\x32\0\x4c\x42\x42\x30\x5f\x33\x36\x32\0\x4c\x42\x42\x30\x5f\x31\x33\
+\x36\x32\0\x4c\x42\x42\x30\x5f\x31\x32\x36\x32\0\x4c\x42\x42\x30\x5f\x31\x31\
+\x36\x32\0\x4c\x42\x42\x30\x5f\x31\x30\x36\x32\0\x4c\x42\x42\x30\x5f\x39\x35\
+\x32\0\x4c\x42\x42\x30\x5f\x37\x35\x32\0\x4c\x42\x42\x30\x5f\x36\x35\x32\0\x4c\
+\x42\x42\x30\x5f\x35\x35\x32\0\x4c\x42\x42\x30\x5f\x34\x35\x32\0\x4c\x42\x42\
+\x30\x5f\x33\x35\x32\0\x4c\x42\x42\x30\x5f\x31\x33\x35\x32\0\x4c\x42\x42\x30\
+\x5f\x31\x32\x35\x32\0\x4c\x42\x42\x30\x5f\x31\x31\x35\x32\0\x4c\x42\x42\x30\
+\x5f\x31\x30\x35\x32\0\x4c\x42\x42\x30\x5f\x39\x34\x32\0\x4c\x42\x42\x30\x5f\
+\x37\x34\x32\0\x4c\x42\x42\x30\x5f\x36\x34\x32\0\x4c\x42\x42\x30\x5f\x35\x34\
+\x32\0\x4c\x42\x42\x30\x5f\x34\x34\x32\0\x4c\x42\x42\x30\x5f\x33\x34\x32\0\x4c\
+\x42\x42\x30\x5f\x31\x33\x34\x32\0\x4c\x42\x42\x30\x5f\x31\x32\x34\x32\0\x4c\
+\x42\x42\x30\x5f\x31\x31\x34\x32\0\x4c\x42\x42\x30\x5f\x31\x30\x34\x32\0\x4c\
+\x42\x42\x30\x5f\x39\x33\x32\0\x4c\x42\x42\x30\x5f\x37\x33\x32\0\x4c\x42\x42\
+\x30\x5f\x36\x33\x32\0\x4c\x42\x42\x30\x5f\x35\x33\x32\0\x4c\x42\x42\x30\x5f\
+\x34\x33\x32\0\x4c\x42\x42\x30\x5f\x33\x33\x32\0\x4c\x42\x42\x30\x5f\x31\x33\
+\x33\x32\0\x4c\x42\x42\x30\x5f\x31\x32\x33\x32\0\x4c\x42\x42\x30\x5f\x31\x33\
+\x32\0\x4c\x42\x42\x30\x5f\x31\x31\x33\x32\0\x4c\x42\x42\x30\x5f\x31\x30\x33\
+\x32\0\x4c\x42\x42\x30\x5f\x39\x32\x32\0\x4c\x42\x42\x30\x5f\x38\x32\x32\0\x4c\
+\x42\x42\x30\x5f\x37\x32\x32\0\x4c\x42\x42\x30\x5f\x36\x32\x32\0\x4c\x42\x42\
+\x30\x5f\x35\x32\x32\0\x4c\x42\x42\x30\x5f\x34\x32\x32\0\x4c\x42\x42\x30\x5f\
+\x31\x33\x32\x32\0\x4c\x42\x42\x30\x5f\x31\x32\x32\x32\0\x4c\x42\x42\x30\x5f\
+\x31\x31\x32\x32\0\x4c\x42\x42\x30\x5f\x31\x30\x32\x32\0\x4c\x42\x42\x30\x5f\
+\x39\x31\x32\0\x4c\x42\x42\x30\x5f\x38\x31\x32\0\x4c\x42\x42\x30\x5f\x37\x31\
+\x32\0\x4c\x42\x42\x30\x5f\x36\x31\x32\0\x4c\x42\x42\x30\x5f\x35\x31\x32\0\x4c\
+\x42\x42\x30\x5f\x34\x31\x32\0\x4c\x42\x42\x30\x5f\x31\x33\x31\x32\0\x4c\x42\
+\x42\x30\x5f\x31\x32\x31\x32\0\x4c\x42\x42\x30\x5f\x31\x31\x31\x32\0\x4c\x42\
+\x42\x30\x5f\x31\x30\x31\x32\0\x4c\x42\x42\x30\x5f\x39\x30\x32\0\x4c\x42\x42\
+\x30\x5f\x38\x30\x32\0\x4c\x42\x42\x30\x5f\x37\x30\x32\0\x4c\x42\x42\x30\x5f\
+\x36\x30\x32\0\x4c\x42\x42\x30\x5f\x35\x30\x32\0\x4c\x42\x42\x30\x5f\x34\x30\
+\x32\0\x4c\x42\x42\x30\x5f\x31\x34\x30\x32\0\x4c\x42\x42\x30\x5f\x31\x33\x30\
+\x32\0\x4c\x42\x42\x30\x5f\x31\x32\x30\x32\0\x4c\x42\x42\x30\x5f\x31\x31\x30\
+\x32\0\x4c\x42\x42\x30\x5f\x31\x30\x30\x32\0\x72\x73\x73\x5f\x66\x6c\x6f\x77\
+\x5f\x61\x63\x74\x69\x6f\x6e\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x32\0\x4c\x42\
+\x42\x30\x5f\x39\x31\0\x4c\x42\x42\x30\x5f\x32\x39\x31\0\x4c\x42\x42\x30\x5f\
+\x31\x39\x31\0\x4c\x42\x42\x30\x5f\x38\x31\0\x4c\x42\x42\x30\x5f\x32\x38\x31\0\
+\x4c\x42\x42\x30\x5f\x31\x38\x31\0\x4c\x42\x42\x30\x5f\x37\x31\0\x4c\x42\x42\
+\x30\x5f\x32\x37\x31\0\x4c\x42\x42\x30\x5f\x31\x37\x31\0\x4c\x42\x42\x30\x5f\
+\x36\x31\0\x4c\x42\x42\x30\x5f\x32\x36\x31\0\x4c\x42\x42\x30\x5f\x31\x36\x31\0\
+\x4c\x42\x42\x30\x5f\x35\x31\0\x4c\x42\x42\x30\x5f\x38\x35\x31\0\x4c\x42\x42\
+\x30\x5f\x32\x35\x31\0\x4c\x42\x42\x30\x5f\x31\x35\x31\0\x4c\x42\x42\x30\x5f\
+\x34\x31\0\x4c\x42\x42\x30\x5f\x32\x34\x31\0\x4c\x42\x42\x30\x5f\x31\x34\x31\0\
+\x4c\x42\x42\x30\x5f\x33\x31\0\x4c\x42\x42\x30\x5f\x38\x33\x31\0\x4c\x42\x42\
+\x30\x5f\x32\x33\x31\0\x4c\x42\x42\x30\x5f\x31\x33\x31\0\x4c\x42\x42\x30\x5f\
+\x32\x31\0\x4c\x42\x42\x30\x5f\x33\x32\x31\0\x4c\x42\x42\x30\x5f\x32\x32\x31\0\
+\x4c\x42\x42\x30\x5f\x31\x32\x31\0\x4c\x42\x42\x30\x5f\x31\x31\0\x4c\x42\x42\
+\x30\x5f\x31\x34\x31\x31\0\x4c\x42\x42\x30\x5f\x33\x31\x31\0\x4c\x42\x42\x30\
+\x5f\x32\x31\x31\0\x4c\x42\x42\x30\x5f\x31\x31\x31\0\x4c\x42\x42\x30\x5f\x33\
+\x30\x31\0\x4c\x42\x42\x30\x5f\x32\x30\x31\0\x4c\x42\x42\x30\x5f\x31\x30\x31\0\
+\x72\x73\x73\x5f\x66\x6c\x6f\x77\x5f\x61\x63\x74\x69\x6f\x6e\x2e\x5f\x5f\x5f\
+\x5f\x66\x6d\x74\x2e\x31\0\x2e\x72\x6f\x64\x61\x74\x61\x2e\x73\x74\x72\x31\x2e\
+\x31\0\x4c\x42\x42\x30\x5f\x39\x39\x30\0\x4c\x42\x42\x30\x5f\x38\x39\x30\0\x4c\
+\x42\x42\x30\x5f\x37\x39\x30\0\x4c\x42\x42\x30\x5f\x36\x39\x30\0\x4c\x42\x42\
+\x30\x5f\x35\x39\x30\0\x4c\x42\x42\x30\x5f\x34\x39\x30\0\x4c\x42\x42\x30\x5f\
+\x33\x39\x30\0\x4c\x42\x42\x30\x5f\x31\x33\x39\x30\0\x4c\x42\x42\x30\x5f\x31\
+\x32\x39\x30\0\x4c\x42\x42\x30\x5f\x31\x31\x39\x30\0\x4c\x42\x42\x30\x5f\x31\
+\x30\x39\x30\0\x4c\x42\x42\x30\x5f\x39\x38\x30\0\x4c\x42\x42\x30\x5f\x38\x38\
+\x30\0\x4c\x42\x42\x30\x5f\x37\x38\x30\0\x4c\x42\x42\x30\x5f\x36\x38\x30\0\x4c\
+\x42\x42\x30\x5f\x35\x38\x30\0\x4c\x42\x42\x30\x5f\x34\x38\x30\0\x4c\x42\x42\
+\x30\x5f\x33\x38\x30\0\x4c\x42\x42\x30\x5f\x31\x33\x38\x30\0\x4c\x42\x42\x30\
+\x5f\x31\x32\x38\x30\0\x4c\x42\x42\x30\x5f\x31\x31\x38\x30\0\x4c\x42\x42\x30\
+\x5f\x31\x30\x38\x30\0\x4c\x42\x42\x30\x5f\x39\x37\x30\0\x4c\x42\x42\x30\x5f\
+\x38\x37\x30\0\x4c\x42\x42\x30\x5f\x37\x37\x30\0\x4c\x42\x42\x30\x5f\x36\x37\
+\x30\0\x4c\x42\x42\x30\x5f\x35\x37\x30\0\x4c\x42\x42\x30\x5f\x34\x37\x30\0\x4c\
+\x42\x42\x30\x5f\x33\x37\x30\0\x4c\x42\x42\x30\x5f\x31\x33\x37\x30\0\x4c\x42\
+\x42\x30\x5f\x31\x32\x37\x30\0\x4c\x42\x42\x30\x5f\x31\x31\x37\x30\0\x4c\x42\
+\x42\x30\x5f\x31\x30\x37\x30\0\x4c\x42\x42\x30\x5f\x39\x36\x30\0\x4c\x42\x42\
+\x30\x5f\x38\x36\x30\0\x4c\x42\x42\x30\x5f\x37\x36\x30\0\x4c\x42\x42\x30\x5f\
+\x36\x36\x30\0\x4c\x42\x42\x30\x5f\x35\x36\x30\0\x4c\x42\x42\x30\x5f\x34\x36\
+\x30\0\x4c\x42\x42\x30\x5f\x33\x36\x30\0\x4c\x42\x42\x30\x5f\x31\x33\x36\x30\0\
+\x4c\x42\x42\x30\x5f\x31\x32\x36\x30\0\x4c\x42\x42\x30\x5f\x31\x31\x36\x30\0\
+\x4c\x42\x42\x30\x5f\x31\x30\x36\x30\0\x4c\x42\x42\x30\x5f\x39\x35\x30\0\x4c\
+\x42\x42\x30\x5f\x37\x35\x30\0\x4c\x42\x42\x30\x5f\x36\x35\x30\0\x4c\x42\x42\
+\x30\x5f\x35\x35\x30\0\x4c\x42\x42\x30\x5f\x34\x35\x30\0\x4c\x42\x42\x30\x5f\
+\x33\x35\x30\0\x4c\x42\x42\x30\x5f\x31\x33\x35\x30\0\x4c\x42\x42\x30\x5f\x31\
+\x32\x35\x30\0\x4c\x42\x42\x30\x5f\x31\x31\x35\x30\0\x4c\x42\x42\x30\x5f\x31\
+\x30\x35\x30\0\x4c\x42\x42\x30\x5f\x39\x34\x30\0\x4c\x42\x42\x30\x5f\x37\x34\
+\x30\0\x4c\x42\x42\x30\x5f\x36\x34\x30\0\x4c\x42\x42\x30\x5f\x35\x34\x30\0\x4c\
+\x42\x42\x30\x5f\x34\x34\x30\0\x4c\x42\x42\x30\x5f\x33\x34\x30\0\x4c\x42\x42\
+\x30\x5f\x31\x33\x34\x30\0\x4c\x42\x42\x30\x5f\x31\x32\x34\x30\0\x4c\x42\x42\
+\x30\x5f\x31\x31\x34\x30\0\x4c\x42\x42\x30\x5f\x31\x30\x34\x30\0\x4c\x42\x42\
+\x30\x5f\x39\x33\x30\0\x4c\x42\x42\x30\x5f\x37\x33\x30\0\x4c\x42\x42\x30\x5f\
+\x36\x33\x30\0\x4c\x42\x42\x30\x5f\x35\x33\x30\0\x4c\x42\x42\x30\x5f\x34\x33\
+\x30\0\x4c\x42\x42\x30\x5f\x33\x33\x30\0\x4c\x42\x42\x30\x5f\x31\x33\x33\x30\0\
+\x4c\x42\x42\x30\x5f\x31\x32\x33\x30\0\x4c\x42\x42\x30\x5f\x31\x31\x33\x30\0\
+\x4c\x42\x42\x30\x5f\x31\x30\x33\x30\0\x4c\x42\x42\x30\x5f\x39\x32\x30\0\x4c\
+\x42\x42\x30\x5f\x38\x32\x30\0\x4c\x42\x42\x30\x5f\x37\x32\x30\0\x4c\x42\x42\
+\x30\x5f\x36\x32\x30\0\x4c\x42\x42\x30\x5f\x35\x32\x30\0\x4c\x42\x42\x30\x5f\
+\x34\x32\x30\0\x4c\x42\x42\x30\x5f\x31\x33\x32\x30\0\x4c\x42\x42\x30\x5f\x31\
+\x32\x32\x30\0\x4c\x42\x42\x30\x5f\x31\x31\x32\x30\0\x4c\x42\x42\x30\x5f\x31\
+\x30\x32\x30\0\x4c\x42\x42\x30\x5f\x39\x31\x30\0\x4c\x42\x42\x30\x5f\x38\x31\
+\x30\0\x4c\x42\x42\x30\x5f\x37\x31\x30\0\x4c\x42\x42\x30\x5f\x36\x31\x30\0\x4c\
+\x42\x42\x30\x5f\x35\x31\x30\0\x4c\x42\x42\x30\x5f\x34\x31\x30\0\x4c\x42\x42\
+\x30\x5f\x31\x33\x31\x30\0\x4c\x42\x42\x30\x5f\x31\x32\x31\x30\0\x4c\x42\x42\
+\x30\x5f\x31\x31\x31\x30\0\x4c\x42\x42\x30\x5f\x31\x30\x31\x30\0\x4c\x42\x42\
+\x30\x5f\x39\x30\x30\0\x4c\x42\x42\x30\x5f\x38\x30\x30\0\x4c\x42\x42\x30\x5f\
+\x37\x30\x30\0\x4c\x42\x42\x30\x5f\x36\x30\x30\0\x4c\x42\x42\x30\x5f\x35\x30\
+\x30\0\x4c\x42\x42\x30\x5f\x34\x30\x30\0\x4c\x42\x42\x30\x5f\x31\x34\x30\x30\0\
+\x4c\x42\x42\x30\x5f\x31\x33\x30\x30\0\x4c\x42\x42\x30\x5f\x31\x32\x30\x30\0\
+\x4c\x42\x42\x30\x5f\x31\x31\x30\x30\0\x4c\x42\x42\x30\x5f\x31\x30\x30\x30\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1b\x01\0\0\x03\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\x92\x76\x04\0\0\0\0\0\xad\x1a\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0f\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x75\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x40\0\0\0\0\0\0\0\xc8\xf6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\x71\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x98\x37\x03\0\
+\0\0\0\0\x50\0\0\0\0\0\0\0\x1d\0\0\0\x03\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\
+\0\0\xc4\x16\0\0\x01\0\0\0\x32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\xf7\0\0\0\0\0\
+\0\x1c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\x80\0\
+\0\0\x01\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x28\xf7\0\0\0\0\0\0\x20\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2b\x01\0\0\x01\0\0\
+\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x48\xf7\0\0\0\0\0\0\x2e\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe8\0\0\0\x01\0\0\0\x03\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x76\xf7\0\0\0\0\0\0\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4a\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\x83\xf7\0\0\0\0\0\0\x35\x4f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb8\
+\x46\x01\0\0\0\0\0\xb1\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\xbd\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x69\x49\x01\0\0\
+\0\0\0\x7e\x0b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\xb9\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe8\x37\x03\0\0\0\0\0\
+\x60\0\0\0\0\0\0\0\x1d\0\0\0\x0b\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x3a\
+\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe7\x54\x01\0\0\0\0\0\xcd\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5e\0\0\0\x01\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb4\x55\x01\0\0\0\0\0\x10\x03\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5a\0\0\0\x09\0\0\0\x40\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\x48\x38\x03\0\0\0\0\0\x20\x0c\0\0\0\0\0\0\x1d\0\0\0\
+\x0e\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x86\0\0\0\x01\0\0\0\x30\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\xc4\x58\x01\0\0\0\0\0\xee\x07\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\x01\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\xa5\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\xb2\x60\x01\0\0\0\0\0\x60\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\xa1\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x68\x44\x03\0\0\0\0\0\xb0\0\0\0\0\0\0\0\x1d\0\0\0\x11\0\0\0\x08\0\0\0\0\0\0\0\
+\x10\0\0\0\0\0\0\0\x37\x01\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x14\
+\x61\x01\0\0\0\0\0\xbe\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\x33\x01\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x45\x03\
+\0\0\0\0\0\x50\0\0\0\0\0\0\0\x1d\0\0\0\x13\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\
+\0\0\0\x19\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd4\x6f\x01\0\0\0\0\
+\0\x30\x30\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x15\
+\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x68\x45\x03\0\0\0\0\0\0\x30\
+\x01\0\0\0\0\0\x1d\0\0\0\x15\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x04\x01\
+\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\xa0\x02\0\0\0\0\0\x28\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\x09\0\0\0\
+\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x68\x75\x04\0\0\0\0\0\x20\0\0\0\0\0\0\0\x1d\
+\0\0\0\x17\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\xf4\0\0\0\x01\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\0\0\x30\xa0\x02\0\0\0\0\0\x46\x53\0\0\0\0\0\0\0\0\0\0\0\
+\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf0\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\0\0\x88\x75\x04\0\0\0\0\0\0\x01\0\0\0\0\0\0\x1d\0\0\0\x19\0\0\0\
+\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x91\0\0\0\x01\0\0\0\x30\0\0\0\0\0\0\0\0\0\
+\0\0\0\0\0\0\x76\xf3\x02\0\0\0\0\0\xcc\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\
+\0\0\0\0\x01\0\0\0\0\0\0\0\xd9\0\0\0\x03\x4c\xff\x6f\0\0\0\x80\0\0\0\0\0\0\0\0\
+\0\0\0\0\x88\x76\x04\0\0\0\0\0\x0a\0\0\0\0\0\0\0\x1d\0\0\0\0\0\0\0\x01\0\0\0\0\
+\0\0\0\0\0\0\0\0\0\0\0\x23\x01\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
+\x48\xf4\x02\0\0\0\0\0\x50\x43\0\0\0\0\0\0\x01\0\0\0\xcb\x02\0\0\x08\0\0\0\0\0\
+\0\0\x18\0\0\0\0\0\0\0";
+}
+
+#ifdef __cplusplus
+struct tap_rss *tap_rss::open(const struct bpf_object_open_opts *opts) { return tap_rss__open_opts(opts); }
+struct tap_rss *tap_rss::open_and_load() { return tap_rss__open_and_load(); }
+int tap_rss::load(struct tap_rss *skel) { return tap_rss__load(skel); }
+int tap_rss::attach(struct tap_rss *skel) { return tap_rss__attach(skel); }
+void tap_rss::detach(struct tap_rss *skel) { tap_rss__detach(skel); }
+void tap_rss::destroy(struct tap_rss *skel) { tap_rss__destroy(skel); }
+const void *tap_rss::elf_bytes(size_t *sz) { return tap_rss__elf_bytes(sz); }
+#endif /* __cplusplus */
+
+__attribute__((unused)) static void
+tap_rss__assert(struct tap_rss *s __attribute__((unused)))
+{
+#ifdef __cplusplus
+#define _Static_assert static_assert
+#endif
+#ifdef __cplusplus
+#undef _Static_assert
+#endif
+}
+
+#endif /* __TAP_RSS_SKEL_H__ */
diff --git a/drivers/net/tap/tap_rss.stub.h b/drivers/net/tap/tap_rss.stub.h
new file mode 100644
index 000000000000..10a1692e1e15
--- /dev/null
+++ b/drivers/net/tap/tap_rss.stub.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Stub if libbpf is not available
+ */
+
+struct bpf_object;
+struct bpf_map;
+
+struct tap_rss {
+	struct bpf_object *obj;
+	struct {
+		struct bpf_map *rss_map;
+	} maps;
+};
+
+static struct tap_rss *tap_rss__open_and_load(void)
+{
+	errno = ENOTSUP;
+	return NULL;
+}
+
+static void tap_rss__destroy(struct tap_rss *obj)
+{
+}
+
+static int tap_rss__attach(struct tap_rss *obj)
+{
+	return -1;
+}
+
+static int bpf_object__btf_fd(struct bpf_object *obj)
+{
+	return -1;
+}
+
+static int bpf_map__update_elem(const struct bpf_map *map, const void *key, size_t key_size,
+				const void *value, size_t value_size, int flags)
+{
+	return -1;
+}
+
+static int bpf_map__delete_elem(const struct bpf_map *map,
+				const void *key, size_t key_size, int flags)
+{
+	return -1;
+}
-- 
2.43.0


^ permalink raw reply	[relevance 1%]

* [PATCH v7 2/5] ethdev: fix skip valid port in probing callback
  2024-01-30  6:36  3% ` [PATCH v7 " Huisong Li
@ 2024-01-30  6:36  2%   ` Huisong Li
  0 siblings, 0 replies; 200+ results
From: Huisong Li @ 2024-01-30  6:36 UTC (permalink / raw)
  To: dev, Ajit Khaparde, Somnath Kotur, Dariusz Sosnowski,
	Viacheslav Ovsiienko, Ori Kam, Suanming Mou, Matan Azrad,
	Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko,
	Stephen Hemminger
  Cc: fengchengwen, liudongdong3, liuyonglong, lihuisong

The event callback in application may use the macro RTE_ETH_FOREACH_DEV to
iterate over all enabled ports to do something(like, verifying the port id
validity) when receive a probing event. If the ethdev state of a port is
not RTE_ETH_DEV_UNUSED, this port will be considered as a valid port.

However, this state is set to RTE_ETH_DEV_ATTACHED after pushing probing
event. It means that probing callback will skip this port. But this
assignment can not move to front of probing notification. See
commit be8cd210379a ("ethdev: fix port probing notification")

So this patch has to add a new state, RTE_ETH_DEV_ALLOCATED. Set the ethdev
state to RTE_ETH_DEV_ALLOCATED before pushing probing event and set it to
RTE_ETH_DEV_ATTACHED after definitely probed. And this port is valid if its
device state is 'ALLOCATED' or 'ATTACHED'.

In addition, the new state has to be placed behind 'REMOVED' to avoid ABI
break. Fortunately, this ethdev state is internal and applications can not
access it directly. So this patch encapsulates an API, rte_eth_dev_is_used,
for ethdev or PMD to call and eliminate concerns about using this state
enum value comparison.

Fixes: be8cd210379a ("ethdev: fix port probing notification")
Cc: stable@dpdk.org

Signed-off-by: Huisong Li <lihuisong@huawei.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/bnxt/bnxt_ethdev.c |  3 ++-
 drivers/net/mlx5/mlx5.c        |  2 +-
 lib/ethdev/ethdev_driver.c     | 13 ++++++++++---
 lib/ethdev/ethdev_driver.h     | 12 ++++++++++++
 lib/ethdev/ethdev_pci.h        |  2 +-
 lib/ethdev/rte_class_eth.c     |  2 +-
 lib/ethdev/rte_ethdev.c        |  4 ++--
 lib/ethdev/rte_ethdev.h        |  4 +++-
 lib/ethdev/version.map         |  1 +
 9 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index acf7e6e46e..cb4c4cfb0e 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -6109,7 +6109,8 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev)
 
 	PMD_DRV_LOG(DEBUG, "Calling Device uninit\n");
 
-	if (eth_dev->state != RTE_ETH_DEV_UNUSED)
+
+	if (rte_eth_dev_is_used(eth_dev->state))
 		bnxt_dev_close_op(eth_dev);
 
 	return 0;
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 3a182de248..1f1d9b7d96 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -3258,7 +3258,7 @@ mlx5_eth_find_next(uint16_t port_id, struct rte_device *odev)
 	while (port_id < RTE_MAX_ETHPORTS) {
 		struct rte_eth_dev *dev = &rte_eth_devices[port_id];
 
-		if (dev->state != RTE_ETH_DEV_UNUSED &&
+		if (rte_eth_dev_is_used(dev->state) &&
 		    dev->device &&
 		    (dev->device == odev ||
 		     (dev->device->driver &&
diff --git a/lib/ethdev/ethdev_driver.c b/lib/ethdev/ethdev_driver.c
index bd917a15fc..2b4a6e2b2c 100644
--- a/lib/ethdev/ethdev_driver.c
+++ b/lib/ethdev/ethdev_driver.c
@@ -52,8 +52,8 @@ eth_dev_find_free_port(void)
 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
 		/* Using shared name field to find a free port. */
 		if (eth_dev_shared_data->data[i].name[0] == '\0') {
-			RTE_ASSERT(rte_eth_devices[i].state ==
-				   RTE_ETH_DEV_UNUSED);
+			RTE_ASSERT(!rte_eth_dev_is_used(
+					rte_eth_devices[i].state));
 			return i;
 		}
 	}
@@ -217,11 +217,18 @@ rte_eth_dev_probing_finish(struct rte_eth_dev *dev)
 	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
 		eth_dev_fp_ops_setup(rte_eth_fp_ops + dev->data->port_id, dev);
 
+	dev->state = RTE_ETH_DEV_ALLOCATED;
 	rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_NEW, NULL);
 
 	dev->state = RTE_ETH_DEV_ATTACHED;
 }
 
+bool rte_eth_dev_is_used(uint16_t dev_state)
+{
+	return dev_state == RTE_ETH_DEV_ALLOCATED ||
+		dev_state == RTE_ETH_DEV_ATTACHED;
+}
+
 int
 rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
 {
@@ -239,7 +246,7 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
 	if (ret != 0)
 		return ret;
 
-	if (eth_dev->state != RTE_ETH_DEV_UNUSED)
+	if (rte_eth_dev_is_used(eth_dev->state))
 		rte_eth_dev_callback_process(eth_dev,
 				RTE_ETH_EVENT_DESTROY, NULL);
 
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index f05f68a67c..238bd72ab0 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -1596,6 +1596,18 @@ int rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 __rte_internal
 void rte_eth_dev_probing_finish(struct rte_eth_dev *dev);
 
+/**
+ * Check if a Ethernet device state is used or not
+ *
+ * @param dev_state
+ *   The state of the Ethernet device
+ * @return
+ *   - true if the state of the Ethernet device is allocated or attached
+ *   - false if this state is neither allocated nor attached
+ */
+__rte_internal
+bool rte_eth_dev_is_used(uint16_t dev_state);
+
 /**
  * Create memzone for HW rings.
  * malloc can't be used as the physical address is needed.
diff --git a/lib/ethdev/ethdev_pci.h b/lib/ethdev/ethdev_pci.h
index 737fff1833..c07a98e04f 100644
--- a/lib/ethdev/ethdev_pci.h
+++ b/lib/ethdev/ethdev_pci.h
@@ -165,7 +165,7 @@ rte_eth_dev_pci_generic_remove(struct rte_pci_device *pci_dev,
 	 * eth device has been released.
 	 */
 	if (rte_eal_process_type() == RTE_PROC_SECONDARY &&
-	    eth_dev->state == RTE_ETH_DEV_UNUSED)
+	    !rte_eth_dev_is_used(eth_dev->state))
 		return 0;
 
 	if (dev_uninit) {
diff --git a/lib/ethdev/rte_class_eth.c b/lib/ethdev/rte_class_eth.c
index bc003db8af..31cabee525 100644
--- a/lib/ethdev/rte_class_eth.c
+++ b/lib/ethdev/rte_class_eth.c
@@ -118,7 +118,7 @@ eth_dev_match(const struct rte_eth_dev *edev,
 	const struct rte_kvargs *kvlist = arg->kvlist;
 	unsigned int pair;
 
-	if (edev->state == RTE_ETH_DEV_UNUSED)
+	if (!rte_eth_dev_is_used(edev->state))
 		return -1;
 	if (arg->device != NULL && arg->device != edev->device)
 		return -1;
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index f61dc7dd7b..b6b7a20e35 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -349,7 +349,7 @@ uint16_t
 rte_eth_find_next(uint16_t port_id)
 {
 	while (port_id < RTE_MAX_ETHPORTS &&
-			rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED)
+	       !rte_eth_dev_is_used(rte_eth_devices[port_id].state))
 		port_id++;
 
 	if (port_id >= RTE_MAX_ETHPORTS)
@@ -408,7 +408,7 @@ rte_eth_dev_is_valid_port(uint16_t port_id)
 	int is_valid;
 
 	if (port_id >= RTE_MAX_ETHPORTS ||
-	    (rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED))
+	    !rte_eth_dev_is_used(rte_eth_devices[port_id].state))
 		is_valid = 0;
 	else
 		is_valid = 1;
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 2687c23fa6..5079fea8a6 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -2068,10 +2068,12 @@ typedef uint16_t (*rte_tx_callback_fn)(uint16_t port_id, uint16_t queue,
 enum rte_eth_dev_state {
 	/** Device is unused before being probed. */
 	RTE_ETH_DEV_UNUSED = 0,
-	/** Device is attached when allocated in probing. */
+	/** Device is attached when definitely probed. */
 	RTE_ETH_DEV_ATTACHED,
 	/** Device is in removed state when plug-out is detected. */
 	RTE_ETH_DEV_REMOVED,
+	/** Device is allocated and is set before reporting new event. */
+	RTE_ETH_DEV_ALLOCATED,
 };
 
 struct rte_eth_dev_sriov {
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index a050baab0f..26867eb6e5 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -333,6 +333,7 @@ INTERNAL {
 	rte_eth_dev_get_by_name;
 	rte_eth_dev_is_rx_hairpin_queue;
 	rte_eth_dev_is_tx_hairpin_queue;
+	rte_eth_dev_is_used;
 	rte_eth_dev_probing_finish;
 	rte_eth_dev_release_port;
 	rte_eth_dev_internal_reset;
-- 
2.33.0


^ permalink raw reply	[relevance 2%]

* [PATCH v7 0/5] app/testpmd: support multiple process attach and detach port
       [not found]     <20220825024425.10534-1-lihuisong@huawei.com>
  @ 2024-01-30  6:36  3% ` Huisong Li
  2024-01-30  6:36  2%   ` [PATCH v7 2/5] ethdev: fix skip valid port in probing callback Huisong Li
  1 sibling, 1 reply; 200+ results
From: Huisong Li @ 2024-01-30  6:36 UTC (permalink / raw)
  To: dev
  Cc: thomas, ferruh.yigit, andrew.rybchenko, fengchengwen,
	liudongdong3, liuyonglong, lihuisong

This patchset fix some bugs and support attaching and detaching port
in primary and secondary.

---
 -v7: fix conflicts
 -v6: adjust rte_eth_dev_is_used position based on alphabetical order
      in version.map
 -v5: move 'ALLOCATED' state to the back of 'REMOVED' to avoid abi break.
 -v4: fix a misspelling. 
 -v3:
   #1 merge patch 1/6 and patch 2/6 into patch 1/5, and add modification
      for other bus type.
   #2 add a RTE_ETH_DEV_ALLOCATED state in rte_eth_dev_state to resolve
      the probelm in patch 2/5. 
 -v2: resend due to CI unexplained failure.

Huisong Li (5):
  drivers/bus: restore driver assignment at front of probing
  ethdev: fix skip valid port in probing callback
  app/testpmd: check the validity of the port
  app/testpmd: add attach and detach port for multiple process
  app/testpmd: stop forwarding in new or destroy event

 app/test-pmd/testpmd.c                   | 47 +++++++++++++++---------
 app/test-pmd/testpmd.h                   |  1 -
 drivers/bus/auxiliary/auxiliary_common.c |  9 ++++-
 drivers/bus/dpaa/dpaa_bus.c              |  9 ++++-
 drivers/bus/fslmc/fslmc_bus.c            |  8 +++-
 drivers/bus/ifpga/ifpga_bus.c            | 12 ++++--
 drivers/bus/pci/pci_common.c             |  9 ++++-
 drivers/bus/vdev/vdev.c                  | 10 ++++-
 drivers/bus/vmbus/vmbus_common.c         |  9 ++++-
 drivers/net/bnxt/bnxt_ethdev.c           |  3 +-
 drivers/net/bonding/bonding_testpmd.c    |  1 -
 drivers/net/mlx5/mlx5.c                  |  2 +-
 lib/ethdev/ethdev_driver.c               | 13 +++++--
 lib/ethdev/ethdev_driver.h               | 12 ++++++
 lib/ethdev/ethdev_pci.h                  |  2 +-
 lib/ethdev/rte_class_eth.c               |  2 +-
 lib/ethdev/rte_ethdev.c                  |  4 +-
 lib/ethdev/rte_ethdev.h                  |  4 +-
 lib/ethdev/version.map                   |  1 +
 19 files changed, 114 insertions(+), 44 deletions(-)

-- 
2.33.0


^ permalink raw reply	[relevance 3%]

* Re: [RFC] ethdev: fast path async flow API
  2024-01-29 13:38  0%         ` Dariusz Sosnowski
@ 2024-01-29 17:36  0%           ` Ferruh Yigit
  2024-01-30 12:06  0%             ` Dariusz Sosnowski
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2024-01-29 17:36 UTC (permalink / raw)
  To: Dariusz Sosnowski, Stephen Hemminger
  Cc: NBU-Contact-Thomas Monjalon (EXTERNAL), Andrew Rybchenko, Ori Kam, dev

On 1/29/2024 1:38 PM, Dariusz Sosnowski wrote:
> Hi all,
> 
>> -----Original Message-----
>> From: Dariusz Sosnowski <dsosnowski@nvidia.com>
>> Sent: Tuesday, January 23, 2024 12:37
>> To: Stephen Hemminger <stephen@networkplumber.org>
>> Cc: NBU-Contact-Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>;
>> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
>> <andrew.rybchenko@oktetlabs.ru>; Ori Kam <orika@nvidia.com>;
>> dev@dpdk.org
>> Subject: RE: [RFC] ethdev: fast path async flow API
>>
>> Hi Stephen,
>>
>> Sorry for such a late response.
>>
>> From: Stephen Hemminger <stephen@networkplumber.org>
>> Sent: Thursday, January 4, 2024 02:08
>>> On Wed, 3 Jan 2024 19:14:49 +0000
>>> Dariusz Sosnowski <dsosnowski@nvidia.com> wrote:
>>>> In summary, in my opinion extending the async flow API with bulking
>>> capabilities or exposing the queue directly to the application is not desirable.
>>>> This proposal aims to reduce the I-cache overhead in async flow API
>>>> by
>>> reusing the existing design pattern in DPDK - fast path functions are
>>> inlined to the application code and they call cached PMD callbacks.
>>>
>>> Inline needs to more discouraged in DPDK, because it only works if
>>> application ends up building with DPDK from source.
>>> It doesn't work for the Linux distro packaging model and symbol
>>> versioning, etc.
>>
>> I understand the problem. In that case, I have a proposal.
>> I had a chat with Thomas regarding this RFC, and he noticed that there are 2
>> separate changes proposed here:
>>
>> 1. Per-port callbacks for async flow API.
>>     - Moves specified callbacks to rte_flow_fp_ops struct and allow PMDs to
>> register them dynamically.
>>     - Removes indirection at API level - no need to call rte_flow_ops_get().
>>     - Removes checking if callbacks are defined - either the default DPDK callback
>> is used or the one provided by PMD.
>> 2. Make async flow API functions inlineable.
>>
>> Change (1) won't break ABI (existing callbacks in rte_flow_ops can be marked
>> as deprecated for now and phased out later) and in my opinion is less
>> controversial compared to change (2).
>>
>> I'll rerun the benchmarks for both changes separately to compare their
>> benefits in isolation.
>> This would allow us to decide if change (2) is worth the drawbacks it
>> introduces.
>>
>> What do you think?
> 
> I split the RFC into 2 parts:
> 
> 1. Introduce per-port callbacks:
>     - Introduce rte_flow_fp_ops struct - holds callbacks for fast path calls, for each port. PMD registers callbacks through rte_flow_fp_ops_register().
>     - Relevant rte_flow_async_* functions just pass arguments to fast path callbacks. Validation checks are done only if RTE_FLOW_DEBUG macro is defined.
>     - Biggest difference is the removal of callback access through rte_flow_get_ops().
> 2. Inline async flow API functions.
>     - Relevant rte_flow_async_* functions definitions are moved to rte_flow.h and made inlineable.
> 
> Here are the results of the benchmark:
> 
> |                       | Avg Insertion | Diff over baseline | Avg Deletion | Diff over baseline |
> |-----------------------|---------------|--------------------|--------------|--------------------|
> | baseline (v24.03-rc0) |     5855.4    |                    |    9026.8    |                    |
> | applied (1)           |     6384.2    |    +528.8 (+9%)    |    10054.2   |  +1027.4 (+11.4%)  |
> | applied (2)           |     6434.6    |   +579.2 (+9.9%)   |    10011.4   |   +984.6 (+10.9%)  |
> 
> Results are in KFlows/sec.
> The benchmark is continuously inserting and deleting 2M flow rules.
> These rules match on IPv4 destination address and with a single action DROP.
> Flow rules are inserted and deleted using a single flow queue.
> 
> Change (2) improves insertion rate performance by ~1% compared to (1), but decreases deletion rate by ~0.5%.
> Based on these results, I think we can say that making rte_flow_async_*() calls inlineable may not be worth it compared to the issues it causes.
> 
> What do you all think about the results?
> 

Hi Dariusz,

As discussed before, converting APIs to static inline functions or
exposing 'rte_eth_dev' has cons but with only applying first part above
seems get rid of them with reasonable performance gain, so I think we
can continue with this approach and continue to reviews.

Most of the 'rte_flow_async_*' are already missing the function validity
check, so having a default (dummy?) rte_flow_fp_ops for them seems even
an improvement there.


Only previously 'struct rte_flow_ops' was coming from drivers, ethdev
layer doesn't need to maintain anything.
But with 'rte_flow_fp_ops' struct, ethdev needs to store another array
with fixed ('RTE_MAX_ETHPORTS') size which will be another blocker in
the future to convert this fixed arrays to dynamically allocated arrays.

For this, does it still help we add an a new field to "struct
rte_eth_dev", like "struct rte_flow_ops *flow_ops", similar to 'dev_ops'?
The indirection still will be there, but eliminate 'rte_flow_get_ops()'
call and checks comes with it.
If makes sense, is there a chance to experiment this and get some
performance numbers with it?


^ permalink raw reply	[relevance 0%]

* Re: [PATCH v3 3/3] dts: add API doc generation
  2024-01-22 16:35  2%   ` [PATCH v3 3/3] dts: add API doc generation Juraj Linkeš
@ 2024-01-29 17:09  0%     ` Jeremy Spewock
       [not found]         ` <CAJvnSUCNjo0p-yhROF1MNLKhjiAw2QTyTHO2hpOaVVUn0xnJ0A@mail.gmail.com>
  1 sibling, 0 replies; 200+ results
From: Jeremy Spewock @ 2024-01-29 17:09 UTC (permalink / raw)
  To: Juraj Linkeš
  Cc: thomas, Honnappa.Nagarahalli, bruce.richardson, probb,
	paul.szczepanek, yoan.picchi, Luca.Vizzarro, dev

On Mon, Jan 22, 2024 at 11:35 AM Juraj Linkeš
<juraj.linkes@pantheon.tech> wrote:
>
> The tool used to generate developer docs is Sphinx, which is already in
> use in DPDK. The same configuration is used to preserve style, but it's
> been augmented with doc-generating configuration. There's a change that
> modifies how the sidebar displays the content hierarchy that's been put
> into an if block to not interfere with regular docs.
>
> Sphinx generates the documentation from Python docstrings. The docstring
> format is the Google format [0] which requires the sphinx.ext.napoleon
> extension. The other extension, sphinx.ext.intersphinx, enables linking
> to object in external documentations, such as the Python documentation.
>
> There are two requirements for building DTS docs:
> * The same Python version as DTS or higher, because Sphinx imports the
>   code.
> * Also the same Python packages as DTS, for the same reason.
>
> [0] https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings
>
> Signed-off-by: Juraj Linkeš <juraj.linkes@pantheon.tech>
> ---
>  buildtools/call-sphinx-build.py | 33 +++++++++++++++++++---------
>  doc/api/doxy-api-index.md       |  3 +++
>  doc/api/doxy-api.conf.in        |  2 ++
>  doc/api/meson.build             | 11 +++++++---
>  doc/guides/conf.py              | 39 ++++++++++++++++++++++++++++-----
>  doc/guides/meson.build          |  1 +
>  doc/guides/tools/dts.rst        | 34 +++++++++++++++++++++++++++-
>  dts/doc/meson.build             | 27 +++++++++++++++++++++++
>  dts/meson.build                 | 16 ++++++++++++++
>  meson.build                     |  1 +
>  10 files changed, 148 insertions(+), 19 deletions(-)
>  create mode 100644 dts/doc/meson.build
>  create mode 100644 dts/meson.build
>
> diff --git a/buildtools/call-sphinx-build.py b/buildtools/call-sphinx-build.py
> index 39a60d09fa..aea771a64e 100755
> --- a/buildtools/call-sphinx-build.py
> +++ b/buildtools/call-sphinx-build.py
> @@ -3,37 +3,50 @@
>  # Copyright(c) 2019 Intel Corporation
>  #
>
> +import argparse
>  import sys
>  import os
>  from os.path import join
>  from subprocess import run, PIPE, STDOUT
>  from packaging.version import Version
>
> -# assign parameters to variables
> -(sphinx, version, src, dst, *extra_args) = sys.argv[1:]
> +parser = argparse.ArgumentParser()
> +parser.add_argument('sphinx')
> +parser.add_argument('version')
> +parser.add_argument('src')
> +parser.add_argument('dst')
> +parser.add_argument('--dts-root', default=None)
> +args, extra_args = parser.parse_known_args()
>
>  # set the version in environment for sphinx to pick up
> -os.environ['DPDK_VERSION'] = version
> +os.environ['DPDK_VERSION'] = args.version
> +if args.dts_root:
> +    os.environ['DTS_ROOT'] = args.dts_root
>
>  # for sphinx version >= 1.7 add parallelism using "-j auto"
> -ver = run([sphinx, '--version'], stdout=PIPE,
> +ver = run([args.sphinx, '--version'], stdout=PIPE,
>            stderr=STDOUT).stdout.decode().split()[-1]
> -sphinx_cmd = [sphinx] + extra_args
> +sphinx_cmd = [args.sphinx] + extra_args
>  if Version(ver) >= Version('1.7'):
>      sphinx_cmd += ['-j', 'auto']
>
>  # find all the files sphinx will process so we can write them as dependencies
>  srcfiles = []
> -for root, dirs, files in os.walk(src):
> +for root, dirs, files in os.walk(args.src):
>      srcfiles.extend([join(root, f) for f in files])
>
> +if not os.path.exists(args.dst):
> +    os.makedirs(args.dst)
> +
>  # run sphinx, putting the html output in a "html" directory
> -with open(join(dst, 'sphinx_html.out'), 'w') as out:
> -    process = run(sphinx_cmd + ['-b', 'html', src, join(dst, 'html')],
> -                  stdout=out)
> +with open(join(args.dst, 'sphinx_html.out'), 'w') as out:
> +    process = run(
> +        sphinx_cmd + ['-b', 'html', args.src, join(args.dst, 'html')],
> +        stdout=out
> +    )
>
>  # create a gcc format .d file giving all the dependencies of this doc build
> -with open(join(dst, '.html.d'), 'w') as d:
> +with open(join(args.dst, '.html.d'), 'w') as d:
>      d.write('html: ' + ' '.join(srcfiles) + '\n')
>
>  sys.exit(process.returncode)
> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> index a6a768bd7c..b49b24acce 100644
> --- a/doc/api/doxy-api-index.md
> +++ b/doc/api/doxy-api-index.md
> @@ -241,3 +241,6 @@ The public API headers are grouped by topics:
>    [experimental APIs](@ref rte_compat.h),
>    [ABI versioning](@ref rte_function_versioning.h),
>    [version](@ref rte_version.h)
> +
> +- **tests**:
> +  [**DTS**](@dts_api_main_page)
> diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in
> index e94c9e4e46..d53edeba57 100644
> --- a/doc/api/doxy-api.conf.in
> +++ b/doc/api/doxy-api.conf.in
> @@ -121,6 +121,8 @@ SEARCHENGINE            = YES
>  SORT_MEMBER_DOCS        = NO
>  SOURCE_BROWSER          = YES
>
> +ALIASES                 = "dts_api_main_page=@DTS_API_MAIN_PAGE@"
> +
>  EXAMPLE_PATH            = @TOPDIR@/examples
>  EXAMPLE_PATTERNS        = *.c
>  EXAMPLE_RECURSIVE       = YES
> diff --git a/doc/api/meson.build b/doc/api/meson.build
> index 5b50692df9..ffc75d7b5a 100644
> --- a/doc/api/meson.build
> +++ b/doc/api/meson.build
> @@ -1,6 +1,7 @@
>  # SPDX-License-Identifier: BSD-3-Clause
>  # Copyright(c) 2018 Luca Boccassi <bluca@debian.org>
>
> +doc_api_build_dir = meson.current_build_dir()
>  doxygen = find_program('doxygen', required: get_option('enable_docs'))
>
>  if not doxygen.found()
> @@ -32,14 +33,18 @@ example = custom_target('examples.dox',
>  # set up common Doxygen configuration
>  cdata = configuration_data()
>  cdata.set('VERSION', meson.project_version())
> -cdata.set('API_EXAMPLES', join_paths(dpdk_build_root, 'doc', 'api', 'examples.dox'))
> -cdata.set('OUTPUT', join_paths(dpdk_build_root, 'doc', 'api'))
> +cdata.set('API_EXAMPLES', join_paths(doc_api_build_dir, 'examples.dox'))
> +cdata.set('OUTPUT', doc_api_build_dir)
>  cdata.set('TOPDIR', dpdk_source_root)
> -cdata.set('STRIP_FROM_PATH', ' '.join([dpdk_source_root, join_paths(dpdk_build_root, 'doc', 'api')]))
> +cdata.set('STRIP_FROM_PATH', ' '.join([dpdk_source_root, doc_api_build_dir]))
>  cdata.set('WARN_AS_ERROR', 'NO')
>  if get_option('werror')
>      cdata.set('WARN_AS_ERROR', 'YES')
>  endif
> +# A local reference must be relative to the main index.html page
> +# The path below can't be taken from the DTS meson file as that would
> +# require recursive subdir traversal (doc, dts, then doc again)
> +cdata.set('DTS_API_MAIN_PAGE', join_paths('..', 'dts', 'html', 'index.html'))
>
>  # configure HTML Doxygen run
>  html_cdata = configuration_data()
> diff --git a/doc/guides/conf.py b/doc/guides/conf.py
> index 0f7ff5282d..b442a1f76c 100644
> --- a/doc/guides/conf.py
> +++ b/doc/guides/conf.py
> @@ -7,10 +7,9 @@
>  from sphinx import __version__ as sphinx_version
>  from os import listdir
>  from os import environ
> -from os.path import basename
> -from os.path import dirname
> +from os.path import basename, dirname
>  from os.path import join as path_join
> -from sys import argv, stderr
> +from sys import argv, stderr, path
>
>  import configparser
>
> @@ -24,6 +23,37 @@
>            file=stderr)
>      pass
>
> +# Napoleon enables the Google format of Python doscstrings, used in DTS
> +# Intersphinx allows linking to external projects, such as Python docs, also used in DTS
> +extensions = ['sphinx.ext.napoleon', 'sphinx.ext.intersphinx']
> +
> +# DTS Python docstring options
> +autodoc_default_options = {
> +    'members': True,
> +    'member-order': 'bysource',
> +    'show-inheritance': True,
> +}
> +autodoc_class_signature = 'separated'
> +autodoc_typehints = 'both'
> +autodoc_typehints_format = 'short'
> +autodoc_typehints_description_target = 'documented'
> +napoleon_numpy_docstring = False
> +napoleon_attr_annotations = True
> +napoleon_preprocess_types = True
> +add_module_names = False
> +toc_object_entries = True
> +toc_object_entries_show_parents = 'hide'
> +intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}
> +
> +dts_root = environ.get('DTS_ROOT')
> +if dts_root:
> +    path.append(dts_root)
> +    # DTS Sidebar config
> +    html_theme_options = {
> +        'collapse_navigation': False,
> +        'navigation_depth': -1,
> +    }
> +
>  stop_on_error = ('-W' in argv)
>
>  project = 'Data Plane Development Kit'
> @@ -35,8 +65,7 @@
>  html_show_copyright = False
>  highlight_language = 'none'
>
> -release = environ.setdefault('DPDK_VERSION', "None")
> -version = release
> +version = environ.setdefault('DPDK_VERSION', "None")
>
>  master_doc = 'index'
>
> diff --git a/doc/guides/meson.build b/doc/guides/meson.build
> index 51f81da2e3..8933d75f6b 100644
> --- a/doc/guides/meson.build
> +++ b/doc/guides/meson.build
> @@ -1,6 +1,7 @@
>  # SPDX-License-Identifier: BSD-3-Clause
>  # Copyright(c) 2018 Intel Corporation
>
> +doc_guides_source_dir = meson.current_source_dir()
>  sphinx = find_program('sphinx-build', required: get_option('enable_docs'))
>
>  if not sphinx.found()
> diff --git a/doc/guides/tools/dts.rst b/doc/guides/tools/dts.rst
> index 846696e14e..21d3d89fc2 100644
> --- a/doc/guides/tools/dts.rst
> +++ b/doc/guides/tools/dts.rst
> @@ -278,7 +278,12 @@ and try not to divert much from it.
>  The :ref:`DTS developer tools <dts_dev_tools>` will issue warnings
>  when some of the basics are not met.
>
> -The code must be properly documented with docstrings.
> +The API documentation, which is a helpful reference when developing, may be accessed
> +in the code directly or generated with the :ref:`API docs build steps <building_api_docs>`.
> +When adding new files or modifying the directory structure, the corresponding changes must
> +be made to DTS api doc sources in ``dts/doc``.
> +
> +Speaking of which, the code must be properly documented with docstrings.
>  The style must conform to the `Google style
>  <https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings>`_.
>  See an example of the style `here
> @@ -413,6 +418,33 @@ the DTS code check and format script.
>  Refer to the script for usage: ``devtools/dts-check-format.sh -h``.
>
>
> +.. _building_api_docs:
> +
> +Building DTS API docs
> +---------------------
> +
> +To build DTS API docs, install the dependencies with Poetry, then enter its shell:
> +
> +.. code-block:: console
> +
> +   poetry install --with docs
> +   poetry shell
> +

The only thing to note here is with newer versions of poetry this will
start to throw warnings because of the way we use poetry and don't
have a root package. It is just a warning message so it shouldn't
cause any real problems, but I believe the way we should be handling
it is passing --no-root into poetry install so that it knows not to
use the root package.

>
> +The documentation is built using the standard DPDK build system. After executing the meson command
> +and entering Poetry's shell, build the documentation with:
> +
> +.. code-block:: console
> +
> +   ninja -C build dts-doc
> +
> +The output is generated in ``build/doc/api/dts/html``.
> +
> +.. Note::
> +
> +   Make sure to fix any Sphinx warnings when adding or updating docstrings. Also make sure to run
> +   the ``devtools/dts-check-format.sh`` script and address any issues it finds.
> +
> +
>  Configuration Schema
>  --------------------
>
> diff --git a/dts/doc/meson.build b/dts/doc/meson.build
> new file mode 100644
> index 0000000000..01b7b51034
> --- /dev/null
> +++ b/dts/doc/meson.build
> @@ -0,0 +1,27 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2023 PANTHEON.tech s.r.o.
> +
> +sphinx = find_program('sphinx-build', required: false)
> +sphinx_apidoc = find_program('sphinx-apidoc', required: false)
> +
> +if not sphinx.found() or not sphinx_apidoc.found()
> +    subdir_done()
> +endif
> +
> +dts_doc_api_build_dir = join_paths(doc_api_build_dir, 'dts')
> +
> +extra_sphinx_args = ['-E', '-c', doc_guides_source_dir, '--dts-root', dts_dir]
> +if get_option('werror')
> +    extra_sphinx_args += '-W'
> +endif
> +
> +htmldir = join_paths(get_option('datadir'), 'doc', 'dpdk', 'dts')
> +dts_api_html = custom_target('dts_api_html',
> +        output: 'html',
> +        command: [sphinx_wrapper, sphinx, meson.project_version(),
> +            meson.current_source_dir(), dts_doc_api_build_dir, extra_sphinx_args],
> +        build_by_default: false,
> +        install: get_option('enable_docs'),
> +        install_dir: htmldir)
> +doc_targets += dts_api_html
> +doc_target_names += 'DTS_API_HTML'
> diff --git a/dts/meson.build b/dts/meson.build
> new file mode 100644
> index 0000000000..e8ce0f06ac
> --- /dev/null
> +++ b/dts/meson.build
> @@ -0,0 +1,16 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2023 PANTHEON.tech s.r.o.
> +
> +doc_targets = []
> +doc_target_names = []
> +dts_dir = meson.current_source_dir()
> +
> +subdir('doc')
> +
> +if doc_targets.length() == 0
> +    message = 'No docs targets found'
> +else
> +    message = 'Built docs:'
> +endif
> +run_target('dts-doc', command: [echo, message, doc_target_names],
> +    depends: doc_targets)
> diff --git a/meson.build b/meson.build
> index 5e161f43e5..001fdcbbbf 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -87,6 +87,7 @@ subdir('app')
>
>  # build docs
>  subdir('doc')
> +subdir('dts')
>
>  # build any examples explicitly requested - useful for developers - and
>  # install any example code into the appropriate install path
> --
> 2.34.1
>
Reviewed-by: Jeremy Spewock <jspewock@iol.unh.edu>

^ permalink raw reply	[relevance 0%]

* RE: [RFC] ethdev: fast path async flow API
  2024-01-23 11:37  3%       ` Dariusz Sosnowski
@ 2024-01-29 13:38  0%         ` Dariusz Sosnowski
  2024-01-29 17:36  0%           ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Dariusz Sosnowski @ 2024-01-29 13:38 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: NBU-Contact-Thomas Monjalon (EXTERNAL),
	Ferruh Yigit, Andrew Rybchenko, Ori Kam, dev

Hi all,

> -----Original Message-----
> From: Dariusz Sosnowski <dsosnowski@nvidia.com>
> Sent: Tuesday, January 23, 2024 12:37
> To: Stephen Hemminger <stephen@networkplumber.org>
> Cc: NBU-Contact-Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>; Ori Kam <orika@nvidia.com>;
> dev@dpdk.org
> Subject: RE: [RFC] ethdev: fast path async flow API
> 
> Hi Stephen,
> 
> Sorry for such a late response.
> 
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Thursday, January 4, 2024 02:08
> > On Wed, 3 Jan 2024 19:14:49 +0000
> > Dariusz Sosnowski <dsosnowski@nvidia.com> wrote:
> > > In summary, in my opinion extending the async flow API with bulking
> > capabilities or exposing the queue directly to the application is not desirable.
> > > This proposal aims to reduce the I-cache overhead in async flow API
> > > by
> > reusing the existing design pattern in DPDK - fast path functions are
> > inlined to the application code and they call cached PMD callbacks.
> >
> > Inline needs to more discouraged in DPDK, because it only works if
> > application ends up building with DPDK from source.
> > It doesn't work for the Linux distro packaging model and symbol
> > versioning, etc.
> 
> I understand the problem. In that case, I have a proposal.
> I had a chat with Thomas regarding this RFC, and he noticed that there are 2
> separate changes proposed here:
> 
> 1. Per-port callbacks for async flow API.
>     - Moves specified callbacks to rte_flow_fp_ops struct and allow PMDs to
> register them dynamically.
>     - Removes indirection at API level - no need to call rte_flow_ops_get().
>     - Removes checking if callbacks are defined - either the default DPDK callback
> is used or the one provided by PMD.
> 2. Make async flow API functions inlineable.
> 
> Change (1) won't break ABI (existing callbacks in rte_flow_ops can be marked
> as deprecated for now and phased out later) and in my opinion is less
> controversial compared to change (2).
> 
> I'll rerun the benchmarks for both changes separately to compare their
> benefits in isolation.
> This would allow us to decide if change (2) is worth the drawbacks it
> introduces.
> 
> What do you think?

I split the RFC into 2 parts:

1. Introduce per-port callbacks:
    - Introduce rte_flow_fp_ops struct - holds callbacks for fast path calls, for each port. PMD registers callbacks through rte_flow_fp_ops_register().
    - Relevant rte_flow_async_* functions just pass arguments to fast path callbacks. Validation checks are done only if RTE_FLOW_DEBUG macro is defined.
    - Biggest difference is the removal of callback access through rte_flow_get_ops().
2. Inline async flow API functions.
    - Relevant rte_flow_async_* functions definitions are moved to rte_flow.h and made inlineable.

Here are the results of the benchmark:

|                       | Avg Insertion | Diff over baseline | Avg Deletion | Diff over baseline |
|-----------------------|---------------|--------------------|--------------|--------------------|
| baseline (v24.03-rc0) |     5855.4    |                    |    9026.8    |                    |
| applied (1)           |     6384.2    |    +528.8 (+9%)    |    10054.2   |  +1027.4 (+11.4%)  |
| applied (2)           |     6434.6    |   +579.2 (+9.9%)   |    10011.4   |   +984.6 (+10.9%)  |

Results are in KFlows/sec.
The benchmark is continuously inserting and deleting 2M flow rules.
These rules match on IPv4 destination address and with a single action DROP.
Flow rules are inserted and deleted using a single flow queue.

Change (2) improves insertion rate performance by ~1% compared to (1), but decreases deletion rate by ~0.5%.
Based on these results, I think we can say that making rte_flow_async_*() calls inlineable may not be worth it compared to the issues it causes.

What do you all think about the results?

Best regards,
Dariusz Sosnowski
 

^ permalink raw reply	[relevance 0%]

* Re: [RESEND v7 0/3] add telemetry cmds for ring
    @ 2024-01-27  8:33  0%   ` Jie Hai
  1 sibling, 0 replies; 200+ results
From: Jie Hai @ 2024-01-27  8:33 UTC (permalink / raw)
  To: honnappa.nagarahalli, konstantin.v.ananyev, dev, thomas,
	david.marchand, Ruifeng.Wang, mb
  Cc: lihuisong, fengchengwen, liudongdong3

Hi, Thomas,

Kindly ping for review.

Thanks,
Jie Hai


On 2023/11/9 18:20, Jie Hai wrote:
> This patch set supports telemetry cmd to list rings and dump information
> of a ring by its name.
> 
> v1->v2:
> 1. Add space after "switch".
> 2. Fix wrong strlen parameter.
> 
> v2->v3:
> 1. Remove prefix "rte_" for static function.
> 2. Add Acked-by Konstantin Ananyev for PATCH 1.
> 3. Introduce functions to return strings instead copy strings.
> 4. Check pointer to memzone of ring.
> 5. Remove redundant variable.
> 6. Hold lock when access ring data.
> 
> v3->v4:
> 1. Update changelog according to reviews of Honnappa Nagarahalli.
> 2. Add Reviewed-by Honnappa Nagarahalli.
> 3. Correct grammar in help information.
> 4. Correct spell warning on "te" reported by checkpatch.pl.
> 5. Use ring_walk() to query ring info instead of rte_ring_lookup().
> 6. Fix that type definition the flag field of rte_ring does not match the usage.
> 7. Use rte_tel_data_add_dict_uint_hex instead of rte_tel_data_add_dict_u64
>     for mask and flags.
> 
> v4->v5:
> 1. Add Acked-by Konstantin Ananyev and Chengwen Feng.
> 2. Add ABI change explanation for commit message of patch 1/3.
> 
> v5->v6:
> 1. Add Acked-by Morten Br?rup.
> 2. Fix incorrect reference of commit.
> 
> v6->v7:
> 1. Remove prod/consumer head/tail info.
> 
> Jie Hai (3):
>    ring: fix unmatched type definition and usage
>    ring: add telemetry cmd to list rings
>    ring: add telemetry cmd for ring info
> 
>   lib/ring/meson.build     |   1 +
>   lib/ring/rte_ring.c      | 135 +++++++++++++++++++++++++++++++++++++++
>   lib/ring/rte_ring_core.h |   2 +-
>   3 files changed, 137 insertions(+), 1 deletion(-)
> 

^ permalink raw reply	[relevance 0%]

* Re: [PATCH v2 11/11] eventdev: RFC clarify docs on event object fields
  @ 2024-01-24 11:34  3%     ` Mattias Rönnblom
  2024-02-01 16:59  0%       ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Mattias Rönnblom @ 2024-01-24 11:34 UTC (permalink / raw)
  To: Bruce Richardson, dev
  Cc: jerinj, mattias.ronnblom, abdullah.sevincer, sachin.saxena,
	hemant.agrawal, pbhagavatula, pravin.pathak

On 2024-01-19 18:43, Bruce Richardson wrote:
> Clarify the meaning of the NEW, FORWARD and RELEASE event types.
> For the fields in "rte_event" struct, enhance the comments on each to
> clarify the field's use, and whether it is preserved between enqueue and
> dequeue, and it's role, if any, in scheduling.
> 
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> ---
> 
> As with the previous patch, please review this patch to ensure that the
> expected semantics of the various event types and event fields have not
> changed in an unexpected way.
> ---
>   lib/eventdev/rte_eventdev.h | 105 ++++++++++++++++++++++++++----------
>   1 file changed, 77 insertions(+), 28 deletions(-)
> 
> diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h
> index cb13602ffb..4eff1c4958 100644
> --- a/lib/eventdev/rte_eventdev.h
> +++ b/lib/eventdev/rte_eventdev.h
> @@ -1416,21 +1416,25 @@ struct rte_event_vector {
> 
>   /* Event enqueue operations */
>   #define RTE_EVENT_OP_NEW                0
> -/**< The event producers use this operation to inject a new event to the
> +/**< The @ref rte_event.op field should be set to this type to inject a new event to the
>    * event device.
>    */

"type" -> "value"

"to" -> "into"?

You could also say "to mark the event as new".

What is new? Maybe "new (as opposed to a forwarded) event." or "new 
(i.e., not previously dequeued).".

"The application sets the @ref rte_event.op field of an enqueued event 
to this value to mark the event as new (i.e., not previously dequeued)."

>   #define RTE_EVENT_OP_FORWARD            1
> -/**< The CPU use this operation to forward the event to different event queue or
> - * change to new application specific flow or schedule type to enable
> - * pipelining.
> +/**< SW should set the @ref rte_event.op filed to this type to return a
> + * previously dequeued event to the event device for further processing.

"filed" -> "field"

"SW" -> "The application"

"to be scheduled for further processing (or transmission)"

The wording should otherwise be the same as NEW, whatever you choose there.

>    *
> - * This operation must only be enqueued to the same port that the
> + * This event *must* be enqueued to the same port that the
>    * event to be forwarded was dequeued from.

OK, so you "should" mark a new event RTE_EVENT_OP_FORWARD but you 
"*must*" enqueue it to the same port.

I think you "must" do both.

> + *
> + * The event's fields, including (but not limited to) flow_id, scheduling type,
> + * destination queue, and event payload e.g. mbuf pointer, may all be updated as
> + * desired by software, but the @ref rte_event.impl_opaque field must

"software" -> "application"

> + * be kept to the same value as was present when the event was dequeued.
>    */
>   #define RTE_EVENT_OP_RELEASE            2
>   /**< Release the flow context associated with the schedule type.
>    *
> - * If current flow's scheduler type method is *RTE_SCHED_TYPE_ATOMIC*
> + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_ATOMIC
>    * then this function hints the scheduler that the user has completed critical
>    * section processing in the current atomic context.
>    * The scheduler is now allowed to schedule events from the same flow from
> @@ -1442,21 +1446,19 @@ struct rte_event_vector {
>    * performance, but the user needs to design carefully the split into critical
>    * vs non-critical sections.
>    *
> - * If current flow's scheduler type method is *RTE_SCHED_TYPE_ORDERED*
> - * then this function hints the scheduler that the user has done all that need
> - * to maintain event order in the current ordered context.
> - * The scheduler is allowed to release the ordered context of this port and
> - * avoid reordering any following enqueues.
> - *
> - * Early ordered context release may increase parallelism and thus system
> - * performance.
> + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_ORDERED

Isn't a missing "or @ref RTE_SCHED_TYPE_ATOMIC" just an oversight (in 
the original API wording)?

> + * then this function informs the scheduler that the current event has
> + * completed processing and will not be returned to the scheduler, i.e.
> + * it has been dropped, and so the reordering context for that event
> + * should be considered filled.
>    *
> - * If current flow's scheduler type method is *RTE_SCHED_TYPE_PARALLEL*
> + * If current flow's scheduler type method is @ref RTE_SCHED_TYPE_PARALLEL
>    * or no scheduling context is held then this function may be an NOOP,
>    * depending on the implementation.

Maybe you can also fix this "function" -> "operation". I suggest you 
delete that sentence, because it makes no sense.

What is says in a somewhat vague manner is that you tread into the realm 
of undefined behavior if you release PARALLEL events.

>    *
>    * This operation must only be enqueued to the same port that the
> - * event to be released was dequeued from.
> + * event to be released was dequeued from. The @ref rte_event.impl_opaque
> + * field in the release event must match that in the original dequeued event.

I would say "same value" rather than "match".

"The @ref rte_event.impl_opaque field in the release event have the same 
value as in the original dequeued event."

>    */
> 
>   /**
> @@ -1473,53 +1475,100 @@ struct rte_event {
>   			/**< Targeted flow identifier for the enqueue and
>   			 * dequeue operation.
>   			 * The value must be in the range of
> -			 * [0, nb_event_queue_flows - 1] which
> +			 * [0, @ref rte_event_dev_config.nb_event_queue_flows - 1] which

The same comment as I had before about ranges for unsigned types.

>   			 * previously supplied to rte_event_dev_configure().
> +			 *
> +			 * For @ref RTE_SCHED_TYPE_ATOMIC, this field is used to identify a
> +			 * flow context for atomicity, such that events from each individual flow
> +			 * will only be scheduled to one port at a time.

flow_id alone doesn't identify an atomic flow. It's queue_id + flow_id. 
I'm not sure I think "flow context" adds much, unless it's defined 
somewhere. Sounds like some assumed implementation detail.

> +			 *
> +			 * This field is preserved between enqueue and dequeue when
> +			 * a device reports the @ref RTE_EVENT_DEV_CAP_CARRY_FLOW_ID
> +			 * capability. Otherwise the value is implementation dependent
> +			 * on dequeue >   			 */
>   			uint32_t sub_event_type:8;
>   			/**< Sub-event types based on the event source.
> +			 *
> +			 * This field is preserved between enqueue and dequeue.
> +			 * This field is for SW or event adapter use,

"SW" -> "application"

> +			 * and is unused in scheduling decisions.
> +			 *
>   			 * @see RTE_EVENT_TYPE_CPU
>   			 */
>   			uint32_t event_type:4;
> -			/**< Event type to classify the event source.
> -			 * @see RTE_EVENT_TYPE_ETHDEV, (RTE_EVENT_TYPE_*)
> +			/**< Event type to classify the event source. (RTE_EVENT_TYPE_*)
> +			 *
> +			 * This field is preserved between enqueue and dequeue
> +			 * This field is for SW or event adapter use,
> +			 * and is unused in scheduling decisions.

"unused" -> "is not considered"?

>   			 */
>   			uint8_t op:2;
> -			/**< The type of event enqueue operation - new/forward/
> -			 * etc.This field is not preserved across an instance
> +			/**< The type of event enqueue operation - new/forward/ etc.
> +			 *
> +			 * This field is *not* preserved across an instance
>   			 * and is undefined on dequeue.

Maybe you should use "undefined" rather than "implementation dependent", 
or change this instance of undefined to implementation dependent. Now 
two different terms are used for the same thing.

> -			 * @see RTE_EVENT_OP_NEW, (RTE_EVENT_OP_*)
> +			 *
> +			 * @see RTE_EVENT_OP_NEW
> +			 * @see RTE_EVENT_OP_FORWARD
> +			 * @see RTE_EVENT_OP_RELEASE
>   			 */
>   			uint8_t rsvd:4;
> -			/**< Reserved for future use */
> +			/**< Reserved for future use.
> +			 *
> +			 * Should be set to zero on enqueue. Zero on dequeue.
> +			 */

Why say they should be zero on dequeue? Doesn't this defeat the purpose 
of having reserved bits, for future use? With you suggested wording, you 
can't use these bits without breaking the ABI.

>   			uint8_t sched_type:2;
>   			/**< Scheduler synchronization type (RTE_SCHED_TYPE_*)
>   			 * associated with flow id on a given event queue
>   			 * for the enqueue and dequeue operation.
> +			 *
> +			 * This field is used to determine the scheduling type
> +			 * for events sent to queues where @ref RTE_EVENT_QUEUE_CFG_ALL_TYPES
> +			 * is supported.

"supported" -> "configured"

> +			 * For queues where only a single scheduling type is available,
> +			 * this field must be set to match the configured scheduling type.
> +			 *

Why is the API/event device asking this of the application?

> +			 * This field is preserved between enqueue and dequeue.
> +			 *
> +			 * @see RTE_SCHED_TYPE_ORDERED
> +			 * @see RTE_SCHED_TYPE_ATOMIC
> +			 * @see RTE_SCHED_TYPE_PARALLEL
>   			 */
>   			uint8_t queue_id;
>   			/**< Targeted event queue identifier for the enqueue or
>   			 * dequeue operation.
>   			 * The value must be in the range of
> -			 * [0, nb_event_queues - 1] which previously supplied to
> -			 * rte_event_dev_configure().
> +			 * [0, @ref rte_event_dev_config.nb_event_queues - 1] which was
> +			 * previously supplied to rte_event_dev_configure().
> +			 *
> +			 * This field is preserved between enqueue on dequeue.
>   			 */
>   			uint8_t priority;
>   			/**< Event priority relative to other events in the
>   			 * event queue. The requested priority should in the
> -			 * range of  [RTE_EVENT_DEV_PRIORITY_HIGHEST,
> -			 * RTE_EVENT_DEV_PRIORITY_LOWEST].
> +			 * range of  [@ref RTE_EVENT_DEV_PRIORITY_HIGHEST,
> +			 * @ref RTE_EVENT_DEV_PRIORITY_LOWEST].
>   			 * The implementation shall normalize the requested
>   			 * priority to supported priority value.
> +			 *
>   			 * Valid when the device has
> -			 * RTE_EVENT_DEV_CAP_EVENT_QOS capability.
> +			 * @ref RTE_EVENT_DEV_CAP_EVENT_QOS capability.
> +			 * Ignored otherwise.
> +			 *
> +			 * This field is preserved between enqueue and dequeue.

Is the normalized or unnormalized value that is preserved?

>   			 */
>   			uint8_t impl_opaque;
>   			/**< Implementation specific opaque value.

Maybe you can also fix "implementation" here to be something more 
specific. Implementation, of what?

"Event device implementation" or just "event device".

> +			 *
>   			 * An implementation may use this field to hold
>   			 * implementation specific value to share between
>   			 * dequeue and enqueue operation.
> +			 *
>   			 * The application should not modify this field.
> +			 * Its value is implementation dependent on dequeue,
> +			 * and must be returned unmodified on enqueue when
> +			 * op type is @ref RTE_EVENT_OP_FORWARD or @ref RTE_EVENT_OP_RELEASE

Should it be mentioned that impl_opaque is ignored by the event device 
for NEW events?

>   			 */
>   		};
>   	};
> --
> 2.40.1
> 

^ permalink raw reply	[relevance 3%]

* RE: [RFC] ethdev: fast path async flow API
  @ 2024-01-23 11:37  3%       ` Dariusz Sosnowski
  2024-01-29 13:38  0%         ` Dariusz Sosnowski
  0 siblings, 1 reply; 200+ results
From: Dariusz Sosnowski @ 2024-01-23 11:37 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: NBU-Contact-Thomas Monjalon (EXTERNAL),
	Ferruh Yigit, Andrew Rybchenko, Ori Kam, dev

Hi Stephen,

Sorry for such a late response.

From: Stephen Hemminger <stephen@networkplumber.org>
Sent: Thursday, January 4, 2024 02:08
> On Wed, 3 Jan 2024 19:14:49 +0000
> Dariusz Sosnowski <dsosnowski@nvidia.com> wrote:
> > In summary, in my opinion extending the async flow API with bulking
> capabilities or exposing the queue directly to the application is not desirable.
> > This proposal aims to reduce the I-cache overhead in async flow API by
> reusing the existing design pattern in DPDK - fast path functions are inlined to
> the application code and they call cached PMD callbacks.
> 
> Inline needs to more discouraged in DPDK, because it only works if application
> ends up building with DPDK from source.
> It doesn't work for the Linux distro packaging model and symbol versioning,
> etc.

I understand the problem. In that case, I have a proposal.
I had a chat with Thomas regarding this RFC, and he noticed that there are 2 separate changes proposed here:

1. Per-port callbacks for async flow API.
    - Moves specified callbacks to rte_flow_fp_ops struct and allow PMDs to register them dynamically.
    - Removes indirection at API level - no need to call rte_flow_ops_get().
    - Removes checking if callbacks are defined - either the default DPDK callback is used or the one provided by PMD.
2. Make async flow API functions inlineable.

Change (1) won't break ABI (existing callbacks in rte_flow_ops can be marked as deprecated for now and phased out later) and in my opinion is less controversial compared to change (2).

I'll rerun the benchmarks for both changes separately to compare their benefits in isolation.
This would allow us to decide if change (2) is worth the drawbacks it introduces.

What do you think?

Best regards,
Dariusz Sosnowski

^ permalink raw reply	[relevance 3%]

* [PATCH v3 3/3] dts: add API doc generation
  @ 2024-01-22 16:35  2%   ` Juraj Linkeš
  2024-01-29 17:09  0%     ` Jeremy Spewock
       [not found]         ` <CAJvnSUCNjo0p-yhROF1MNLKhjiAw2QTyTHO2hpOaVVUn0xnJ0A@mail.gmail.com>
  0 siblings, 2 replies; 200+ results
From: Juraj Linkeš @ 2024-01-22 16:35 UTC (permalink / raw)
  To: thomas, Honnappa.Nagarahalli, bruce.richardson, jspewock, probb,
	paul.szczepanek, yoan.picchi, Luca.Vizzarro
  Cc: dev, Juraj Linkeš

The tool used to generate developer docs is Sphinx, which is already in
use in DPDK. The same configuration is used to preserve style, but it's
been augmented with doc-generating configuration. There's a change that
modifies how the sidebar displays the content hierarchy that's been put
into an if block to not interfere with regular docs.

Sphinx generates the documentation from Python docstrings. The docstring
format is the Google format [0] which requires the sphinx.ext.napoleon
extension. The other extension, sphinx.ext.intersphinx, enables linking
to object in external documentations, such as the Python documentation.

There are two requirements for building DTS docs:
* The same Python version as DTS or higher, because Sphinx imports the
  code.
* Also the same Python packages as DTS, for the same reason.

[0] https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings

Signed-off-by: Juraj Linkeš <juraj.linkes@pantheon.tech>
---
 buildtools/call-sphinx-build.py | 33 +++++++++++++++++++---------
 doc/api/doxy-api-index.md       |  3 +++
 doc/api/doxy-api.conf.in        |  2 ++
 doc/api/meson.build             | 11 +++++++---
 doc/guides/conf.py              | 39 ++++++++++++++++++++++++++++-----
 doc/guides/meson.build          |  1 +
 doc/guides/tools/dts.rst        | 34 +++++++++++++++++++++++++++-
 dts/doc/meson.build             | 27 +++++++++++++++++++++++
 dts/meson.build                 | 16 ++++++++++++++
 meson.build                     |  1 +
 10 files changed, 148 insertions(+), 19 deletions(-)
 create mode 100644 dts/doc/meson.build
 create mode 100644 dts/meson.build

diff --git a/buildtools/call-sphinx-build.py b/buildtools/call-sphinx-build.py
index 39a60d09fa..aea771a64e 100755
--- a/buildtools/call-sphinx-build.py
+++ b/buildtools/call-sphinx-build.py
@@ -3,37 +3,50 @@
 # Copyright(c) 2019 Intel Corporation
 #
 
+import argparse
 import sys
 import os
 from os.path import join
 from subprocess import run, PIPE, STDOUT
 from packaging.version import Version
 
-# assign parameters to variables
-(sphinx, version, src, dst, *extra_args) = sys.argv[1:]
+parser = argparse.ArgumentParser()
+parser.add_argument('sphinx')
+parser.add_argument('version')
+parser.add_argument('src')
+parser.add_argument('dst')
+parser.add_argument('--dts-root', default=None)
+args, extra_args = parser.parse_known_args()
 
 # set the version in environment for sphinx to pick up
-os.environ['DPDK_VERSION'] = version
+os.environ['DPDK_VERSION'] = args.version
+if args.dts_root:
+    os.environ['DTS_ROOT'] = args.dts_root
 
 # for sphinx version >= 1.7 add parallelism using "-j auto"
-ver = run([sphinx, '--version'], stdout=PIPE,
+ver = run([args.sphinx, '--version'], stdout=PIPE,
           stderr=STDOUT).stdout.decode().split()[-1]
-sphinx_cmd = [sphinx] + extra_args
+sphinx_cmd = [args.sphinx] + extra_args
 if Version(ver) >= Version('1.7'):
     sphinx_cmd += ['-j', 'auto']
 
 # find all the files sphinx will process so we can write them as dependencies
 srcfiles = []
-for root, dirs, files in os.walk(src):
+for root, dirs, files in os.walk(args.src):
     srcfiles.extend([join(root, f) for f in files])
 
+if not os.path.exists(args.dst):
+    os.makedirs(args.dst)
+
 # run sphinx, putting the html output in a "html" directory
-with open(join(dst, 'sphinx_html.out'), 'w') as out:
-    process = run(sphinx_cmd + ['-b', 'html', src, join(dst, 'html')],
-                  stdout=out)
+with open(join(args.dst, 'sphinx_html.out'), 'w') as out:
+    process = run(
+        sphinx_cmd + ['-b', 'html', args.src, join(args.dst, 'html')],
+        stdout=out
+    )
 
 # create a gcc format .d file giving all the dependencies of this doc build
-with open(join(dst, '.html.d'), 'w') as d:
+with open(join(args.dst, '.html.d'), 'w') as d:
     d.write('html: ' + ' '.join(srcfiles) + '\n')
 
 sys.exit(process.returncode)
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index a6a768bd7c..b49b24acce 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -241,3 +241,6 @@ The public API headers are grouped by topics:
   [experimental APIs](@ref rte_compat.h),
   [ABI versioning](@ref rte_function_versioning.h),
   [version](@ref rte_version.h)
+
+- **tests**:
+  [**DTS**](@dts_api_main_page)
diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in
index e94c9e4e46..d53edeba57 100644
--- a/doc/api/doxy-api.conf.in
+++ b/doc/api/doxy-api.conf.in
@@ -121,6 +121,8 @@ SEARCHENGINE            = YES
 SORT_MEMBER_DOCS        = NO
 SOURCE_BROWSER          = YES
 
+ALIASES                 = "dts_api_main_page=@DTS_API_MAIN_PAGE@"
+
 EXAMPLE_PATH            = @TOPDIR@/examples
 EXAMPLE_PATTERNS        = *.c
 EXAMPLE_RECURSIVE       = YES
diff --git a/doc/api/meson.build b/doc/api/meson.build
index 5b50692df9..ffc75d7b5a 100644
--- a/doc/api/meson.build
+++ b/doc/api/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Luca Boccassi <bluca@debian.org>
 
+doc_api_build_dir = meson.current_build_dir()
 doxygen = find_program('doxygen', required: get_option('enable_docs'))
 
 if not doxygen.found()
@@ -32,14 +33,18 @@ example = custom_target('examples.dox',
 # set up common Doxygen configuration
 cdata = configuration_data()
 cdata.set('VERSION', meson.project_version())
-cdata.set('API_EXAMPLES', join_paths(dpdk_build_root, 'doc', 'api', 'examples.dox'))
-cdata.set('OUTPUT', join_paths(dpdk_build_root, 'doc', 'api'))
+cdata.set('API_EXAMPLES', join_paths(doc_api_build_dir, 'examples.dox'))
+cdata.set('OUTPUT', doc_api_build_dir)
 cdata.set('TOPDIR', dpdk_source_root)
-cdata.set('STRIP_FROM_PATH', ' '.join([dpdk_source_root, join_paths(dpdk_build_root, 'doc', 'api')]))
+cdata.set('STRIP_FROM_PATH', ' '.join([dpdk_source_root, doc_api_build_dir]))
 cdata.set('WARN_AS_ERROR', 'NO')
 if get_option('werror')
     cdata.set('WARN_AS_ERROR', 'YES')
 endif
+# A local reference must be relative to the main index.html page
+# The path below can't be taken from the DTS meson file as that would
+# require recursive subdir traversal (doc, dts, then doc again)
+cdata.set('DTS_API_MAIN_PAGE', join_paths('..', 'dts', 'html', 'index.html'))
 
 # configure HTML Doxygen run
 html_cdata = configuration_data()
diff --git a/doc/guides/conf.py b/doc/guides/conf.py
index 0f7ff5282d..b442a1f76c 100644
--- a/doc/guides/conf.py
+++ b/doc/guides/conf.py
@@ -7,10 +7,9 @@
 from sphinx import __version__ as sphinx_version
 from os import listdir
 from os import environ
-from os.path import basename
-from os.path import dirname
+from os.path import basename, dirname
 from os.path import join as path_join
-from sys import argv, stderr
+from sys import argv, stderr, path
 
 import configparser
 
@@ -24,6 +23,37 @@
           file=stderr)
     pass
 
+# Napoleon enables the Google format of Python doscstrings, used in DTS
+# Intersphinx allows linking to external projects, such as Python docs, also used in DTS
+extensions = ['sphinx.ext.napoleon', 'sphinx.ext.intersphinx']
+
+# DTS Python docstring options
+autodoc_default_options = {
+    'members': True,
+    'member-order': 'bysource',
+    'show-inheritance': True,
+}
+autodoc_class_signature = 'separated'
+autodoc_typehints = 'both'
+autodoc_typehints_format = 'short'
+autodoc_typehints_description_target = 'documented'
+napoleon_numpy_docstring = False
+napoleon_attr_annotations = True
+napoleon_preprocess_types = True
+add_module_names = False
+toc_object_entries = True
+toc_object_entries_show_parents = 'hide'
+intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}
+
+dts_root = environ.get('DTS_ROOT')
+if dts_root:
+    path.append(dts_root)
+    # DTS Sidebar config
+    html_theme_options = {
+        'collapse_navigation': False,
+        'navigation_depth': -1,
+    }
+
 stop_on_error = ('-W' in argv)
 
 project = 'Data Plane Development Kit'
@@ -35,8 +65,7 @@
 html_show_copyright = False
 highlight_language = 'none'
 
-release = environ.setdefault('DPDK_VERSION', "None")
-version = release
+version = environ.setdefault('DPDK_VERSION', "None")
 
 master_doc = 'index'
 
diff --git a/doc/guides/meson.build b/doc/guides/meson.build
index 51f81da2e3..8933d75f6b 100644
--- a/doc/guides/meson.build
+++ b/doc/guides/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Intel Corporation
 
+doc_guides_source_dir = meson.current_source_dir()
 sphinx = find_program('sphinx-build', required: get_option('enable_docs'))
 
 if not sphinx.found()
diff --git a/doc/guides/tools/dts.rst b/doc/guides/tools/dts.rst
index 846696e14e..21d3d89fc2 100644
--- a/doc/guides/tools/dts.rst
+++ b/doc/guides/tools/dts.rst
@@ -278,7 +278,12 @@ and try not to divert much from it.
 The :ref:`DTS developer tools <dts_dev_tools>` will issue warnings
 when some of the basics are not met.
 
-The code must be properly documented with docstrings.
+The API documentation, which is a helpful reference when developing, may be accessed
+in the code directly or generated with the :ref:`API docs build steps <building_api_docs>`.
+When adding new files or modifying the directory structure, the corresponding changes must
+be made to DTS api doc sources in ``dts/doc``.
+
+Speaking of which, the code must be properly documented with docstrings.
 The style must conform to the `Google style
 <https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings>`_.
 See an example of the style `here
@@ -413,6 +418,33 @@ the DTS code check and format script.
 Refer to the script for usage: ``devtools/dts-check-format.sh -h``.
 
 
+.. _building_api_docs:
+
+Building DTS API docs
+---------------------
+
+To build DTS API docs, install the dependencies with Poetry, then enter its shell:
+
+.. code-block:: console
+
+   poetry install --with docs
+   poetry shell
+
+The documentation is built using the standard DPDK build system. After executing the meson command
+and entering Poetry's shell, build the documentation with:
+
+.. code-block:: console
+
+   ninja -C build dts-doc
+
+The output is generated in ``build/doc/api/dts/html``.
+
+.. Note::
+
+   Make sure to fix any Sphinx warnings when adding or updating docstrings. Also make sure to run
+   the ``devtools/dts-check-format.sh`` script and address any issues it finds.
+
+
 Configuration Schema
 --------------------
 
diff --git a/dts/doc/meson.build b/dts/doc/meson.build
new file mode 100644
index 0000000000..01b7b51034
--- /dev/null
+++ b/dts/doc/meson.build
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2023 PANTHEON.tech s.r.o.
+
+sphinx = find_program('sphinx-build', required: false)
+sphinx_apidoc = find_program('sphinx-apidoc', required: false)
+
+if not sphinx.found() or not sphinx_apidoc.found()
+    subdir_done()
+endif
+
+dts_doc_api_build_dir = join_paths(doc_api_build_dir, 'dts')
+
+extra_sphinx_args = ['-E', '-c', doc_guides_source_dir, '--dts-root', dts_dir]
+if get_option('werror')
+    extra_sphinx_args += '-W'
+endif
+
+htmldir = join_paths(get_option('datadir'), 'doc', 'dpdk', 'dts')
+dts_api_html = custom_target('dts_api_html',
+        output: 'html',
+        command: [sphinx_wrapper, sphinx, meson.project_version(),
+            meson.current_source_dir(), dts_doc_api_build_dir, extra_sphinx_args],
+        build_by_default: false,
+        install: get_option('enable_docs'),
+        install_dir: htmldir)
+doc_targets += dts_api_html
+doc_target_names += 'DTS_API_HTML'
diff --git a/dts/meson.build b/dts/meson.build
new file mode 100644
index 0000000000..e8ce0f06ac
--- /dev/null
+++ b/dts/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2023 PANTHEON.tech s.r.o.
+
+doc_targets = []
+doc_target_names = []
+dts_dir = meson.current_source_dir()
+
+subdir('doc')
+
+if doc_targets.length() == 0
+    message = 'No docs targets found'
+else
+    message = 'Built docs:'
+endif
+run_target('dts-doc', command: [echo, message, doc_target_names],
+    depends: doc_targets)
diff --git a/meson.build b/meson.build
index 5e161f43e5..001fdcbbbf 100644
--- a/meson.build
+++ b/meson.build
@@ -87,6 +87,7 @@ subdir('app')
 
 # build docs
 subdir('doc')
+subdir('dts')
 
 # build any examples explicitly requested - useful for developers - and
 # install any example code into the appropriate install path
-- 
2.34.1


^ permalink raw reply	[relevance 2%]

* RE: [dpdk-dev] [v2] ethdev: support Tx queue used count
  2024-01-18  9:47  3%   ` [dpdk-dev] [v2] " jerinj
@ 2024-01-22 13:00  0%     ` Konstantin Ananyev
  0 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2024-01-22 13:00 UTC (permalink / raw)
  To: jerinj, dev, Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
  Cc: ferruh.yigit, ajit.khaparde, aboyer, beilei.xing,
	bruce.richardson, chas3, chenbo.xia, ciara.loftus, dsinghrawat,
	ed.czeck, evgenys, grive, g.singh, haiyue.wang, hkalra,
	heinrich.kuhn, hemant.agrawal, hyonkim, igorch, irusskikh,
	jgrajcia, jasvinder.singh, jianwang, jiawenwu, jingjing.wu,
	johndale, john.miller, linville, keith.wiles, kirankumark,
	lironh, longli, mw, spinler, matan, matt.peters, maxime.coquelin,
	mk, humin (Q),
	pnalla, ndabilpuram, qiming.yang, qi.z.zhang, radhac,
	rahul.lakkireddy, rmody, rosen.xu, sachin.saxena, skoteshwar,
	shshaikh, shaibran, shepard.siegel, asomalap, somnath.kotur,
	sthemmin, steven.webster, skori, mtetsuyah, vburru, viacheslavo,
	xiao.w.wang, Wangxiaoyun (Cloud), Zhuangyuzeng (Yisen),
	yongwang, Xuanziyang (William),
	cristian.dumitrescu, Morten Brørup



> From: Jerin Jacob <jerinj@marvell.com>
> 
> Introduce a new API to retrieve the number of used descriptors
> in a Tx queue. Applications can leverage this API in the fast path to
> inspect the Tx queue occupancy and take appropriate actions based on the
> available free descriptors.
> 
> A notable use case could be implementing Random Early Discard (RED)
> in software based on Tx queue occupancy.
> 
> Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Acked-by: Morten Brørup <mb@smartsharesystems.com>
> ---
>  devtools/libabigail.abignore           |  3 +
>  doc/guides/nics/features.rst           | 10 ++++
>  doc/guides/nics/features/default.ini   |  1 +
>  doc/guides/rel_notes/release_24_03.rst |  5 ++
>  lib/ethdev/ethdev_driver.h             |  2 +
>  lib/ethdev/ethdev_private.c            |  1 +
>  lib/ethdev/ethdev_trace_points.c       |  3 +
>  lib/ethdev/rte_ethdev.h                | 80 ++++++++++++++++++++++++++
>  lib/ethdev/rte_ethdev_core.h           |  7 ++-
>  lib/ethdev/rte_ethdev_trace_fp.h       |  8 +++
>  lib/ethdev/version.map                 |  1 +
>  11 files changed, 120 insertions(+), 1 deletion(-)
> 
> v2:
> - Rename _nic_features_tx_queue_used_count to _nic_features_tx_queue_count
> - Fix trace emission of case fops->tx_queue_count == NULL
> - Rename tx_queue_id to queue_id in implementation symbols and prints
> - Added "goto out" for better error handling
> - Add release note
> - Added libabigail suppression rule for the reserved2 field update
> - Fix all ordering and grouping, empty line comment from Ferruh
> - Added following notes in doxygen documentation for better clarity on API usage
>  * @note There is no requirement to call this function before rte_eth_tx_burst() invocation.
>  * @note Utilize this function exclusively when the caller needs to determine the used queue count
>  * across all descriptors of a Tx queue. If the use case only involves checking the status of a
>  * specific descriptor slot, opt for rte_eth_tx_descriptor_status() instead.
> 
> rfc..v1:
> - Updated API similar to rte_eth_rx_queue_count() where it returns
> "used" count instead of "free" count
> 
> diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
> index 21b8cd6113..d6e98c6f52 100644
> --- a/devtools/libabigail.abignore
> +++ b/devtools/libabigail.abignore
> @@ -33,3 +33,6 @@
>  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>  ; Temporary exceptions till next major ABI version ;
>  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> +[suppress_type]
> +	name = rte_eth_fp_ops
> +	has_data_member_inserted_between = {offset_of(reserved2), end}
> diff --git a/doc/guides/nics/features.rst b/doc/guides/nics/features.rst
> index f7d9980849..f38941c719 100644
> --- a/doc/guides/nics/features.rst
> +++ b/doc/guides/nics/features.rst
> @@ -697,6 +697,16 @@ or "Unavailable."
>  * **[related]    API**: ``rte_eth_tx_descriptor_status()``.
> 
> 
> +.. _nic_features_tx_queue_count:
> +
> +Tx queue count
> +--------------
> +
> +Supports to get the number of used descriptors of a Tx queue.
> +
> +* **[implements] eth_dev_ops**: ``tx_queue_count``.
> +* **[related] API**: ``rte_eth_tx_queue_count()``.
> +
>  .. _nic_features_basic_stats:
> 
>  Basic stats
> diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
> index 6d50236292..5115963136 100644
> --- a/doc/guides/nics/features/default.ini
> +++ b/doc/guides/nics/features/default.ini
> @@ -59,6 +59,7 @@ Packet type parsing  =
>  Timesync             =
>  Rx descriptor status =
>  Tx descriptor status =
> +Tx queue count       =
>  Basic stats          =
>  Extended stats       =
>  Stats per queue      =
> diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
> index c4fc8ad583..16dd367178 100644
> --- a/doc/guides/rel_notes/release_24_03.rst
> +++ b/doc/guides/rel_notes/release_24_03.rst
> @@ -65,6 +65,11 @@ New Features
>    * Added ``RTE_FLOW_ITEM_TYPE_RANDOM`` to match random value.
>    * Added ``RTE_FLOW_FIELD_RANDOM`` to represent it in field ID struct.
> 
> +* ** Support for getting the number of used descriptors of a Tx queue. **
> +
> +  * Added a fath path function ``rte_eth_tx_queue_count`` to get the number of used
> +    descriptors of a Tx queue.
> +
> 
>  Removed Items
>  -------------
> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
> index b482cd12bb..f05f68a67c 100644
> --- a/lib/ethdev/ethdev_driver.h
> +++ b/lib/ethdev/ethdev_driver.h
> @@ -58,6 +58,8 @@ struct rte_eth_dev {
>  	eth_rx_queue_count_t rx_queue_count;
>  	/** Check the status of a Rx descriptor */
>  	eth_rx_descriptor_status_t rx_descriptor_status;
> +	/** Get the number of used Tx descriptors */
> +	eth_tx_queue_count_t tx_queue_count;
>  	/** Check the status of a Tx descriptor */
>  	eth_tx_descriptor_status_t tx_descriptor_status;
>  	/** Pointer to PMD transmit mbufs reuse function */
> diff --git a/lib/ethdev/ethdev_private.c b/lib/ethdev/ethdev_private.c
> index a656df293c..626524558a 100644
> --- a/lib/ethdev/ethdev_private.c
> +++ b/lib/ethdev/ethdev_private.c
> @@ -273,6 +273,7 @@ eth_dev_fp_ops_setup(struct rte_eth_fp_ops *fpo,
>  	fpo->tx_pkt_prepare = dev->tx_pkt_prepare;
>  	fpo->rx_queue_count = dev->rx_queue_count;
>  	fpo->rx_descriptor_status = dev->rx_descriptor_status;
> +	fpo->tx_queue_count = dev->tx_queue_count;
>  	fpo->tx_descriptor_status = dev->tx_descriptor_status;
>  	fpo->recycle_tx_mbufs_reuse = dev->recycle_tx_mbufs_reuse;
>  	fpo->recycle_rx_descriptors_refill = dev->recycle_rx_descriptors_refill;
> diff --git a/lib/ethdev/ethdev_trace_points.c b/lib/ethdev/ethdev_trace_points.c
> index 91f71d868b..bd6dd4e78a 100644
> --- a/lib/ethdev/ethdev_trace_points.c
> +++ b/lib/ethdev/ethdev_trace_points.c
> @@ -37,6 +37,9 @@ RTE_TRACE_POINT_REGISTER(rte_eth_trace_call_rx_callbacks,
>  RTE_TRACE_POINT_REGISTER(rte_eth_trace_call_tx_callbacks,
>  	lib.ethdev.call_tx_callbacks)
> 
> +RTE_TRACE_POINT_REGISTER(rte_eth_trace_tx_queue_count,
> +	lib.ethdev.tx_queue_count)
> +
>  RTE_TRACE_POINT_REGISTER(rte_eth_trace_iterator_init,
>  	lib.ethdev.iterator_init)
> 
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index b7f52e03a5..2687c23fa6 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -6823,6 +6823,86 @@ rte_eth_recycle_mbufs(uint16_t rx_port_id, uint16_t rx_queue_id,
>  __rte_experimental
>  int rte_eth_buffer_split_get_supported_hdr_ptypes(uint16_t port_id, uint32_t *ptypes, int num);
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
> + *
> + * Get the number of used descriptors of a Tx queue
> + *
> + * This function retrieves the number of used descriptors of a transmit queue.
> + * Applications can use this API in the fast path to inspect Tx queue occupancy and take
> + * appropriate actions based on the available free descriptors.
> + * An example action could be implementing the Random Early Discard (RED).
> + *
> + * Since it's a fast-path function, no check is performed on port_id and
> + * queue_id. The caller must therefore ensure that the port is enabled
> + * and the queue is configured and running.
> + *
> + * @param port_id
> + *   The port identifier of the device.
> + * @param queue_id
> + *   The index of the transmit queue.
> + *   The value must be in the range [0, nb_tx_queue - 1] previously supplied
> + *   to rte_eth_dev_configure().
> + * @return
> + *  The number of used descriptors in the specific queue, or:
> + *   - (-ENODEV) if *port_id* is invalid. Enabled only when RTE_ETHDEV_DEBUG_TX is enabled
> + *   - (-EINVAL) if *queue_id* is invalid. Enabled only when RTE_ETHDEV_DEBUG_TX is enabled
> + *   - (-ENOTSUP) if the device does not support this function.
> + *
> + * @note This function is designed for fast-path use.
> + * @note There is no requirement to call this function before rte_eth_tx_burst() invocation.
> + * @note Utilize this function exclusively when the caller needs to determine the used queue count
> + * across all descriptors of a Tx queue. If the use case only involves checking the status of a
> + * specific descriptor slot, opt for rte_eth_tx_descriptor_status() instead.
> + */
> +
> +__rte_experimental
> +static inline int
> +rte_eth_tx_queue_count(uint16_t port_id, uint16_t queue_id)
> +{
> +	struct rte_eth_fp_ops *fops;
> +	void *qd;
> +	int rc;
> +
> +#ifdef RTE_ETHDEV_DEBUG_TX
> +	if (port_id >= RTE_MAX_ETHPORTS || !rte_eth_dev_is_valid_port(port_id)) {
> +		RTE_ETHDEV_LOG_LINE(ERR, "Invalid port_id=%u", port_id);
> +		rc = -ENODEV;
> +		goto out;
> +	}
> +
> +	if (queue_id >= RTE_MAX_QUEUES_PER_PORT) {
> +		RTE_ETHDEV_LOG_LINE(ERR, "Invalid queue_id=%u for port_id=%u",
> +				    queue_id, port_id);
> +		rc = -EINVAL;
> +		goto out;
> +	}
> +#endif
> +
> +	/* Fetch pointer to Tx queue data */
> +	fops = &rte_eth_fp_ops[port_id];
> +	qd = fops->txq.data[queue_id];
> +
> +#ifdef RTE_ETHDEV_DEBUG_TX
> +	if (qd == NULL) {
> +		RTE_ETHDEV_LOG_LINE(ERR, "Invalid queue_id=%u for port_id=%u",
> +				    queue_id, port_id);
> +		rc = -EINVAL;
> +		goto out;
> +	}
> +#endif
> +	if (fops->tx_queue_count == NULL) {
> +		rc = -ENOTSUP;
> +		goto out;
> +	}
> +
> +	rc = fops->tx_queue_count(qd);
> +
> +out:
> +	rte_eth_trace_tx_queue_count(port_id, queue_id, rc);
> +	return rc;
> +}
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/lib/ethdev/rte_ethdev_core.h b/lib/ethdev/rte_ethdev_core.h
> index 4bfaf79c6c..a18f242ca4 100644
> --- a/lib/ethdev/rte_ethdev_core.h
> +++ b/lib/ethdev/rte_ethdev_core.h
> @@ -50,6 +50,9 @@ typedef uint32_t (*eth_rx_queue_count_t)(void *rxq);
>  /** @internal Check the status of a Rx descriptor */
>  typedef int (*eth_rx_descriptor_status_t)(void *rxq, uint16_t offset);
> 
> +/** @internal Get number of used descriptors on a transmit queue. */
> +typedef int (*eth_tx_queue_count_t)(void *txq);
> +
>  /** @internal Check the status of a Tx descriptor */
>  typedef int (*eth_tx_descriptor_status_t)(void *txq, uint16_t offset);
> 
> @@ -116,7 +119,9 @@ struct rte_eth_fp_ops {
>  	eth_tx_descriptor_status_t tx_descriptor_status;
>  	/** Copy used mbufs from Tx mbuf ring into Rx. */
>  	eth_recycle_tx_mbufs_reuse_t recycle_tx_mbufs_reuse;
> -	uintptr_t reserved2[2];
> +	/** Get the number of used Tx descriptors. */
> +	eth_tx_queue_count_t tx_queue_count;
> +	uintptr_t reserved2[1];
>  	/**@}*/
> 
>  } __rte_cache_aligned;
> diff --git a/lib/ethdev/rte_ethdev_trace_fp.h b/lib/ethdev/rte_ethdev_trace_fp.h
> index 186271c9ff..40b6e4756b 100644
> --- a/lib/ethdev/rte_ethdev_trace_fp.h
> +++ b/lib/ethdev/rte_ethdev_trace_fp.h
> @@ -73,6 +73,14 @@ RTE_TRACE_POINT_FP(
>  	rte_trace_point_emit_u64(count);
>  )
> 
> +RTE_TRACE_POINT_FP(
> +	rte_eth_trace_tx_queue_count,
> +	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t queue_id, int rc),
> +	rte_trace_point_emit_u16(port_id);
> +	rte_trace_point_emit_u16(queue_id);
> +	rte_trace_point_emit_int(rc);
> +)
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
> index a050baab0f..73a788d91a 100644
> --- a/lib/ethdev/version.map
> +++ b/lib/ethdev/version.map
> @@ -319,6 +319,7 @@ EXPERIMENTAL {
> 
>  	# added in 24.03
>  	rte_eth_find_rss_algo;
> +	rte_eth_tx_queue_count;
>  };
> 
>  INTERNAL {
> --

Acked-by: Konstantin Ananyev <konstantin.ananyev@huawei.com>

> 2.43.0


^ permalink raw reply	[relevance 0%]

* [PATCH v2 3/3] dts: add API doc generation
  @ 2024-01-22 12:00  2%   ` Juraj Linkeš
  0 siblings, 0 replies; 200+ results
From: Juraj Linkeš @ 2024-01-22 12:00 UTC (permalink / raw)
  To: thomas, Honnappa.Nagarahalli, bruce.richardson, jspewock, probb,
	paul.szczepanek, yoan.picchi, Luca.Vizzarro
  Cc: dev, Juraj Linkeš

The tool used to generate developer docs is Sphinx, which is already in
use in DPDK. The same configuration is used to preserve style, but it's
been augmented with doc-generating configuration. There's a change that
modifies how the sidebar displays the content hierarchy that's been put
into an if block to not interfere with regular docs.

Sphinx generates the documentation from Python docstrings. The docstring
format is the Google format [0] which requires the sphinx.ext.napoleon
extension. The other extension, sphinx.ext.intersphinx, enables linking
to object in external documentations, such as the Python documentation.

There are two requirements for building DTS docs:
* The same Python version as DTS or higher, because Sphinx imports the
  code.
* Also the same Python packages as DTS, for the same reason.

[0] https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings

Signed-off-by: Juraj Linkeš <juraj.linkes@pantheon.tech>
---
 buildtools/call-sphinx-build.py | 33 +++++++++++++++++++---------
 doc/api/doxy-api-index.md       |  3 +++
 doc/api/doxy-api.conf.in        |  2 ++
 doc/api/meson.build             | 11 +++++++---
 doc/guides/conf.py              | 39 ++++++++++++++++++++++++++++-----
 doc/guides/meson.build          |  1 +
 doc/guides/tools/dts.rst        | 34 +++++++++++++++++++++++++++-
 dts/doc/meson.build             | 27 +++++++++++++++++++++++
 dts/meson.build                 | 16 ++++++++++++++
 meson.build                     |  1 +
 10 files changed, 148 insertions(+), 19 deletions(-)
 create mode 100644 dts/doc/meson.build
 create mode 100644 dts/meson.build

diff --git a/buildtools/call-sphinx-build.py b/buildtools/call-sphinx-build.py
index 39a60d09fa..aea771a64e 100755
--- a/buildtools/call-sphinx-build.py
+++ b/buildtools/call-sphinx-build.py
@@ -3,37 +3,50 @@
 # Copyright(c) 2019 Intel Corporation
 #
 
+import argparse
 import sys
 import os
 from os.path import join
 from subprocess import run, PIPE, STDOUT
 from packaging.version import Version
 
-# assign parameters to variables
-(sphinx, version, src, dst, *extra_args) = sys.argv[1:]
+parser = argparse.ArgumentParser()
+parser.add_argument('sphinx')
+parser.add_argument('version')
+parser.add_argument('src')
+parser.add_argument('dst')
+parser.add_argument('--dts-root', default=None)
+args, extra_args = parser.parse_known_args()
 
 # set the version in environment for sphinx to pick up
-os.environ['DPDK_VERSION'] = version
+os.environ['DPDK_VERSION'] = args.version
+if args.dts_root:
+    os.environ['DTS_ROOT'] = args.dts_root
 
 # for sphinx version >= 1.7 add parallelism using "-j auto"
-ver = run([sphinx, '--version'], stdout=PIPE,
+ver = run([args.sphinx, '--version'], stdout=PIPE,
           stderr=STDOUT).stdout.decode().split()[-1]
-sphinx_cmd = [sphinx] + extra_args
+sphinx_cmd = [args.sphinx] + extra_args
 if Version(ver) >= Version('1.7'):
     sphinx_cmd += ['-j', 'auto']
 
 # find all the files sphinx will process so we can write them as dependencies
 srcfiles = []
-for root, dirs, files in os.walk(src):
+for root, dirs, files in os.walk(args.src):
     srcfiles.extend([join(root, f) for f in files])
 
+if not os.path.exists(args.dst):
+    os.makedirs(args.dst)
+
 # run sphinx, putting the html output in a "html" directory
-with open(join(dst, 'sphinx_html.out'), 'w') as out:
-    process = run(sphinx_cmd + ['-b', 'html', src, join(dst, 'html')],
-                  stdout=out)
+with open(join(args.dst, 'sphinx_html.out'), 'w') as out:
+    process = run(
+        sphinx_cmd + ['-b', 'html', args.src, join(args.dst, 'html')],
+        stdout=out
+    )
 
 # create a gcc format .d file giving all the dependencies of this doc build
-with open(join(dst, '.html.d'), 'w') as d:
+with open(join(args.dst, '.html.d'), 'w') as d:
     d.write('html: ' + ' '.join(srcfiles) + '\n')
 
 sys.exit(process.returncode)
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index a6a768bd7c..b49b24acce 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -241,3 +241,6 @@ The public API headers are grouped by topics:
   [experimental APIs](@ref rte_compat.h),
   [ABI versioning](@ref rte_function_versioning.h),
   [version](@ref rte_version.h)
+
+- **tests**:
+  [**DTS**](@dts_api_main_page)
diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in
index e94c9e4e46..d53edeba57 100644
--- a/doc/api/doxy-api.conf.in
+++ b/doc/api/doxy-api.conf.in
@@ -121,6 +121,8 @@ SEARCHENGINE            = YES
 SORT_MEMBER_DOCS        = NO
 SOURCE_BROWSER          = YES
 
+ALIASES                 = "dts_api_main_page=@DTS_API_MAIN_PAGE@"
+
 EXAMPLE_PATH            = @TOPDIR@/examples
 EXAMPLE_PATTERNS        = *.c
 EXAMPLE_RECURSIVE       = YES
diff --git a/doc/api/meson.build b/doc/api/meson.build
index 5b50692df9..ffc75d7b5a 100644
--- a/doc/api/meson.build
+++ b/doc/api/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Luca Boccassi <bluca@debian.org>
 
+doc_api_build_dir = meson.current_build_dir()
 doxygen = find_program('doxygen', required: get_option('enable_docs'))
 
 if not doxygen.found()
@@ -32,14 +33,18 @@ example = custom_target('examples.dox',
 # set up common Doxygen configuration
 cdata = configuration_data()
 cdata.set('VERSION', meson.project_version())
-cdata.set('API_EXAMPLES', join_paths(dpdk_build_root, 'doc', 'api', 'examples.dox'))
-cdata.set('OUTPUT', join_paths(dpdk_build_root, 'doc', 'api'))
+cdata.set('API_EXAMPLES', join_paths(doc_api_build_dir, 'examples.dox'))
+cdata.set('OUTPUT', doc_api_build_dir)
 cdata.set('TOPDIR', dpdk_source_root)
-cdata.set('STRIP_FROM_PATH', ' '.join([dpdk_source_root, join_paths(dpdk_build_root, 'doc', 'api')]))
+cdata.set('STRIP_FROM_PATH', ' '.join([dpdk_source_root, doc_api_build_dir]))
 cdata.set('WARN_AS_ERROR', 'NO')
 if get_option('werror')
     cdata.set('WARN_AS_ERROR', 'YES')
 endif
+# A local reference must be relative to the main index.html page
+# The path below can't be taken from the DTS meson file as that would
+# require recursive subdir traversal (doc, dts, then doc again)
+cdata.set('DTS_API_MAIN_PAGE', join_paths('..', 'dts', 'html', 'index.html'))
 
 # configure HTML Doxygen run
 html_cdata = configuration_data()
diff --git a/doc/guides/conf.py b/doc/guides/conf.py
index 0f7ff5282d..b442a1f76c 100644
--- a/doc/guides/conf.py
+++ b/doc/guides/conf.py
@@ -7,10 +7,9 @@
 from sphinx import __version__ as sphinx_version
 from os import listdir
 from os import environ
-from os.path import basename
-from os.path import dirname
+from os.path import basename, dirname
 from os.path import join as path_join
-from sys import argv, stderr
+from sys import argv, stderr, path
 
 import configparser
 
@@ -24,6 +23,37 @@
           file=stderr)
     pass
 
+# Napoleon enables the Google format of Python doscstrings, used in DTS
+# Intersphinx allows linking to external projects, such as Python docs, also used in DTS
+extensions = ['sphinx.ext.napoleon', 'sphinx.ext.intersphinx']
+
+# DTS Python docstring options
+autodoc_default_options = {
+    'members': True,
+    'member-order': 'bysource',
+    'show-inheritance': True,
+}
+autodoc_class_signature = 'separated'
+autodoc_typehints = 'both'
+autodoc_typehints_format = 'short'
+autodoc_typehints_description_target = 'documented'
+napoleon_numpy_docstring = False
+napoleon_attr_annotations = True
+napoleon_preprocess_types = True
+add_module_names = False
+toc_object_entries = True
+toc_object_entries_show_parents = 'hide'
+intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}
+
+dts_root = environ.get('DTS_ROOT')
+if dts_root:
+    path.append(dts_root)
+    # DTS Sidebar config
+    html_theme_options = {
+        'collapse_navigation': False,
+        'navigation_depth': -1,
+    }
+
 stop_on_error = ('-W' in argv)
 
 project = 'Data Plane Development Kit'
@@ -35,8 +65,7 @@
 html_show_copyright = False
 highlight_language = 'none'
 
-release = environ.setdefault('DPDK_VERSION', "None")
-version = release
+version = environ.setdefault('DPDK_VERSION', "None")
 
 master_doc = 'index'
 
diff --git a/doc/guides/meson.build b/doc/guides/meson.build
index 51f81da2e3..8933d75f6b 100644
--- a/doc/guides/meson.build
+++ b/doc/guides/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Intel Corporation
 
+doc_guides_source_dir = meson.current_source_dir()
 sphinx = find_program('sphinx-build', required: get_option('enable_docs'))
 
 if not sphinx.found()
diff --git a/doc/guides/tools/dts.rst b/doc/guides/tools/dts.rst
index b6a3e1e791..49be2dbfa1 100644
--- a/doc/guides/tools/dts.rst
+++ b/doc/guides/tools/dts.rst
@@ -284,7 +284,12 @@ and try not to divert much from it.
 The :ref:`DTS developer tools <dts_dev_tools>` will issue warnings
 when some of the basics are not met.
 
-The code must be properly documented with docstrings.
+The API documentation, which is a helpful reference when developing, may be accessed
+in the code directly or generated with the :ref:`API docs build steps <building_api_docs>`.
+When adding new files or modifying the directory structure, the corresponding changes must
+be made to DTS api doc sources in ``dts/doc``.
+
+Speaking of which, the code must be properly documented with docstrings.
 The style must conform to the `Google style
 <https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings>`_.
 See an example of the style `here
@@ -413,3 +418,30 @@ There are three tools used in DTS to help with code checking, style and formatti
 These three tools are all used in ``devtools/dts-check-format.sh``,
 the DTS code check and format script.
 Refer to the script for usage: ``devtools/dts-check-format.sh -h``.
+
+
+.. _building_api_docs:
+
+Building DTS API docs
+---------------------
+
+To build DTS API docs, install the dependencies with Poetry, then enter its shell:
+
+.. code-block:: console
+
+   poetry install --with docs
+   poetry shell
+
+The documentation is built using the standard DPDK build system. After executing the meson command
+and entering Poetry's shell, build the documentation with:
+
+.. code-block:: console
+
+   ninja -C build dts-doc
+
+The output is generated in ``build/doc/api/dts/html``.
+
+.. Note::
+
+   Make sure to fix any Sphinx warnings when adding or updating docstrings. Also make sure to run
+   the ``devtools/dts-check-format.sh`` script and address any issues it finds.
diff --git a/dts/doc/meson.build b/dts/doc/meson.build
new file mode 100644
index 0000000000..01b7b51034
--- /dev/null
+++ b/dts/doc/meson.build
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2023 PANTHEON.tech s.r.o.
+
+sphinx = find_program('sphinx-build', required: false)
+sphinx_apidoc = find_program('sphinx-apidoc', required: false)
+
+if not sphinx.found() or not sphinx_apidoc.found()
+    subdir_done()
+endif
+
+dts_doc_api_build_dir = join_paths(doc_api_build_dir, 'dts')
+
+extra_sphinx_args = ['-E', '-c', doc_guides_source_dir, '--dts-root', dts_dir]
+if get_option('werror')
+    extra_sphinx_args += '-W'
+endif
+
+htmldir = join_paths(get_option('datadir'), 'doc', 'dpdk', 'dts')
+dts_api_html = custom_target('dts_api_html',
+        output: 'html',
+        command: [sphinx_wrapper, sphinx, meson.project_version(),
+            meson.current_source_dir(), dts_doc_api_build_dir, extra_sphinx_args],
+        build_by_default: false,
+        install: get_option('enable_docs'),
+        install_dir: htmldir)
+doc_targets += dts_api_html
+doc_target_names += 'DTS_API_HTML'
diff --git a/dts/meson.build b/dts/meson.build
new file mode 100644
index 0000000000..e8ce0f06ac
--- /dev/null
+++ b/dts/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2023 PANTHEON.tech s.r.o.
+
+doc_targets = []
+doc_target_names = []
+dts_dir = meson.current_source_dir()
+
+subdir('doc')
+
+if doc_targets.length() == 0
+    message = 'No docs targets found'
+else
+    message = 'Built docs:'
+endif
+run_target('dts-doc', command: [echo, message, doc_target_names],
+    depends: doc_targets)
diff --git a/meson.build b/meson.build
index 5e161f43e5..001fdcbbbf 100644
--- a/meson.build
+++ b/meson.build
@@ -87,6 +87,7 @@ subdir('app')
 
 # build docs
 subdir('doc')
+subdir('dts')
 
 # build any examples explicitly requested - useful for developers - and
 # install any example code into the appropriate install path
-- 
2.34.1


^ permalink raw reply	[relevance 2%]

* Re: [Bug 1368] inconsistency in eventdev dev_info and config structs makes some valid configs impossible
  2024-01-18 11:26  3% ` Bruce Richardson
@ 2024-01-18 13:21  0%   ` Bruce Richardson
  0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2024-01-18 13:21 UTC (permalink / raw)
  To: dev; +Cc: jerinj

On Thu, Jan 18, 2024 at 11:26:45AM +0000, Bruce Richardson wrote:
> On Thu, Jan 18, 2024 at 11:18:58AM +0000, bugzilla@dpdk.org wrote:
> >    Bug ID [1]1368
> >    Summary inconsistency in eventdev dev_info and config structs makes
> >    some valid configs impossible
> >    Product DPDK
> >    Version unspecified
> >    Hardware All
> >    OS All
> >    Status UNCONFIRMED
> >    Severity normal
> >    Priority Normal
> >    Component eventdev
> >    Assignee dev@dpdk.org
> >    Reporter bruce.richardson@intel.com
> >    Target Milestone ---
> > 
> > In the rte_event_dev_info struct[1], we have the max_event_queues[2] and
> > max_single_link_event_port_queue_pairs[3] members. The doxygen docs on the
> > latter states: "These ports and queues are not accounted for in
> > max_event_ports or max_event_queues."
> > 
> > This implies that a device which has 8 regular queues and an extra 8
> > single-link only queues, would report max_event_queues == 8, and
> > max_single_link_event_port_queue_pairs == 8 on return from
> > rte_event_dev_info_get() function.
> > 
> > Those values returned from info_get are generally to be used to guide the
> > configuration using rte_event_dev_configure() API, which takes the
> > rte_event_dev_config[4] struct. This has two similar fields, in
> > nb_event_queues[5] and nb_single_link_event_port_queues[6]. However, a
> > problem arises in that the documentation states that nb_event_queues cannot
> > be greater than the previously reported max_event_queues (which by itself
> > makes sense), but the documentation also states that
> > nb_single_link_event_port_queues is a subset of the overall event ports and
> > queues, and cannot be greater than the nb_event_queues given in the same
> > config structure.
> > 
> > To illustrate the issue by continuing to use the same example as above,
> > suppose an app wants to take that device with 8 regular queues and 8 single
> > link ones, and have an app with 2 shared processing queues, e.g. for
> > load-balancing packets/events among 8 cores, but also wants to use the 8
> > single link queues to allow sending packets/events directly to each core
> > without load balancing.  In this 2 + 8 scenario, there is no valid
> > dev_config struct settings that will work:
> > * making the 8 a subset of the nb_event_queues, means that nb_event_queues
> >   is 10, which is greater than max_event_queues and so invalid.
> > * keeping them separate, so that nb_event_queues == 2 and
> >   nb_single_link_port_queues == 8 violates the constraint that the
> >   single_link value cannot exceed the former nb_event_queues value.
> > 
> > We therefore need to adjust the constraints to make things work. Now we can
> > do so, while keeping the single_link value *not included* in the
> > total-count in dev_info, but have it *included* in the config struct, but
> > such a setup is very confusing for the user. Therefore, I think instead we
> > need to correct this by aligning the two structures - either the
> > single_link queues are included in the queue/port counts in both structs,
> > or they aren't included.
> > 
> 
> Since I'm doing some clean-up work on rte_eventdev.h doxygen comments, I'm
> happy enough to push a patch to help fix this, if we can agree on the
> solution.
> 
> Of the two possibilities (make both have single-link included in count, or
> make both have single-link not-included), I would suggest we go for having
> them included, on the basis that that would involve an internal DPDK change
> to increase the reported counts in dev_info from any drivers supporting
> single link queues, but should *not* involve any changes to end
> applications, which would already be specifying the values based on
> nb_single_link being a subset of nb_event_queues. On the other hand,
> changing semantics of the config struct fields would likely mean changes to
> end-apps and so be an ABI/API break.
> 
Checking the implementation in the eventdev.c file, I find that
(unsurprisingly) the implementation doesn't correspond to the
documentation. For the problematic configuration described above, it is
actually possible to implement, since the API checks that nb_event_queues
(and nb_event_ports) is < max_event_queues + max_single_link_queues.

I will patch the documentation in the header to reflect this, but I still
think we should look to change this in future as it's rather inconsistent.

Regards,
/Bruce

^ permalink raw reply	[relevance 0%]

* Re: [Bug 1368] inconsistency in eventdev dev_info and config structs makes some valid configs impossible
  @ 2024-01-18 11:26  3% ` Bruce Richardson
  2024-01-18 13:21  0%   ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2024-01-18 11:26 UTC (permalink / raw)
  To: dev; +Cc: jerinj

On Thu, Jan 18, 2024 at 11:18:58AM +0000, bugzilla@dpdk.org wrote:
>    Bug ID [1]1368
>    Summary inconsistency in eventdev dev_info and config structs makes
>    some valid configs impossible
>    Product DPDK
>    Version unspecified
>    Hardware All
>    OS All
>    Status UNCONFIRMED
>    Severity normal
>    Priority Normal
>    Component eventdev
>    Assignee dev@dpdk.org
>    Reporter bruce.richardson@intel.com
>    Target Milestone ---
> 
> In the rte_event_dev_info struct[1], we have the max_event_queues[2] and
> max_single_link_event_port_queue_pairs[3] members. The doxygen docs on the
> latter states: "These ports and queues are not accounted for in
> max_event_ports or max_event_queues."
> 
> This implies that a device which has 8 regular queues and an extra 8
> single-link only queues, would report max_event_queues == 8, and
> max_single_link_event_port_queue_pairs == 8 on return from
> rte_event_dev_info_get() function.
> 
> Those values returned from info_get are generally to be used to guide the
> configuration using rte_event_dev_configure() API, which takes the
> rte_event_dev_config[4] struct. This has two similar fields, in
> nb_event_queues[5] and nb_single_link_event_port_queues[6]. However, a
> problem arises in that the documentation states that nb_event_queues cannot
> be greater than the previously reported max_event_queues (which by itself
> makes sense), but the documentation also states that
> nb_single_link_event_port_queues is a subset of the overall event ports and
> queues, and cannot be greater than the nb_event_queues given in the same
> config structure.
> 
> To illustrate the issue by continuing to use the same example as above,
> suppose an app wants to take that device with 8 regular queues and 8 single
> link ones, and have an app with 2 shared processing queues, e.g. for
> load-balancing packets/events among 8 cores, but also wants to use the 8
> single link queues to allow sending packets/events directly to each core
> without load balancing.  In this 2 + 8 scenario, there is no valid
> dev_config struct settings that will work:
> * making the 8 a subset of the nb_event_queues, means that nb_event_queues
>   is 10, which is greater than max_event_queues and so invalid.
> * keeping them separate, so that nb_event_queues == 2 and
>   nb_single_link_port_queues == 8 violates the constraint that the
>   single_link value cannot exceed the former nb_event_queues value.
> 
> We therefore need to adjust the constraints to make things work. Now we can
> do so, while keeping the single_link value *not included* in the
> total-count in dev_info, but have it *included* in the config struct, but
> such a setup is very confusing for the user. Therefore, I think instead we
> need to correct this by aligning the two structures - either the
> single_link queues are included in the queue/port counts in both structs,
> or they aren't included.
> 

Since I'm doing some clean-up work on rte_eventdev.h doxygen comments, I'm
happy enough to push a patch to help fix this, if we can agree on the
solution.

Of the two possibilities (make both have single-link included in count, or
make both have single-link not-included), I would suggest we go for having
them included, on the basis that that would involve an internal DPDK change
to increase the reported counts in dev_info from any drivers supporting
single link queues, but should *not* involve any changes to end
applications, which would already be specifying the values based on
nb_single_link being a subset of nb_event_queues. On the other hand,
changing semantics of the config struct fields would likely mean changes to
end-apps and so be an ABI/API break.

/Bruce

^ permalink raw reply	[relevance 3%]

* [dpdk-dev] [v2] ethdev: support Tx queue used count
                       ` (2 preceding siblings ...)
  2024-01-12 16:52  3%   ` Stephen Hemminger
@ 2024-01-18  9:47  3%   ` jerinj
  2024-01-22 13:00  0%     ` Konstantin Ananyev
  3 siblings, 1 reply; 200+ results
From: jerinj @ 2024-01-18  9:47 UTC (permalink / raw)
  To: dev, Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko
  Cc: ferruh.yigit, ajit.khaparde, aboyer, beilei.xing,
	bruce.richardson, chas3, chenbo.xia, ciara.loftus, dsinghrawat,
	ed.czeck, evgenys, grive, g.singh, zhouguoyang, haiyue.wang,
	hkalra, heinrich.kuhn, hemant.agrawal, hyonkim, igorch,
	irusskikh, jgrajcia, jasvinder.singh, jianwang, jiawenwu,
	jingjing.wu, johndale, john.miller, linville, keith.wiles,
	kirankumark, oulijun, lironh, longli, mw, spinler, matan,
	matt.peters, maxime.coquelin, mk, humin29, pnalla, ndabilpuram,
	qiming.yang, qi.z.zhang, radhac, rahul.lakkireddy, rmody,
	rosen.xu, sachin.saxena, skoteshwar, shshaikh, shaibran,
	shepard.siegel, asomalap, somnath.kotur, sthemmin,
	steven.webster, skori, mtetsuyah, vburru, viacheslavo,
	xiao.w.wang, cloud.wangxiaoyun, yisen.zhuang, yongwang,
	xuanziyang2, cristian.dumitrescu, Jerin Jacob,
	Morten Brørup

From: Jerin Jacob <jerinj@marvell.com>

Introduce a new API to retrieve the number of used descriptors
in a Tx queue. Applications can leverage this API in the fast path to
inspect the Tx queue occupancy and take appropriate actions based on the
available free descriptors.

A notable use case could be implementing Random Early Discard (RED)
in software based on Tx queue occupancy.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Acked-by: Morten Brørup <mb@smartsharesystems.com>
---
 devtools/libabigail.abignore           |  3 +
 doc/guides/nics/features.rst           | 10 ++++
 doc/guides/nics/features/default.ini   |  1 +
 doc/guides/rel_notes/release_24_03.rst |  5 ++
 lib/ethdev/ethdev_driver.h             |  2 +
 lib/ethdev/ethdev_private.c            |  1 +
 lib/ethdev/ethdev_trace_points.c       |  3 +
 lib/ethdev/rte_ethdev.h                | 80 ++++++++++++++++++++++++++
 lib/ethdev/rte_ethdev_core.h           |  7 ++-
 lib/ethdev/rte_ethdev_trace_fp.h       |  8 +++
 lib/ethdev/version.map                 |  1 +
 11 files changed, 120 insertions(+), 1 deletion(-)

v2:
- Rename _nic_features_tx_queue_used_count to _nic_features_tx_queue_count 
- Fix trace emission of case fops->tx_queue_count == NULL
- Rename tx_queue_id to queue_id in implementation symbols and prints
- Added "goto out" for better error handling 
- Add release note
- Added libabigail suppression rule for the reserved2 field update
- Fix all ordering and grouping, empty line comment from Ferruh 
- Added following notes in doxygen documentation for better clarity on API usage
 * @note There is no requirement to call this function before rte_eth_tx_burst() invocation.
 * @note Utilize this function exclusively when the caller needs to determine the used queue count
 * across all descriptors of a Tx queue. If the use case only involves checking the status of a
 * specific descriptor slot, opt for rte_eth_tx_descriptor_status() instead.

rfc..v1:
- Updated API similar to rte_eth_rx_queue_count() where it returns
"used" count instead of "free" count

diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index 21b8cd6113..d6e98c6f52 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -33,3 +33,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Temporary exceptions till next major ABI version ;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+[suppress_type]
+	name = rte_eth_fp_ops
+	has_data_member_inserted_between = {offset_of(reserved2), end}
diff --git a/doc/guides/nics/features.rst b/doc/guides/nics/features.rst
index f7d9980849..f38941c719 100644
--- a/doc/guides/nics/features.rst
+++ b/doc/guides/nics/features.rst
@@ -697,6 +697,16 @@ or "Unavailable."
 * **[related]    API**: ``rte_eth_tx_descriptor_status()``.
 
 
+.. _nic_features_tx_queue_count:
+
+Tx queue count
+--------------
+
+Supports to get the number of used descriptors of a Tx queue.
+
+* **[implements] eth_dev_ops**: ``tx_queue_count``.
+* **[related] API**: ``rte_eth_tx_queue_count()``.
+
 .. _nic_features_basic_stats:
 
 Basic stats
diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
index 6d50236292..5115963136 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -59,6 +59,7 @@ Packet type parsing  =
 Timesync             =
 Rx descriptor status =
 Tx descriptor status =
+Tx queue count       =
 Basic stats          =
 Extended stats       =
 Stats per queue      =
diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index c4fc8ad583..16dd367178 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -65,6 +65,11 @@ New Features
   * Added ``RTE_FLOW_ITEM_TYPE_RANDOM`` to match random value.
   * Added ``RTE_FLOW_FIELD_RANDOM`` to represent it in field ID struct.
 
+* ** Support for getting the number of used descriptors of a Tx queue. **
+
+  * Added a fath path function ``rte_eth_tx_queue_count`` to get the number of used
+    descriptors of a Tx queue.
+
 
 Removed Items
 -------------
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index b482cd12bb..f05f68a67c 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -58,6 +58,8 @@ struct rte_eth_dev {
 	eth_rx_queue_count_t rx_queue_count;
 	/** Check the status of a Rx descriptor */
 	eth_rx_descriptor_status_t rx_descriptor_status;
+	/** Get the number of used Tx descriptors */
+	eth_tx_queue_count_t tx_queue_count;
 	/** Check the status of a Tx descriptor */
 	eth_tx_descriptor_status_t tx_descriptor_status;
 	/** Pointer to PMD transmit mbufs reuse function */
diff --git a/lib/ethdev/ethdev_private.c b/lib/ethdev/ethdev_private.c
index a656df293c..626524558a 100644
--- a/lib/ethdev/ethdev_private.c
+++ b/lib/ethdev/ethdev_private.c
@@ -273,6 +273,7 @@ eth_dev_fp_ops_setup(struct rte_eth_fp_ops *fpo,
 	fpo->tx_pkt_prepare = dev->tx_pkt_prepare;
 	fpo->rx_queue_count = dev->rx_queue_count;
 	fpo->rx_descriptor_status = dev->rx_descriptor_status;
+	fpo->tx_queue_count = dev->tx_queue_count;
 	fpo->tx_descriptor_status = dev->tx_descriptor_status;
 	fpo->recycle_tx_mbufs_reuse = dev->recycle_tx_mbufs_reuse;
 	fpo->recycle_rx_descriptors_refill = dev->recycle_rx_descriptors_refill;
diff --git a/lib/ethdev/ethdev_trace_points.c b/lib/ethdev/ethdev_trace_points.c
index 91f71d868b..bd6dd4e78a 100644
--- a/lib/ethdev/ethdev_trace_points.c
+++ b/lib/ethdev/ethdev_trace_points.c
@@ -37,6 +37,9 @@ RTE_TRACE_POINT_REGISTER(rte_eth_trace_call_rx_callbacks,
 RTE_TRACE_POINT_REGISTER(rte_eth_trace_call_tx_callbacks,
 	lib.ethdev.call_tx_callbacks)
 
+RTE_TRACE_POINT_REGISTER(rte_eth_trace_tx_queue_count,
+	lib.ethdev.tx_queue_count)
+
 RTE_TRACE_POINT_REGISTER(rte_eth_trace_iterator_init,
 	lib.ethdev.iterator_init)
 
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index b7f52e03a5..2687c23fa6 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -6823,6 +6823,86 @@ rte_eth_recycle_mbufs(uint16_t rx_port_id, uint16_t rx_queue_id,
 __rte_experimental
 int rte_eth_buffer_split_get_supported_hdr_ptypes(uint16_t port_id, uint32_t *ptypes, int num);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Get the number of used descriptors of a Tx queue
+ *
+ * This function retrieves the number of used descriptors of a transmit queue.
+ * Applications can use this API in the fast path to inspect Tx queue occupancy and take
+ * appropriate actions based on the available free descriptors.
+ * An example action could be implementing the Random Early Discard (RED).
+ *
+ * Since it's a fast-path function, no check is performed on port_id and
+ * queue_id. The caller must therefore ensure that the port is enabled
+ * and the queue is configured and running.
+ *
+ * @param port_id
+ *   The port identifier of the device.
+ * @param queue_id
+ *   The index of the transmit queue.
+ *   The value must be in the range [0, nb_tx_queue - 1] previously supplied
+ *   to rte_eth_dev_configure().
+ * @return
+ *  The number of used descriptors in the specific queue, or:
+ *   - (-ENODEV) if *port_id* is invalid. Enabled only when RTE_ETHDEV_DEBUG_TX is enabled
+ *   - (-EINVAL) if *queue_id* is invalid. Enabled only when RTE_ETHDEV_DEBUG_TX is enabled
+ *   - (-ENOTSUP) if the device does not support this function.
+ *
+ * @note This function is designed for fast-path use.
+ * @note There is no requirement to call this function before rte_eth_tx_burst() invocation.
+ * @note Utilize this function exclusively when the caller needs to determine the used queue count
+ * across all descriptors of a Tx queue. If the use case only involves checking the status of a
+ * specific descriptor slot, opt for rte_eth_tx_descriptor_status() instead.
+ */
+
+__rte_experimental
+static inline int
+rte_eth_tx_queue_count(uint16_t port_id, uint16_t queue_id)
+{
+	struct rte_eth_fp_ops *fops;
+	void *qd;
+	int rc;
+
+#ifdef RTE_ETHDEV_DEBUG_TX
+	if (port_id >= RTE_MAX_ETHPORTS || !rte_eth_dev_is_valid_port(port_id)) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Invalid port_id=%u", port_id);
+		rc = -ENODEV;
+		goto out;
+	}
+
+	if (queue_id >= RTE_MAX_QUEUES_PER_PORT) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Invalid queue_id=%u for port_id=%u",
+				    queue_id, port_id);
+		rc = -EINVAL;
+		goto out;
+	}
+#endif
+
+	/* Fetch pointer to Tx queue data */
+	fops = &rte_eth_fp_ops[port_id];
+	qd = fops->txq.data[queue_id];
+
+#ifdef RTE_ETHDEV_DEBUG_TX
+	if (qd == NULL) {
+		RTE_ETHDEV_LOG_LINE(ERR, "Invalid queue_id=%u for port_id=%u",
+				    queue_id, port_id);
+		rc = -EINVAL;
+		goto out;
+	}
+#endif
+	if (fops->tx_queue_count == NULL) {
+		rc = -ENOTSUP;
+		goto out;
+	}
+
+	rc = fops->tx_queue_count(qd);
+
+out:
+	rte_eth_trace_tx_queue_count(port_id, queue_id, rc);
+	return rc;
+}
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/ethdev/rte_ethdev_core.h b/lib/ethdev/rte_ethdev_core.h
index 4bfaf79c6c..a18f242ca4 100644
--- a/lib/ethdev/rte_ethdev_core.h
+++ b/lib/ethdev/rte_ethdev_core.h
@@ -50,6 +50,9 @@ typedef uint32_t (*eth_rx_queue_count_t)(void *rxq);
 /** @internal Check the status of a Rx descriptor */
 typedef int (*eth_rx_descriptor_status_t)(void *rxq, uint16_t offset);
 
+/** @internal Get number of used descriptors on a transmit queue. */
+typedef int (*eth_tx_queue_count_t)(void *txq);
+
 /** @internal Check the status of a Tx descriptor */
 typedef int (*eth_tx_descriptor_status_t)(void *txq, uint16_t offset);
 
@@ -116,7 +119,9 @@ struct rte_eth_fp_ops {
 	eth_tx_descriptor_status_t tx_descriptor_status;
 	/** Copy used mbufs from Tx mbuf ring into Rx. */
 	eth_recycle_tx_mbufs_reuse_t recycle_tx_mbufs_reuse;
-	uintptr_t reserved2[2];
+	/** Get the number of used Tx descriptors. */
+	eth_tx_queue_count_t tx_queue_count;
+	uintptr_t reserved2[1];
 	/**@}*/
 
 } __rte_cache_aligned;
diff --git a/lib/ethdev/rte_ethdev_trace_fp.h b/lib/ethdev/rte_ethdev_trace_fp.h
index 186271c9ff..40b6e4756b 100644
--- a/lib/ethdev/rte_ethdev_trace_fp.h
+++ b/lib/ethdev/rte_ethdev_trace_fp.h
@@ -73,6 +73,14 @@ RTE_TRACE_POINT_FP(
 	rte_trace_point_emit_u64(count);
 )
 
+RTE_TRACE_POINT_FP(
+	rte_eth_trace_tx_queue_count,
+	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t queue_id, int rc),
+	rte_trace_point_emit_u16(port_id);
+	rte_trace_point_emit_u16(queue_id);
+	rte_trace_point_emit_int(rc);
+)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index a050baab0f..73a788d91a 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -319,6 +319,7 @@ EXPERIMENTAL {
 
 	# added in 24.03
 	rte_eth_find_rss_algo;
+	rte_eth_tx_queue_count;
 };
 
 INTERNAL {
-- 
2.43.0


^ permalink raw reply	[relevance 3%]

* [PATCH v2] bus/uacce: introduce UACCE bus
  2023-12-08  6:18  2% [PATCH] bus/uacce: introduce UACCE bus Chengwen Feng
  2024-01-15  8:14  0% ` lihuisong (C)
@ 2024-01-16  3:35  2% ` Chengwen Feng
  1 sibling, 0 replies; 200+ results
From: Chengwen Feng @ 2024-01-16  3:35 UTC (permalink / raw)
  To: thomas, dev; +Cc: tangkunshan, fanghao11, wangzhou1, zhangfei.gao, lihuisong

UACCE (Unified/User-space-access-intended Accelerator Framework) was
upstream to Linux kernel version 5.7, and it targets to provide Shared
Virtual Addressing (SVA) between accelerators and processes. So
accelerator can access any data structure of the main cpu. [1] for more
information.

This commit introduces UACCE bus, so that the accelerator devices could
seen at DPDK and could be further registered such as a compress, crypto,
dma and ethdev device.

[1] https://docs.kernel.org/misc-devices/uacce.html

Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Acked-by: Zhangfei Gao <zhangfei.gao@linaro.org>
Acked-by: Huisong Li <lihuisong@huawei.com>

---
v2: Address Huisong's comments.
    Replace mmap/munmap with rte_mem_map/rte_mem_unmap.
    Refine rte_uacce_avail_queues()'s return value descriptor.
    Refine impl of removing last new line character.
    Adjust copyright start with 2024.

---
 MAINTAINERS                            |   4 +
 doc/guides/rel_notes/release_24_03.rst |   6 +
 drivers/bus/meson.build                |   1 +
 drivers/bus/uacce/bus_uacce_driver.h   | 254 +++++++++
 drivers/bus/uacce/meson.build          |  12 +
 drivers/bus/uacce/uacce.c              | 701 +++++++++++++++++++++++++
 drivers/bus/uacce/version.map          |  15 +
 7 files changed, 993 insertions(+)
 create mode 100644 drivers/bus/uacce/bus_uacce_driver.h
 create mode 100644 drivers/bus/uacce/meson.build
 create mode 100644 drivers/bus/uacce/uacce.c
 create mode 100644 drivers/bus/uacce/version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index 0d1c8126e3..89711029d5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -604,6 +604,10 @@ Platform bus driver
 M: Tomasz Duszynski <tduszynski@marvell.com>
 F: drivers/bus/platform/
 
+UACCE bus driver
+M: Chengwen Feng <fengchengwen@huawei.com>
+F: drivers/bus/uacce/
+
 VDEV bus driver
 F: drivers/bus/vdev/
 F: app/test/test_vdev.c
diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 6f8ad27808..96ecaec150 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -55,6 +55,12 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Added HiSilicon UACCE bus support.**
+
+  UACCE (Unified/User-space-access-intended Accelerator Framework) bus driver
+  has been added, so that the accelerator devices could seen at DPDK and could
+  be further registered such as a compress, crypto, dma and ethdev device.
+
 
 Removed Items
 -------------
diff --git a/drivers/bus/meson.build b/drivers/bus/meson.build
index a78b4283bf..d67db8576b 100644
--- a/drivers/bus/meson.build
+++ b/drivers/bus/meson.build
@@ -9,6 +9,7 @@ drivers = [
         'ifpga',
         'pci',
         'platform',
+        'uacce',
         'vdev',
         'vmbus',
 ]
diff --git a/drivers/bus/uacce/bus_uacce_driver.h b/drivers/bus/uacce/bus_uacce_driver.h
new file mode 100644
index 0000000000..c8e177d44f
--- /dev/null
+++ b/drivers/bus/uacce/bus_uacce_driver.h
@@ -0,0 +1,254 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 HiSilicon Limited
+ */
+
+#ifndef BUS_UACCE_DRIVER_H
+#define BUS_UACCE_DRIVER_H
+
+/**
+ * @file
+ *
+ * HiSilicon UACCE bus interface.
+ */
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <linux/types.h>
+
+#include <rte_compat.h>
+#include <rte_devargs.h>
+#include <dev_driver.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define RTE_UACCE_DEV_PATH_SIZE		256
+#define RTE_UACCE_API_NAME_SIZE		64
+#define RTE_UACCE_ALGS_NAME_SIZE	384
+#define RTE_UACCE_ATTR_MAX_SIZE		384
+
+/*
+ * Definition for queue file region type.
+ */
+enum rte_uacce_qfrt {
+	RTE_UACCE_QFRT_MMIO = 0, /**< Device mmio region. */
+	RTE_UACCE_QFRT_DUS,      /**< Device user share region. */
+	RTE_UACCE_QFRT_BUTT
+};
+
+struct rte_uacce_driver;
+
+/**
+ * A structure describing a UACCE device.
+ */
+struct rte_uacce_device {
+	RTE_TAILQ_ENTRY(rte_uacce_device) next;  /**< Next in device list. */
+	struct rte_device device;                /**< Inherit core device. */
+	struct rte_uacce_driver *driver;         /**< Driver used in probing. */
+	char name[RTE_DEV_NAME_MAX_LEN];         /**< Device name. */
+	char dev_root[RTE_UACCE_DEV_PATH_SIZE];  /**< Sysfs path with device name. */
+	char cdev_path[RTE_UACCE_DEV_PATH_SIZE]; /**< Device path in devfs. */
+	char api[RTE_UACCE_API_NAME_SIZE];       /**< Device context type. */
+	char algs[RTE_UACCE_ALGS_NAME_SIZE];     /**< Device supported algorithms. */
+	uint32_t flags;                          /**< Device flags. */
+	int numa_node;                           /**< NUMA node connection, -1 if unknown. */
+	uint32_t qfrt_sz[RTE_UACCE_QFRT_BUTT];   /**< Queue file region type's size. */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_uacce_device.
+ */
+#define RTE_DEV_TO_UACCE_DEV(ptr) \
+	container_of(ptr, struct rte_uacce_device, device)
+
+#define RTE_DEV_TO_UACCE_DEV_CONST(ptr) \
+	container_of(ptr, const struct rte_uacce_device, device)
+
+/**
+ * A structure describing an ID for a UACCE driver. Each driver provides a
+ * table of these IDs for each device that it supports.
+ */
+struct rte_uacce_id {
+	const char *dev_api;   /**< Device context type. */
+	/** Device algorithm.
+	 * If this field is NULL, only dev_api is matched. Otherwise, in
+	 * addition to match dev_api, dev_alg must be a subset of device's
+	 * algs.
+	 */
+	const char *dev_alg;
+};
+
+/**
+ * Initialization function for the driver called during probing.
+ */
+typedef int (rte_uacce_probe_t)(struct rte_uacce_driver *, struct rte_uacce_device *);
+
+/**
+ * Uninitialization function for the driver called during hotplugging.
+ */
+typedef int (rte_uacce_remove_t)(struct rte_uacce_device *);
+
+/**
+ * A structure describing a UACCE driver.
+ */
+struct rte_uacce_driver {
+	RTE_TAILQ_ENTRY(rte_uacce_driver) next;	/**< Next in list. */
+	struct rte_driver driver;               /**< Inherit core driver. */
+	struct rte_uacce_bus *bus;              /**< UACCE bus reference. */
+	rte_uacce_probe_t *probe;               /**< Device probe function. */
+	rte_uacce_remove_t *remove;             /**< Device remove function. */
+	const struct rte_uacce_id *id_table;    /**< ID table, NULL terminated. */
+};
+
+/**
+ * Get available queue number.
+ *
+ * @param dev
+ *   A pointer to a rte_uacce_device structure describing the device
+ *   to use.
+ *
+ * @note The available queues on the device may changes dynamically,
+ * for examples, other process may alloc or free queues.
+ *
+ * @return
+ *   >=0 on success. Otherwise negative value is returned.
+ */
+__rte_internal
+int rte_uacce_avail_queues(struct rte_uacce_device *dev);
+
+/*
+ * The queue context for a UACCE queue.
+ */
+struct rte_uacce_qcontex {
+	int fd;                       /**< The file descriptor associated to the queue. */
+	struct rte_uacce_device *dev; /**< The device associated to the queue. */
+	void *qfrt_base[RTE_UACCE_QFRT_BUTT]; /**< The qfrt mmap's memory base. */
+};
+
+/**
+ * Alloc one queue.
+ *
+ * @param dev
+ *   A pointer to a rte_uacce_device structure describing the device to use.
+ * @param qctx
+ *   Pointer to queue context, which is used to store the queue information
+ *   that is successfully applied for.
+ *
+ * @return
+ *   0 on success. Otherwise negative value is returned.
+ */
+__rte_internal
+int rte_uacce_queue_alloc(struct rte_uacce_device *dev, struct rte_uacce_qcontex *qctx);
+
+/**
+ * Free one queue.
+ *
+ * @param qctx
+ *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
+ *
+ * @note Once the queue is freed, any operations on the queue (including
+ * control-plane and data-plane, and also read & write mmap region) are not
+ * allowed.
+ */
+__rte_internal
+void rte_uacce_queue_free(struct rte_uacce_qcontex *qctx);
+
+/**
+ * Start one queue.
+ *
+ * @param qctx
+ *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
+ *
+ * @return
+ *   0 on success. Otherwise negative value is returned.
+ */
+__rte_internal
+int rte_uacce_queue_start(struct rte_uacce_qcontex *qctx);
+
+/**
+ * Send ioctl command to one queue.
+ *
+ * @param qctx
+ *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
+ * @param cmd
+ *   ioctl command.
+ *   @note The nr must not conflict with the definition in Linux kerel:
+ *   include/uapi/misc/uacce/uacce.h. It is recommended that the driver
+ *   custom nr start from 64.
+ * @param arg
+ *   Command input & output buffer.
+ *
+ * @return
+ *   0 on success. Otherwise negative value is returned.
+ */
+__rte_internal
+int rte_uacce_queue_ioctl(struct rte_uacce_qcontex *qctx, unsigned long cmd, void *arg);
+
+/**
+ * Mmap queue file region.
+ *
+ * @param qctx
+ *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
+ * @param qfrt
+ *   The queue file region type. Must be RTE_UACCE_QFRT_MMIO or
+ *   RTE_UACCE_QFRT_DUS.
+ *
+ * @return
+ *   Non-NULL on success. Otherwise NULL is returned.
+ */
+__rte_internal
+void *rte_uacce_queue_mmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt);
+
+/**
+ * Unmap queue file region.
+ *
+ * @param qctx
+ *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
+ * @param qfrt
+ *   The queue file region type. Must be RTE_UACCE_QFRT_MMIO or
+ *   RTE_UACCE_QFRT_DUS.
+ *
+ * @return
+ *   Non-NULL on success. Otherwise NULL is returned.
+ */
+__rte_internal
+void rte_uacce_queue_unmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt);
+
+/**
+ * Register a UACCE driver.
+ *
+ * @param driver
+ *   A pointer to a rte_uacce_driver structure describing the driver to be
+ *   registered.
+ */
+__rte_internal
+void rte_uacce_register(struct rte_uacce_driver *driver);
+
+/**
+ * Unregister a UACCE driver.
+ *
+ * @param driver
+ *   A pointer to a rte_uacce_driver structure describing the driver to be
+ *   unregistered.
+ */
+__rte_internal
+void rte_uacce_unregister(struct rte_uacce_driver *driver);
+
+/**
+ * Helper for UACCE device registration from driver instance.
+ */
+#define RTE_PMD_REGISTER_UACCE(nm, uacce_drv) \
+		RTE_INIT(uacceinitfn_ ##nm) \
+		{\
+			(uacce_drv).driver.name = RTE_STR(nm);\
+			rte_uacce_register(&uacce_drv); \
+		} \
+		RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* BUS_UACCE_DRIVER_H */
diff --git a/drivers/bus/uacce/meson.build b/drivers/bus/uacce/meson.build
new file mode 100644
index 0000000000..a659d65f23
--- /dev/null
+++ b/drivers/bus/uacce/meson.build
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2024 HiSilicon Limited.
+
+if not is_linux
+    build = false
+    reason = 'only supported on Linux'
+endif
+
+sources = files('uacce.c')
+driver_sdk_headers += files('bus_uacce_driver.h')
+
+deps += ['kvargs']
diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
new file mode 100644
index 0000000000..8b666c4e30
--- /dev/null
+++ b/drivers/bus/uacce/uacce.c
@@ -0,0 +1,701 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 HiSilicon Limited
+ */
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <rte_bitops.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_eal_paging.h>
+#include <rte_errno.h>
+#include <rte_log.h>
+#include <rte_kvargs.h>
+#include <bus_driver.h>
+
+#include "bus_uacce_driver.h"
+
+#define UACCE_BUS_CLASS_PATH	"/sys/class/uacce"
+
+/* UACCE device flag of SVA. */
+#define UACCE_DEV_FLGA_SVA	RTE_BIT32(0)
+
+/* Support -a uacce:device-name when start DPDK application. */
+#define UACCE_DEV_PREFIX	"uacce:"
+
+/*
+ * Structure describing the UACCE bus.
+ */
+struct rte_uacce_bus {
+	struct rte_bus bus;		            /* Inherit the generic class. */
+	TAILQ_HEAD(, rte_uacce_device) device_list; /* List of devices. */
+	TAILQ_HEAD(, rte_uacce_driver) driver_list; /* List of drivers. */
+};
+
+/* Forward declaration of UACCE bus. */
+static struct rte_uacce_bus uacce_bus;
+
+enum uacce_params {
+	RTE_UACCE_PARAM_NAME,
+};
+
+static const char *const uacce_params_keys[] = {
+	[RTE_UACCE_PARAM_NAME] = "name",
+	NULL,
+};
+
+#define FOREACH_DEVICE_ON_UACCEBUS(p)	\
+		RTE_TAILQ_FOREACH(p, &uacce_bus.device_list, next)
+#define FOREACH_DRIVER_ON_UACCEBUS(p)	\
+		RTE_TAILQ_FOREACH(p, &uacce_bus.driver_list, next)
+
+extern int uacce_bus_logtype;
+#define UACCE_BUS_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, uacce_bus_logtype, "uacce: " fmt "\n", \
+		##args)
+#define UACCE_BUS_ERR(fmt, args...) UACCE_BUS_LOG(ERR, fmt, ##args)
+#define UACCE_BUS_WARN(fmt, args...) UACCE_BUS_LOG(WARNING, fmt, ##args)
+#define UACCE_BUS_INFO(fmt, args...) UACCE_BUS_LOG(INFO, fmt, ##args)
+#define UACCE_BUS_DEBUG(fmt, args...) UACCE_BUS_LOG(DEBUG, fmt, ##args)
+
+
+static struct rte_devargs *
+uacce_devargs_lookup(const char *dev_name)
+{
+	char name[RTE_UACCE_DEV_PATH_SIZE] = {0};
+	struct rte_devargs *devargs;
+
+	snprintf(name, sizeof(name), "%s%s", UACCE_DEV_PREFIX, dev_name);
+	RTE_EAL_DEVARGS_FOREACH("uacce", devargs) {
+		if (strcmp(devargs->name, name) == 0)
+			return devargs;
+	}
+
+	return NULL;
+}
+
+static bool
+uacce_ignore_device(const char *dev_name)
+{
+	struct rte_devargs *devargs = uacce_devargs_lookup(dev_name);
+
+	switch (uacce_bus.bus.conf.scan_mode) {
+	case RTE_BUS_SCAN_ALLOWLIST:
+		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
+			return false;
+		break;
+	case RTE_BUS_SCAN_UNDEFINED:
+	case RTE_BUS_SCAN_BLOCKLIST:
+		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
+			return false;
+		break;
+	}
+
+	return true;
+}
+
+/*
+ * Returns the number of bytes read (removed last newline) on success.
+ * Otherwise negative value is returned.
+ */
+static int
+uacce_read_attr(const char *dev_root, const char *attr, char *buf, uint32_t sz)
+{
+	char filename[PATH_MAX] = {0};
+	int ret;
+	int fd;
+
+	snprintf(filename, sizeof(filename), "%s/%s", dev_root, attr);
+	fd = open(filename, O_RDONLY, 0);
+	if (fd < 0) {
+		UACCE_BUS_ERR("failed to open %s", filename);
+		return -EIO;
+	}
+
+	ret = read(fd, buf, sz);
+	if (ret > 0) {
+		/* Remove the last new line character. */
+		if (buf[ret - 1] == '\n') {
+			buf[ret - 1] = '\0';
+			ret--;
+		}
+	}
+	if (ret <= 0) {
+		UACCE_BUS_ERR("failed to read %s", filename);
+		ret = -EIO;
+	}
+
+	close(fd);
+
+	return ret;
+}
+
+/* 0 on success. Otherwise negative value is returned. */
+static int
+uacce_read_attr_int(const char *dev_root, const char *attr, int *val)
+{
+	char buf[RTE_UACCE_ATTR_MAX_SIZE] = {0};
+	char *s = NULL;
+	int ret;
+
+	ret = uacce_read_attr(dev_root, attr, buf, sizeof(buf) - 1);
+	if (ret < 0)
+		return ret;
+
+	*val = strtol(buf, &s, 0);
+	if (s[0] != '\0') {
+		UACCE_BUS_ERR("read attr %s/%s expect an integer value", dev_root, attr);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* 0 on success. Otherwise negative value is returned. */
+static int
+uacce_read_attr_u32(const char *dev_root, const char *attr, uint32_t *val)
+{
+	char buf[RTE_UACCE_ATTR_MAX_SIZE] = {0};
+	char *s = NULL;
+	int ret;
+
+	ret = uacce_read_attr(dev_root, attr, buf, sizeof(buf) - 1);
+	if (ret < 0)
+		return ret;
+
+	*val = strtoul(buf, &s, 0);
+	if (s[0] != '\0') {
+		UACCE_BUS_ERR("read attr %s/%s expect an uint32 value", dev_root, attr);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+uacce_read_api(struct rte_uacce_device *dev)
+{
+	int ret = uacce_read_attr(dev->dev_root, "api", dev->api, sizeof(dev->api) - 1);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int
+uacce_read_algs(struct rte_uacce_device *dev)
+{
+	int ret = uacce_read_attr(dev->dev_root, "algorithms", dev->algs, sizeof(dev->algs) - 1);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int
+uacce_read_flags(struct rte_uacce_device *dev)
+{
+	return uacce_read_attr_u32(dev->dev_root, "flags", &dev->flags);
+}
+
+static void
+uacce_read_numa_node(struct rte_uacce_device *dev)
+{
+	int ret = uacce_read_attr_int(dev->dev_root, "device/numa_node", &dev->numa_node);
+	if (ret != 0) {
+		UACCE_BUS_WARN("read attr numa_node failed! set to default");
+		dev->numa_node = -1;
+	}
+}
+
+static int
+uacce_read_qfrt_sz(struct rte_uacce_device *dev)
+{
+	int ret = uacce_read_attr_u32(dev->dev_root, "region_mmio_size",
+				      &dev->qfrt_sz[RTE_UACCE_QFRT_MMIO]);
+	if (ret != 0)
+		return ret;
+	return uacce_read_attr_u32(dev->dev_root, "region_dus_size",
+				   &dev->qfrt_sz[RTE_UACCE_QFRT_DUS]);
+}
+
+static int
+uacce_verify(struct rte_uacce_device *dev)
+{
+	if (!(dev->flags & UACCE_DEV_FLGA_SVA)) {
+		UACCE_BUS_WARN("device %s don't support SVA, skip it!", dev->name);
+		return 1; /* >0 will skip this device. */
+	}
+
+	return 0;
+}
+
+/*
+ * Scan one UACCE sysfs entry, and fill the devices list from it.
+ * It reads api/algs/flags/numa_node/region-size (please refer Linux kernel:
+ * Documentation/ABI/testing/sysfs-driver-uacce) and stores them for later
+ * device-driver matching, driver init...
+ */
+static int
+uacce_scan_one(const char *dev_name)
+{
+	struct rte_uacce_device *dev;
+	int ret;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev)
+		return -ENOMEM;
+
+	dev->device.bus = &uacce_bus.bus;
+	dev->device.name = dev->name;
+	dev->device.devargs = uacce_devargs_lookup(dev_name);
+	snprintf(dev->name, sizeof(dev->name), "%s", dev_name);
+	snprintf(dev->dev_root, sizeof(dev->dev_root), "%s/%s",
+		 UACCE_BUS_CLASS_PATH, dev_name);
+	snprintf(dev->cdev_path, sizeof(dev->cdev_path), "/dev/%s", dev_name);
+
+	ret = uacce_read_api(dev);
+	if (ret != 0)
+		goto err;
+	ret = uacce_read_algs(dev);
+	if (ret != 0)
+		goto err;
+	ret = uacce_read_flags(dev);
+	if (ret != 0)
+		goto err;
+	uacce_read_numa_node(dev);
+	ret = uacce_read_qfrt_sz(dev);
+	if (ret != 0)
+		goto err;
+
+	ret = uacce_verify(dev);
+	if (ret != 0)
+		goto err;
+
+	TAILQ_INSERT_TAIL(&uacce_bus.device_list, dev, next);
+	return 0;
+
+err:
+	free(dev);
+	return ret;
+}
+
+static int
+uacce_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+
+	dir = opendir(UACCE_BUS_CLASS_PATH);
+	if (dir == NULL) {
+		UACCE_BUS_LOG(INFO, "open %s failed!", UACCE_BUS_CLASS_PATH);
+		return 0;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		if (strlen(e->d_name) >= RTE_DEV_NAME_MAX_LEN) {
+			UACCE_BUS_LOG(WARNING, "uacce device name %s too long, skip it!",
+				      e->d_name);
+			continue;
+		}
+
+		if (uacce_ignore_device(e->d_name))
+			continue;
+
+		if (uacce_scan_one(e->d_name) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
+static bool
+uacce_match(const struct rte_uacce_driver *dr, const struct rte_uacce_device *dev)
+{
+	const struct rte_uacce_id *id_table;
+	uint32_t len;
+	char *map;
+
+	for (id_table = dr->id_table; id_table->dev_api != NULL; id_table++) {
+		if (strcmp(id_table->dev_api, dev->api) != 0)
+			continue;
+
+		if (id_table->dev_alg == NULL)
+			return true;
+
+		/* The dev->algs's algrothims is separated by new line, for
+		 * example: dev->algs could be: aaa\nbbbb\ncc, which has three
+		 * algorithms: aaa, bbbb and cc.
+		 * The id_table->dev_alg should be a single algrithm, e.g. bbbb.
+		 */
+		map = strstr(dev->algs, id_table->dev_alg);
+		if (map == NULL)
+			continue;
+		if (map != dev->algs && map[-1] != '\n')
+			continue;
+		len = strlen(id_table->dev_alg);
+		if (map[len] != '\0' && map[len] != '\n')
+			continue;
+
+		return true;
+	}
+
+	return false;
+}
+
+static int
+uacce_probe_one_driver(struct rte_uacce_driver *dr, struct rte_uacce_device *dev)
+{
+	const char *dev_name = dev->name;
+	bool already_probed;
+	int ret;
+
+	if (!uacce_match(dr, dev))
+		/* Match of device and driver failed */
+		return 1;
+
+	already_probed = rte_dev_is_probed(&dev->device);
+	if (already_probed) {
+		UACCE_BUS_INFO("device %s is already probed", dev_name);
+		return -EEXIST;
+	}
+
+	UACCE_BUS_DEBUG("probe device %s using driver %s", dev_name, dr->driver.name);
+
+	ret = dr->probe(dr, dev);
+	if (ret != 0) {
+		UACCE_BUS_ERR("probe device %s with driver %s failed %d",
+			      dev_name, dr->driver.name, ret);
+	} else {
+		dev->device.driver = &dr->driver;
+		dev->driver = dr;
+		UACCE_BUS_DEBUG("probe device %s with driver %s success",
+				dev_name, dr->driver.name);
+	}
+
+	return ret;
+}
+
+static int
+uacce_probe_all_drivers(struct rte_uacce_device *dev)
+{
+	struct rte_uacce_driver *dr;
+	int rc;
+
+	FOREACH_DRIVER_ON_UACCEBUS(dr) {
+		rc = uacce_probe_one_driver(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return rc;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+
+	return 1;
+}
+
+static int
+uacce_probe(void)
+{
+	size_t probed = 0, failed = 0;
+	struct rte_uacce_device *dev;
+	int ret;
+
+	FOREACH_DEVICE_ON_UACCEBUS(dev) {
+		probed++;
+
+		ret = uacce_probe_all_drivers(dev);
+		if (ret < 0) {
+			UACCE_BUS_LOG(ERR, "Requested device %s cannot be used",
+				dev->name);
+			rte_errno = errno;
+			failed++;
+		}
+	}
+
+	return (probed && probed == failed) ? -1 : 0;
+}
+
+static int
+uacce_cleanup(void)
+{
+	struct rte_uacce_device *dev, *tmp_dev;
+	int error = 0;
+
+	RTE_TAILQ_FOREACH_SAFE(dev, &uacce_bus.device_list, next, tmp_dev) {
+		struct rte_uacce_driver *dr = dev->driver;
+		int ret = 0;
+
+		if (dr == NULL || dr->remove == NULL)
+			goto free;
+
+		ret = dr->remove(dev);
+		if (ret < 0) {
+			rte_errno = errno;
+			error = -1;
+		}
+		dev->driver = NULL;
+		dev->device.driver = NULL;
+
+free:
+		memset(dev, 0, sizeof(*dev));
+		free(dev);
+	}
+
+	return error;
+}
+
+static int
+uacce_plug(struct rte_device *dev)
+{
+	return uacce_probe_all_drivers(RTE_DEV_TO_UACCE_DEV(dev));
+}
+
+static int
+uacce_detach_dev(struct rte_uacce_device *dev)
+{
+	struct rte_uacce_driver *dr;
+	int ret = 0;
+
+	dr = dev->driver;
+
+	UACCE_BUS_DEBUG("detach device %s using driver: %s", dev->device.name, dr->driver.name);
+
+	if (dr->remove) {
+		ret = dr->remove(dev);
+		if (ret < 0)
+			return ret;
+	}
+
+	dev->driver = NULL;
+	dev->device.driver = NULL;
+
+	return 0;
+}
+
+static int
+uacce_unplug(struct rte_device *dev)
+{
+	struct rte_uacce_device *uacce_dev;
+	int ret;
+
+	uacce_dev = RTE_DEV_TO_UACCE_DEV(dev);
+	ret = uacce_detach_dev(uacce_dev);
+	if (ret == 0) {
+		TAILQ_REMOVE(&uacce_bus.device_list, uacce_dev, next);
+		rte_devargs_remove(dev->devargs);
+		free(uacce_dev);
+	}
+
+	return ret;
+}
+
+static struct rte_device *
+uacce_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,  const void *data)
+{
+	const struct rte_uacce_device *uacce_start;
+	struct rte_uacce_device *uacce_dev;
+
+	if (start != NULL) {
+		uacce_start = RTE_DEV_TO_UACCE_DEV_CONST(start);
+		uacce_dev = TAILQ_NEXT(uacce_start, next);
+	} else {
+		uacce_dev = TAILQ_FIRST(&uacce_bus.device_list);
+	}
+
+	while (uacce_dev != NULL) {
+		if (cmp(&uacce_dev->device, data) == 0)
+			return &uacce_dev->device;
+		uacce_dev = TAILQ_NEXT(uacce_dev, next);
+	}
+
+	return NULL;
+}
+
+static int
+uacce_parse(const char *name, void *addr)
+{
+	const char **out = addr;
+	int ret;
+
+	ret = strncmp(name, UACCE_DEV_PREFIX, strlen(UACCE_DEV_PREFIX));
+
+	if (ret == 0 && addr)
+		*out = name;
+
+	return ret;
+}
+
+static int
+uacce_dev_match(const struct rte_device *dev, const void *_kvlist)
+{
+	const char *key = uacce_params_keys[RTE_UACCE_PARAM_NAME];
+	const struct rte_kvargs *kvlist = _kvlist;
+	const char *name;
+
+	/* no kvlist arg, all devices match. */
+	if (kvlist == NULL)
+		return 0;
+
+	/* if key is present in kvlist and does not match, filter device. */
+	name = rte_kvargs_get(kvlist, key);
+	if (name != NULL && strcmp(name, dev->name))
+		return -1;
+
+	return 0;
+}
+
+static void *
+uacce_dev_iterate(const void *start, const char *str,
+		  const struct rte_dev_iterator *it __rte_unused)
+{
+	rte_bus_find_device_t find_device;
+	struct rte_kvargs *kvargs = NULL;
+	struct rte_device *dev;
+
+	if (str != NULL) {
+		kvargs = rte_kvargs_parse(str, uacce_params_keys);
+		if (kvargs == NULL) {
+			UACCE_BUS_ERR("cannot parse argument list %s", str);
+			return NULL;
+		}
+	}
+	find_device = uacce_bus.bus.find_device;
+	dev = find_device(start, uacce_dev_match, kvargs);
+	rte_kvargs_free(kvargs);
+	return dev;
+}
+
+int
+rte_uacce_avail_queues(struct rte_uacce_device *dev)
+{
+	int avails = 0;
+	int ret;
+
+	ret = uacce_read_attr_int(dev->dev_root, "available_instances", &avails);
+	if (ret == 0)
+		ret = avails;
+
+	return ret;
+}
+
+int
+rte_uacce_queue_alloc(struct rte_uacce_device *dev, struct rte_uacce_qcontex *qctx)
+{
+	memset(qctx, 0, sizeof(*qctx));
+
+	qctx->fd = open(dev->cdev_path, O_RDWR | O_CLOEXEC);
+	if (qctx->fd >= 0) {
+		qctx->dev = dev;
+		return 0;
+	}
+
+	return -EIO;
+}
+
+void
+rte_uacce_queue_free(struct rte_uacce_qcontex *qctx)
+{
+	if (qctx->fd >= 0)
+		close(qctx->fd);
+	memset(qctx, 0, sizeof(*qctx));
+	qctx->fd = -1;
+}
+
+int
+rte_uacce_queue_start(struct rte_uacce_qcontex *qctx)
+{
+#define UACCE_CMD_START_Q	_IO('W', 0)
+	return ioctl(qctx->fd, UACCE_CMD_START_Q);
+}
+
+int
+rte_uacce_queue_ioctl(struct rte_uacce_qcontex *qctx, unsigned long cmd, void *arg)
+{
+	if (arg == NULL)
+		return ioctl(qctx->fd, cmd);
+
+	return ioctl(qctx->fd, cmd, arg);
+}
+
+void *
+rte_uacce_queue_mmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt)
+{
+	size_t size = qctx->dev->qfrt_sz[qfrt];
+	off_t off = qfrt * getpagesize();
+	void *addr;
+
+	if (size == 0 || qctx->qfrt_base[qfrt] != NULL) {
+		UACCE_BUS_ERR("failed to mmap for %s, size is zero or already mmapped!",
+			      qctx->dev->name);
+		return NULL;
+	}
+
+	addr = rte_mem_map(NULL, size, RTE_PROT_READ | RTE_PROT_WRITE, RTE_MAP_SHARED,
+			   qctx->fd, off);
+	if (addr == NULL) {
+		UACCE_BUS_ERR("failed to mmap for %s, qfrt %d err %s!",
+			      qctx->dev->name, qfrt, rte_strerror(rte_errno));
+		return NULL;
+	}
+	qctx->qfrt_base[qfrt] = addr;
+
+	return addr;
+}
+
+void
+rte_uacce_queue_unmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt)
+{
+	if (qctx->qfrt_base[qfrt] != NULL) {
+		rte_mem_unmap(qctx->qfrt_base[qfrt], qctx->dev->qfrt_sz[qfrt]);
+		qctx->qfrt_base[qfrt] = NULL;
+	}
+}
+
+void
+rte_uacce_register(struct rte_uacce_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&uacce_bus.driver_list, driver, next);
+	driver->bus = &uacce_bus;
+}
+
+void
+rte_uacce_unregister(struct rte_uacce_driver *driver)
+{
+	TAILQ_REMOVE(&uacce_bus.driver_list, driver, next);
+	driver->bus = NULL;
+}
+
+static struct rte_uacce_bus uacce_bus = {
+	.bus = {
+		.scan = uacce_scan,
+		.probe = uacce_probe,
+		.cleanup = uacce_cleanup,
+		.plug = uacce_plug,
+		.unplug = uacce_unplug,
+		.find_device = uacce_find_device,
+		.parse = uacce_parse,
+		.dev_iterate = uacce_dev_iterate,
+	},
+	.device_list = TAILQ_HEAD_INITIALIZER(uacce_bus.device_list),
+	.driver_list = TAILQ_HEAD_INITIALIZER(uacce_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(uacce, uacce_bus.bus);
+RTE_LOG_REGISTER_DEFAULT(uacce_bus_logtype, NOTICE);
diff --git a/drivers/bus/uacce/version.map b/drivers/bus/uacce/version.map
new file mode 100644
index 0000000000..533b2ea0d8
--- /dev/null
+++ b/drivers/bus/uacce/version.map
@@ -0,0 +1,15 @@
+INTERNAL {
+	global:
+
+	rte_uacce_avail_queues;
+	rte_uacce_queue_alloc;
+	rte_uacce_queue_free;
+	rte_uacce_queue_ioctl;
+	rte_uacce_queue_mmap;
+	rte_uacce_queue_start;
+	rte_uacce_queue_unmap;
+	rte_uacce_register;
+	rte_uacce_unregister;
+
+	local: *;
+};
-- 
2.17.1


^ permalink raw reply	[relevance 2%]

* Re: [PATCH] bus/uacce: introduce UACCE bus
  2024-01-15  8:14  0% ` lihuisong (C)
@ 2024-01-15 11:43  0%   ` fengchengwen
  0 siblings, 0 replies; 200+ results
From: fengchengwen @ 2024-01-15 11:43 UTC (permalink / raw)
  To: lihuisong (C), dev
  Cc: tangkunshan@huawei.com >> Tangkunshan, Wangzhou (B),
	Thomas Monjalon

Hi Huisong,

On 2024/1/15 16:14, lihuisong (C) wrote:
> Hi chengwen,
> 
> lgtm,
> with below to changes,
> Acked-by: Huisong Li <lihuisong@huawei.com>
> 
> 
> 在 2023/12/8 14:18, Chengwen Feng 写道:
>> UACCE (Unified/User-space-access-intended Accelerator Framework) was
>> upstream to Linux kernel version 5.7, and it targets to provide Shared
>> Virtual Addressing (SVA) between accelerators and processes. So
>> accelerator can access any data structure of the main cpu. [1] for more
>> information.
>>
>> This commit introduces UACCE bus, so that the accelerator devices could
>> seen at DPDK and could be further registered as a compress, crypto, dma
>> and ethdev device.
>>
>> [1] https://docs.kernel.org/misc-devices/uacce.html
>>
>> Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
>> ---
>>   MAINTAINERS                          |   4 +
>>   drivers/bus/meson.build              |   1 +
>>   drivers/bus/uacce/bus_uacce_driver.h | 254 ++++++++++
>>   drivers/bus/uacce/meson.build        |  12 +
>>   drivers/bus/uacce/uacce.c            | 702 +++++++++++++++++++++++++++
>>   drivers/bus/uacce/version.map        |  15 +
>>   6 files changed, 988 insertions(+)
>>   create mode 100644 drivers/bus/uacce/bus_uacce_driver.h
>>   create mode 100644 drivers/bus/uacce/meson.build
>>   create mode 100644 drivers/bus/uacce/uacce.c
>>   create mode 100644 drivers/bus/uacce/version.map
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 0d1c8126e3..89711029d5 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -604,6 +604,10 @@ Platform bus driver
>>   M: Tomasz Duszynski <tduszynski@marvell.com>
>>   F: drivers/bus/platform/
>>   +UACCE bus driver
>> +M: Chengwen Feng <fengchengwen@huawei.com>
>> +F: drivers/bus/uacce/
>> +
>>   VDEV bus driver
>>   F: drivers/bus/vdev/
>>   F: app/test/test_vdev.c
>> diff --git a/drivers/bus/meson.build b/drivers/bus/meson.build
>> index a78b4283bf..d67db8576b 100644
>> --- a/drivers/bus/meson.build
>> +++ b/drivers/bus/meson.build
>> @@ -9,6 +9,7 @@ drivers = [
>>           'ifpga',
>>           'pci',
>>           'platform',
>> +        'uacce',
>>           'vdev',
>>           'vmbus',
>>   ]
>> diff --git a/drivers/bus/uacce/bus_uacce_driver.h b/drivers/bus/uacce/bus_uacce_driver.h
>> new file mode 100644
>> index 0000000000..0276154658
>> --- /dev/null
>> +++ b/drivers/bus/uacce/bus_uacce_driver.h
>> @@ -0,0 +1,254 @@
>> +/* SPDX-License-Identifier: BSD-3-Clause
>> + * Copyright(c) 2023 HiSilicon Limited
>> + */
>> +
>> +#ifndef BUS_UACCE_DRIVER_H
>> +#define BUS_UACCE_DRIVER_H
>> +
>> +/**
>> + * @file
>> + *
>> + * HiSilicon UACCE bus interface.
>> + */
>> +
>> +#include <inttypes.h>
>> +#include <stdlib.h>
>> +#include <linux/types.h>
>> +
>> +#include <rte_compat.h>
>> +#include <rte_devargs.h>
>> +#include <dev_driver.h>
>> +
>> +#ifdef __cplusplus
>> +extern "C" {
>> +#endif /* __cplusplus */
>> +
>> +#define RTE_UACCE_DEV_PATH_SIZE        256
>> +#define RTE_UACCE_API_NAME_SIZE        64
>> +#define RTE_UACCE_ALGS_NAME_SIZE    384
>> +#define RTE_UACCE_ATTR_MAX_SIZE        384
>> +
>> +/*
>> + * Definition for queue file region type.
>> + */
>> +enum rte_uacce_qfrt {
>> +    RTE_UACCE_QFRT_MMIO = 0, /**< Device mmio region. */
>> +    RTE_UACCE_QFRT_DUS,      /**< Device user share region. */
>> +    RTE_UACCE_QFRT_BUTT
>> +};
>> +
>> +struct rte_uacce_driver;
>> +
>> +/**
>> + * A structure describing a UACCE device.
>> + */
>> +struct rte_uacce_device {
>> +    RTE_TAILQ_ENTRY(rte_uacce_device) next;  /**< Next in device list. */
>> +    struct rte_device device;                /**< Inherit core device. */
>> +    struct rte_uacce_driver *driver;         /**< Driver used in probing. */
>> +    char name[RTE_DEV_NAME_MAX_LEN];         /**< Device name. */
>> +    char dev_root[RTE_UACCE_DEV_PATH_SIZE];  /**< Sysfs path with device name. */
>> +    char cdev_path[RTE_UACCE_DEV_PATH_SIZE]; /**< Device path in devfs. */
>> +    char api[RTE_UACCE_API_NAME_SIZE];       /**< Device context type. */
>> +    char algs[RTE_UACCE_ALGS_NAME_SIZE];     /**< Device supported algorithms. */
>> +    uint32_t flags;                          /**< Device flags. */
>> +    int numa_node;                           /**< NUMA node connection, -1 if unknown. */
>> +    uint32_t qfrt_sz[RTE_UACCE_QFRT_BUTT];   /**< Queue file region type's size. */
>> +};
>> +
>> +/**
>> + * @internal
>> + * Helper macro for drivers that need to convert to struct rte_uacce_device.
>> + */
>> +#define RTE_DEV_TO_UACCE_DEV(ptr) \
>> +    container_of(ptr, struct rte_uacce_device, device)
>> +
>> +#define RTE_DEV_TO_UACCE_DEV_CONST(ptr) \
>> +    container_of(ptr, const struct rte_uacce_device, device)
>> +
>> +/**
>> + * A structure describing an ID for a UACCE driver. Each driver provides a
>> + * table of these IDs for each device that it supports.
>> + */
>> +struct rte_uacce_id {
>> +    const char *dev_api;   /**< Device context type. */
>> +    /** Device algorithm.
>> +     * If this field is NULL, only dev_api is matched. Otherwise, in
>> +     * addition to match dev_api, dev_alg must be a subset of device's
>> +     * algs.
>> +     */
>> +    const char *dev_alg;
>> +};
>> +
>> +/**
>> + * Initialization function for the driver called during probing.
>> + */
>> +typedef int (rte_uacce_probe_t)(struct rte_uacce_driver *, struct rte_uacce_device *);
>> +
>> +/**
>> + * Uninitialization function for the driver called during hotplugging.
>> + */
>> +typedef int (rte_uacce_remove_t)(struct rte_uacce_device *);
>> +
>> +/**
>> + * A structure describing a UACCE driver.
>> + */
>> +struct rte_uacce_driver {
>> +    RTE_TAILQ_ENTRY(rte_uacce_driver) next;    /**< Next in list. */
>> +    struct rte_driver driver;               /**< Inherit core driver. */
>> +    struct rte_uacce_bus *bus;              /**< UACCE bus reference. */
>> +    rte_uacce_probe_t *probe;               /**< Device probe function. */
>> +    rte_uacce_remove_t *remove;             /**< Device remove function. */
>> +    const struct rte_uacce_id *id_table;    /**< ID table, NULL terminated. */
>> +};
>> +
>> +/**
>> + * Get available queue number.
>> + *
>> + * @param dev
>> + *   A pointer to a rte_uacce_device structure describing the device
>> + *   to use.
>> + *
>> + * @note The available queues on the device may changes dynamically,
>> + * for examples, other process may alloc or free queues.
>> + *
>> + * @return
>> + *   0 on success. Otherwise negative value is returned.
>> + */
>> +__rte_internal
>> +int rte_uacce_avail_queues(struct rte_uacce_device *dev);
>> +
>> +/*
>> + * The queue context for a UACCE queue.
>> + */
>> +struct rte_uacce_qcontex {
>> +    int fd;                       /**< The file descriptor associated to the queue. */
>> +    struct rte_uacce_device *dev; /**< The device associated to the queue. */
>> +    void *qfrt_base[RTE_UACCE_QFRT_BUTT]; /**< The qfrt mmap's memory base. */
>> +};
>> +
>> +/**
>> + * Alloc one queue.
>> + *
>> + * @param dev
>> + *   A pointer to a rte_uacce_device structure describing the device to use.
>> + * @param qctx
>> + *   Pointer to queue context, which is used to store the queue information
>> + *   that is successfully applied for.
>> + *
>> + * @return
>> + *   0 on success. Otherwise negative value is returned.
>> + */
>> +__rte_internal
>> +int rte_uacce_queue_alloc(struct rte_uacce_device *dev, struct rte_uacce_qcontex *qctx);
>> +
>> +/**
>> + * Free one queue.
>> + *
>> + * @param qctx
>> + *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
>> + *
>> + * @note Once the queue is freed, any operations on the queue (including
>> + * control-plane and data-plane, and also read & write mmap region) are not
>> + * allowed.
>> + */
>> +__rte_internal
>> +void rte_uacce_queue_free(struct rte_uacce_qcontex *qctx);
>> +
>> +/**
>> + * Start one queue.
>> + *
>> + * @param qctx
>> + *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
>> + *
>> + * @return
>> + *   0 on success. Otherwise negative value is returned.
>> + */
>> +__rte_internal
>> +int rte_uacce_queue_start(struct rte_uacce_qcontex *qctx);
>> +
>> +/**
>> + * Send ioctl command to one queue.
>> + *
>> + * @param qctx
>> + *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
>> + * @param cmd
>> + *   ioctl command.
>> + *   @note The nr must not conflict with the definition in Linux kerel:
>> + *   include/uapi/misc/uacce/uacce.h. It is recommended that the driver
>> + *   custom nr start from 64.
>> + * @param arg
>> + *   Command input & output buffer.
>> + *
>> + * @return
>> + *   0 on success. Otherwise negative value is returned.
>> + */
>> +__rte_internal
>> +int rte_uacce_queue_ioctl(struct rte_uacce_qcontex *qctx, unsigned long cmd, void *arg);
>> +
>> +/**
>> + * Mmap queue file region.
>> + *
>> + * @param qctx
>> + *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
>> + * @param qfrt
>> + *   The queue file region type. Must be RTE_UACCE_QFRT_MMIO or
>> + *   RTE_UACCE_QFRT_DUS.
>> + *
>> + * @return
>> + *   Non-NULL on success. Otherwise NULL is returned.
>> + */
>> +__rte_internal
>> +void *rte_uacce_queue_mmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt);
>> +
>> +/**
>> + * Unmap queue file region.
>> + *
>> + * @param qctx
>> + *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
>> + * @param qfrt
>> + *   The queue file region type. Must be RTE_UACCE_QFRT_MMIO or
>> + *   RTE_UACCE_QFRT_DUS.
>> + *
>> + * @return
>> + *   Non-NULL on success. Otherwise NULL is returned.
>> + */
>> +__rte_internal
>> +void rte_uacce_queue_unmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt);
>> +
>> +/**
>> + * Register a UACCE driver.
>> + *
>> + * @param driver
>> + *   A pointer to a rte_uacce_driver structure describing the driver to be
>> + *   registered.
>> + */
>> +__rte_internal
>> +void rte_uacce_register(struct rte_uacce_driver *driver);
>> +
>> +/**
>> + * Unregister a UACCE driver.
>> + *
>> + * @param driver
>> + *   A pointer to a rte_uacce_driver structure describing the driver to be
>> + *   unregistered.
>> + */
>> +__rte_internal
>> +void rte_uacce_unregister(struct rte_uacce_driver *driver);
>> +
>> +/**
>> + * Helper for UACCE device registration from driver instance.
>> + */
>> +#define RTE_PMD_REGISTER_UACCE(nm, uacce_drv) \
>> +        RTE_INIT(uacceinitfn_ ##nm) \
>> +        {\
>> +            (uacce_drv).driver.name = RTE_STR(nm);\
>> +            rte_uacce_register(&uacce_drv); \
>> +        } \
>> +        RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
>> +
>> +#ifdef __cplusplus
>> +}
>> +#endif /* __cplusplus */
>> +
>> +#endif /* BUS_UACCE_DRIVER_H */
>> diff --git a/drivers/bus/uacce/meson.build b/drivers/bus/uacce/meson.build
>> new file mode 100644
>> index 0000000000..b48d6db11a
>> --- /dev/null
>> +++ b/drivers/bus/uacce/meson.build
>> @@ -0,0 +1,12 @@
>> +# SPDX-License-Identifier: BSD-3-Clause
>> +# Copyright(c) 2023 HiSilicon Limited.
>> +
>> +if not is_linux
>> +    build = false
>> +    reason = 'only supported on Linux'
>> +endif
>> +
>> +sources = files('uacce.c')
>> +driver_sdk_headers += files('bus_uacce_driver.h')
>> +
>> +deps += ['kvargs']
>> diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
>> new file mode 100644
>> index 0000000000..8e824c44df
>> --- /dev/null
>> +++ b/drivers/bus/uacce/uacce.c
>> @@ -0,0 +1,702 @@
>> +/* SPDX-License-Identifier: BSD-3-Clause
>> + * Copyright(c) 2023 HiSilicon Limited
>> + */
>> +
>> +#include <dirent.h>
>> +#include <errno.h>
>> +#include <fcntl.h>
>> +#include <unistd.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +#include <sys/ioctl.h>
>> +#include <sys/mman.h>
>> +#include <sys/stat.h>
>> +#include <sys/types.h>
>> +
>> +#include <rte_bitops.h>
>> +#include <rte_common.h>
>> +#include <rte_devargs.h>
>> +#include <rte_errno.h>
>> +#include <rte_log.h>
>> +#include <rte_kvargs.h>
>> +#include <bus_driver.h>
>> +
>> +#include "bus_uacce_driver.h"
>> +
>> +#define UACCE_BUS_CLASS_PATH    "/sys/class/uacce"
>> +
>> +/* UACCE device flag of SVA. */
>> +#define UACCE_DEV_FLGA_SVA    RTE_BIT32(0)
>> +
>> +/* Support -a uacce:device-name when start DPDK application. */
>> +#define UACCE_DEV_PREFIX    "uacce:"
>> +
>> +/*
>> + * Structure describing the UACCE bus.
>> + */
>> +struct rte_uacce_bus {
>> +    struct rte_bus bus;                    /* Inherit the generic class. */
>> +    TAILQ_HEAD(, rte_uacce_device) device_list; /* List of devices. */
>> +    TAILQ_HEAD(, rte_uacce_driver) driver_list; /* List of drivers. */
>> +};
>> +
>> +/* Forward declaration of UACCE bus. */
>> +static struct rte_uacce_bus uacce_bus;
>> +
>> +enum uacce_params {
>> +    RTE_UACCE_PARAM_NAME,
>> +};
>> +
>> +static const char *const uacce_params_keys[] = {
>> +    [RTE_UACCE_PARAM_NAME] = "name",
>> +    NULL,
>> +};
>> +
>> +#define FOREACH_DEVICE_ON_UACCEBUS(p)    \
>> +        RTE_TAILQ_FOREACH(p, &uacce_bus.device_list, next)
>> +#define FOREACH_DRIVER_ON_UACCEBUS(p)    \
>> +        RTE_TAILQ_FOREACH(p, &uacce_bus.driver_list, next)
>> +
>> +extern int uacce_bus_logtype;
>> +#define UACCE_BUS_LOG(level, fmt, args...) \
>> +    rte_log(RTE_LOG_ ## level, uacce_bus_logtype, "uacce: " fmt "\n", \
>> +        ##args)
>> +#define UACCE_BUS_ERR(fmt, args...) UACCE_BUS_LOG(ERR, fmt, ##args)
>> +#define UACCE_BUS_WARN(fmt, args...) UACCE_BUS_LOG(WARNING, fmt, ##args)
>> +#define UACCE_BUS_INFO(fmt, args...) UACCE_BUS_LOG(INFO, fmt, ##args)
>> +#define UACCE_BUS_DEBUG(fmt, args...) UACCE_BUS_LOG(DEBUG, fmt, ##args)
>> +
>> +
>> +static struct rte_devargs *
>> +uacce_devargs_lookup(const char *dev_name)
>> +{
>> +    char name[RTE_UACCE_DEV_PATH_SIZE] = {0};
>> +    struct rte_devargs *devargs;
>> +
>> +    snprintf(name, sizeof(name), "%s%s", UACCE_DEV_PREFIX, dev_name);
>> +    RTE_EAL_DEVARGS_FOREACH("uacce", devargs) {
>> +        if (strcmp(devargs->name, name) == 0)
>> +            return devargs;
>> +    }
>> +
>> +    return NULL;
>> +}
>> +
>> +static bool
>> +uacce_ignore_device(const char *dev_name)
>> +{
>> +    struct rte_devargs *devargs = uacce_devargs_lookup(dev_name);
>> +
>> +    switch (uacce_bus.bus.conf.scan_mode) {
>> +    case RTE_BUS_SCAN_ALLOWLIST:
>> +        if (devargs && devargs->policy == RTE_DEV_ALLOWED)
>> +            return false;
>> +        break;
>> +    case RTE_BUS_SCAN_UNDEFINED:
>> +    case RTE_BUS_SCAN_BLOCKLIST:
>> +        if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
>> +            return false;
>> +        break;
>> +    }
>> +
>> +    return true;
>> +}
>> +
>> +/*
>> + * Returns the number of bytes read (removed last newline) on success.
>> + * Otherwise negative value is returned.
>> + */
>> +static int
>> +uacce_read_attr(const char *dev_root, const char *attr, char *buf, uint32_t sz)
>> +{
>> +    char filename[PATH_MAX] = {0};
>> +    int ret;
>> +    int fd;
>> +    int i;
>> +
>> +    snprintf(filename, sizeof(filename), "%s/%s", dev_root, attr);
>> +    fd = open(filename, O_RDONLY, 0);
>> +    if (fd < 0) {
>> +        UACCE_BUS_ERR("failed to open %s", filename);
>> +        return -EIO;
>> +    }
>> +
>> +    ret = read(fd, buf, sz);
>> +    if (ret > 0) {
>> +        /* Remove the last new line character. */
>> +        for (i = ret - 1; i >= 0; i--) {
>> +            if (buf[i] == '\n') {
>> +                buf[i] = '\0';
>> +                ret--;
>> +                break;
>> +            }
>> +        }
>> +    }
>> +    if (ret <= 0) {
> close(fd) is also needed here.

ack

>> +        UACCE_BUS_ERR("failed to read %s", filename);
>> +        return -EIO;
>> +    }
>> +
>> +    close(fd);
>> +
>> +    return ret;
>> +}
>> +
>> +/* 0 on success. Otherwise negative value is returned. */
>> +static int
>> +uacce_read_attr_int(const char *dev_root, const char *attr, int *val)
>> +{
>> +    char buf[RTE_UACCE_ATTR_MAX_SIZE] = {0};
>> +    char *s = NULL;
>> +    int ret;
>> +
>> +    ret = uacce_read_attr(dev_root, attr, buf, sizeof(buf) - 1);
>> +    if (ret < 0)
>> +        return ret;
>> +
>> +    *val = strtol(buf, &s, 0);
>> +    if (s[0] != '\0') {
>> +        UACCE_BUS_ERR("read attr %s/%s expect an integer value", dev_root, attr);
>> +        return -EINVAL;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +/* 0 on success. Otherwise negative value is returned. */
>> +static int
>> +uacce_read_attr_u32(const char *dev_root, const char *attr, uint32_t *val)
>> +{
>> +    char buf[RTE_UACCE_ATTR_MAX_SIZE] = {0};
>> +    char *s = NULL;
>> +    int ret;
>> +
>> +    ret = uacce_read_attr(dev_root, attr, buf, sizeof(buf) - 1);
>> +    if (ret < 0)
>> +        return ret;
>> +
>> +    *val = strtoul(buf, &s, 0);
>> +    if (s[0] != '\0') {
>> +        UACCE_BUS_ERR("read attr %s/%s expect an uint32 value", dev_root, attr);
>> +        return -EINVAL;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static int
>> +uacce_read_api(struct rte_uacce_device *dev)
>> +{
>> +    int ret = uacce_read_attr(dev->dev_root, "api", dev->api, sizeof(dev->api) - 1);
>> +    if (ret < 0)
>> +        return ret;
>> +    return 0;
> Could you use return uacce_read_attr()? it is more concise.

This function should return zero when success. and uacce_read_attr will return readed bytes after read.
So it need to convert like above.

>> +}
>> +
>> +static int
>> +uacce_read_algs(struct rte_uacce_device *dev)
>> +{
>> +    int ret = uacce_read_attr(dev->dev_root, "algorithms", dev->algs, sizeof(dev->algs) - 1);
>> +    if (ret < 0)
>> +        return ret;
>> +    return 0;
> return uacce_read_attr()

same as above reason.

>> +}
>> +
>> +static int
>> +uacce_read_flags(struct rte_uacce_device *dev)
>> +{
>> +    return uacce_read_attr_u32(dev->dev_root, "flags", &dev->flags);
>> +}
>> +
>> +static void
>> +uacce_read_numa_node(struct rte_uacce_device *dev)
>> +{
>> +    int ret = uacce_read_attr_int(dev->dev_root, "device/numa_node", &dev->numa_node);
>> +    if (ret != 0) {
>> +        UACCE_BUS_WARN("read attr numa_node failed! set to default");
>> +        dev->numa_node = -1;
>> +    }
>> +}
>> +
>> +static int
>> +uacce_read_qfrt_sz(struct rte_uacce_device *dev)
>> +{
>> +    int ret = uacce_read_attr_u32(dev->dev_root, "region_mmio_size",
>> +                      &dev->qfrt_sz[RTE_UACCE_QFRT_MMIO]);
>> +    if (ret != 0)
>> +        return ret;
>> +    return uacce_read_attr_u32(dev->dev_root, "region_dus_size",
>> +                   &dev->qfrt_sz[RTE_UACCE_QFRT_DUS]);
>> +}
>> +
>> +static int
>> +uacce_verify(struct rte_uacce_device *dev)
>> +{
>> +    if (!(dev->flags & UACCE_DEV_FLGA_SVA)) {
>> +        UACCE_BUS_WARN("device %s don't support SVA, skip it!", dev->name);
>> +        return 1; /* >0 will skip this device. */
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +/*
>> + * Scan one UACCE sysfs entry, and fill the devices list from it.
>> + * It reads api/algs/flags/numa_node/region-size (please refer Linux kernel:
>> + * Documentation/ABI/testing/sysfs-driver-uacce) and stores them for later
>> + * device-driver matching, driver init...
>> + */
>> +static int
>> +uacce_scan_one(const char *dev_name)
>> +{
>> +    struct rte_uacce_device *dev = NULL;
> This assignment for dev is redundant.

ack

>> +    int ret;
>> +
>> +    dev = calloc(1, sizeof(*dev));
>> +    if (!dev)
>> +        return -ENOMEM;
>> +
>> +    dev->device.bus = &uacce_bus.bus;
>> +    dev->device.name = dev->name;
>> +    dev->device.devargs = uacce_devargs_lookup(dev_name);
>> +    snprintf(dev->name, sizeof(dev->name), "%s", dev_name);
>> +    snprintf(dev->dev_root, sizeof(dev->dev_root), "%s/%s",
>> +         UACCE_BUS_CLASS_PATH, dev_name);
>> +    snprintf(dev->cdev_path, sizeof(dev->cdev_path), "/dev/%s", dev_name);
>> +
>> +    ret = uacce_read_api(dev);
>> +    if (ret != 0)
>> +        goto err;
>> +    ret = uacce_read_algs(dev);
>> +    if (ret != 0)
>> +        goto err;
>> +    ret = uacce_read_flags(dev);
>> +    if (ret != 0)
>> +        goto err;
>> +    uacce_read_numa_node(dev);
>> +    ret = uacce_read_qfrt_sz(dev);
>> +    if (ret != 0)
>> +        goto err;
>> +
>> +    ret = uacce_verify(dev);
>> +    if (ret != 0)
>> +        goto err;
>> +
>> +    TAILQ_INSERT_TAIL(&uacce_bus.device_list, dev, next);
>> +    return 0;
>> +
>> +err:
>> +    free(dev);
>> +    return ret;
>> +}
>> +
>> +static int
>> +uacce_scan(void)
>> +{
>> +    struct dirent *e;
>> +    DIR *dir;
>> +
>> +    dir = opendir(UACCE_BUS_CLASS_PATH);
>> +    if (dir == NULL) {
>> +        UACCE_BUS_LOG(INFO, "open %s failed!", UACCE_BUS_CLASS_PATH);
>> +        return 0;
> Why return 0 here?

This sitation should not treated as error.
If return non-zero, the rte_bus_scan() will output a error trace "Scan for uacce bus failed".
But the reason maybe the havn't loaded uacce.ko.
So I think it's okay to return zero here.

>> +    }
>> +
>> +    while ((e = readdir(dir)) != NULL) {
>> +        if (e->d_name[0] == '.')
>> +            continue;
>> +
>> +        if (strlen(e->d_name) >= RTE_DEV_NAME_MAX_LEN) {
>> +            UACCE_BUS_LOG(WARNING, "uacce device name %s too long, skip it!",
>> +                      e->d_name);
>> +            continue;
>> +        }
>> +
>> +        if (uacce_ignore_device(e->d_name))
>> +            continue;
>> +
>> +        if (uacce_scan_one(e->d_name) < 0)
>> +            goto error;
>> +    }
>> +    closedir(dir);
>> +    return 0;
>> +
>> +error:
>> +    closedir(dir);
>> +    return -1;
>> +}
>> +
>> +static bool
>> +uacce_match(const struct rte_uacce_driver *dr, const struct rte_uacce_device *dev)
>> +{
>> +    const struct rte_uacce_id *id_table;
>> +    uint32_t len;
>> +    char *map;
>> +
>> +    for (id_table = dr->id_table; id_table->dev_api != NULL; id_table++) {
>> +        if (strcmp(id_table->dev_api, dev->api) != 0)
>> +            continue;
>> +
>> +        if (id_table->dev_alg == NULL)
>> +            return 1;
> This func() should use "ture" or "false" as return value.

ack

> Should here return "false"?

it means only match dev_api if dev_alg is NULL, so it's okay to return 1(true) here.

>> +
>> +        /* The dev->algs's algrothims is separated by new line, for
>> +         * example: dev->algs could be: aaa\nbbbb\ncc, which has three
>> +         * algorithms: aaa, bbbb and cc.
>> +         * The id_table->dev_alg should be a single algrithm, e.g. bbbb.
>> +         */
>> +        map = strstr(dev->algs, id_table->dev_alg);
>> +        if (map == NULL)
>> +            continue;
>> +        if (map != dev->algs && map[-1] != '\n')
>> +            continue;
>> +        len = strlen(id_table->dev_alg);
>> +        if (map[len] != '\0' && map[len] != '\n')
>> +            continue;
>> +
>> +        return 1;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static int
>> +uacce_probe_one_driver(struct rte_uacce_driver *dr, struct rte_uacce_device *dev)
>> +{
>> +    const char *dev_name = dev->name;
>> +    bool already_probed;
>> +    int ret;
>> +
>> +    if (!uacce_match(dr, dev))
>> +        /* Match of device and driver failed */
>> +        return 1;
>> +
>> +    already_probed = rte_dev_is_probed(&dev->device);
>> +    if (already_probed) {
>> +        UACCE_BUS_INFO("device %s is already probed", dev_name);
>> +        return -EEXIST;
>> +    }
>> +
>> +    UACCE_BUS_DEBUG("probe device %s using driver %s", dev_name, dr->driver.name);
>> +
>> +    ret = dr->probe(dr, dev);
>> +    if (ret != 0) {
>> +        UACCE_BUS_ERR("probe device %s with driver %s failed %d",
>> +                  dev_name, dr->driver.name, ret);
>> +    } else {
>> +        dev->device.driver = &dr->driver;
>> +        dev->driver = dr;
>> +        UACCE_BUS_DEBUG("probe device %s with driver %s success",
>> +                dev_name, dr->driver.name);
>> +    }
>> +
>> +    return ret;
>> +}
>> +
>> +static int
>> +uacce_probe_all_drivers(struct rte_uacce_device *dev)
>> +{
>> +    struct rte_uacce_driver *dr = NULL;
>> +    int rc = 0;
> reduntant assignment.

ack

>> +
>> +    FOREACH_DRIVER_ON_UACCEBUS(dr) {
>> +        rc = uacce_probe_one_driver(dr, dev);
>> +        if (rc < 0)
>> +            /* negative value is an error */
>> +            return rc;
>> +        if (rc > 0)
>> +            /* positive value means driver doesn't support it */
>> +            continue;
>> +        return 0;
>> +    }
>> +    return 1;
>> +}
>> +
>> +static int
>> +uacce_probe(void)
>> +{
>> +    struct rte_uacce_device *dev = NULL;
>> +    size_t probed = 0, failed = 0;
>> +    int ret = 0;
> This ret is reduntant assignment.

ack

Will send v2 to fix the place which acks.

Thanks.

^ permalink raw reply	[relevance 0%]

* [PATCH v3 1/3] ethdev: rename action modify field data structure
  2024-01-15  9:13  3% ` [PATCH v3 0/3] " Suanming Mou
@ 2024-01-15  9:13  8%   ` Suanming Mou
  0 siblings, 0 replies; 200+ results
From: Suanming Mou @ 2024-01-15  9:13 UTC (permalink / raw)
  To: orika, Aman Singh, Yuying Zhang, Dariusz Sosnowski,
	Viacheslav Ovsiienko, Matan Azrad, Thomas Monjalon, Ferruh Yigit,
	Andrew Rybchenko
  Cc: dev

Current rte_flow_action_modify_data struct describes the pkt
field perfectly and is used only in action.

It is planned to be used for item as well. This commit renames
it to "rte_flow_field_data" making it compatible to be used by item.

Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 app/test-pmd/cmdline_flow.c            |  2 +-
 doc/guides/prog_guide/rte_flow.rst     |  2 +-
 doc/guides/rel_notes/release_24_03.rst |  1 +
 drivers/net/mlx5/mlx5_flow.c           |  4 ++--
 drivers/net/mlx5/mlx5_flow.h           |  6 +++---
 drivers/net/mlx5/mlx5_flow_dv.c        | 10 +++++-----
 lib/ethdev/rte_flow.h                  |  8 ++++----
 7 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index ce71818705..3725e955c7 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -740,7 +740,7 @@ enum index {
 #define ITEM_RAW_SIZE \
 	(sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE)
 
-/** Maximum size for external pattern in struct rte_flow_action_modify_data. */
+/** Maximum size for external pattern in struct rte_flow_field_data. */
 #define ACTION_MODIFY_PATTERN_SIZE 32
 
 /** Storage size for struct rte_flow_action_modify_field including pattern. */
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 627b845bfb..bf25c849fb 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3171,7 +3171,7 @@ destination offset as ``48``, and provide immediate value ``0xXXXX85XX``.
    | ``width``     | number of bits to use   |
    +---------------+-------------------------+
 
-.. _table_rte_flow_action_modify_data:
+.. _table_rte_flow_field_data:
 
 .. table:: destination/source field definition
 
diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 2c0e2930cc..a691e794f4 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -106,6 +106,7 @@ ABI Changes
 
 * No ABI change that would break compatibility with 23.11.
 
+* ethdev: Rename the experimental ``struct rte_flow_action_modify_data`` to be ``struct rte_flow_field_data``
 
 Known Issues
 ------------
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 85e8c77c81..5788a7fb57 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2493,7 +2493,7 @@ mlx5_validate_action_ct(struct rte_eth_dev *dev,
  * Validate the level value for modify field action.
  *
  * @param[in] data
- *   Pointer to the rte_flow_action_modify_data structure either src or dst.
+ *   Pointer to the rte_flow_field_data structure either src or dst.
  * @param[out] error
  *   Pointer to error structure.
  *
@@ -2501,7 +2501,7 @@ mlx5_validate_action_ct(struct rte_eth_dev *dev,
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-flow_validate_modify_field_level(const struct rte_flow_action_modify_data *data,
+flow_validate_modify_field_level(const struct rte_flow_field_data *data,
 				 struct rte_flow_error *error)
 {
 	if (data->level == 0)
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 120609c595..8e2034473c 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -1121,7 +1121,7 @@ flow_items_to_tunnel(const struct rte_flow_item items[])
  *   Tag array index.
  */
 static inline uint8_t
-flow_tag_index_get(const struct rte_flow_action_modify_data *data)
+flow_tag_index_get(const struct rte_flow_field_data *data)
 {
 	return data->tag_index ? data->tag_index : data->level;
 }
@@ -2523,7 +2523,7 @@ int mlx5_flow_validate_action_default_miss(uint64_t action_flags,
 				const struct rte_flow_attr *attr,
 				struct rte_flow_error *error);
 int flow_validate_modify_field_level
-			(const struct rte_flow_action_modify_data *data,
+			(const struct rte_flow_field_data *data,
 			 struct rte_flow_error *error);
 int mlx5_flow_item_acceptable(const struct rte_flow_item *item,
 			      const uint8_t *mask,
@@ -2828,7 +2828,7 @@ size_t flow_dv_get_item_hdr_len(const enum rte_flow_item_type item_type);
 int flow_dv_convert_encap_data(const struct rte_flow_item *items, uint8_t *buf,
 			   size_t *size, struct rte_flow_error *error);
 void mlx5_flow_field_id_to_modify_info
-		(const struct rte_flow_action_modify_data *data,
+		(const struct rte_flow_field_data *data,
 		 struct field_modify_info *info, uint32_t *mask,
 		 uint32_t width, struct rte_eth_dev *dev,
 		 const struct rte_flow_attr *attr, struct rte_flow_error *error);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 97f55003c3..e4bfcc76f7 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1446,7 +1446,7 @@ flow_modify_info_mask_32_masked(uint32_t length, uint32_t off, uint32_t post_mas
 }
 
 static __rte_always_inline enum mlx5_modification_field
-mlx5_mpls_modi_field_get(const struct rte_flow_action_modify_data *data)
+mlx5_mpls_modi_field_get(const struct rte_flow_field_data *data)
 {
 	return MLX5_MODI_IN_MPLS_LABEL_0 + data->tag_index;
 }
@@ -1454,7 +1454,7 @@ mlx5_mpls_modi_field_get(const struct rte_flow_action_modify_data *data)
 static void
 mlx5_modify_flex_item(const struct rte_eth_dev *dev,
 		      const struct mlx5_flex_item *flex,
-		      const struct rte_flow_action_modify_data *data,
+		      const struct rte_flow_field_data *data,
 		      struct field_modify_info *info,
 		      uint32_t *mask, uint32_t width)
 {
@@ -1578,7 +1578,7 @@ mlx5_modify_flex_item(const struct rte_eth_dev *dev,
 
 void
 mlx5_flow_field_id_to_modify_info
-		(const struct rte_flow_action_modify_data *data,
+		(const struct rte_flow_field_data *data,
 		 struct field_modify_info *info, uint32_t *mask,
 		 uint32_t width, struct rte_eth_dev *dev,
 		 const struct rte_flow_attr *attr, struct rte_flow_error *error)
@@ -5329,8 +5329,8 @@ flow_dv_validate_action_modify_field(struct rte_eth_dev *dev,
 	struct mlx5_sh_config *config = &priv->sh->config;
 	struct mlx5_hca_attr *hca_attr = &priv->sh->cdev->config.hca_attr;
 	const struct rte_flow_action_modify_field *conf = action->conf;
-	const struct rte_flow_action_modify_data *src_data = &conf->src;
-	const struct rte_flow_action_modify_data *dst_data = &conf->dst;
+	const struct rte_flow_field_data *src_data = &conf->src;
+	const struct rte_flow_field_data *dst_data = &conf->dst;
 	uint32_t dst_width, src_width, width = conf->width;
 
 	ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index affdc8121b..40f6dcaacd 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3910,9 +3910,9 @@ enum rte_flow_field_id {
  * @warning
  * @b EXPERIMENTAL: this structure may change without prior notice
  *
- * Field description for MODIFY_FIELD action.
+ * Field description for packet field.
  */
-struct rte_flow_action_modify_data {
+struct rte_flow_field_data {
 	enum rte_flow_field_id field; /**< Field or memory type ID. */
 	union {
 		struct {
@@ -4021,8 +4021,8 @@ enum rte_flow_modify_op {
  */
 struct rte_flow_action_modify_field {
 	enum rte_flow_modify_op operation; /**< Operation to perform. */
-	struct rte_flow_action_modify_data dst; /**< Destination field. */
-	struct rte_flow_action_modify_data src; /**< Source field. */
+	struct rte_flow_field_data dst; /**< Destination field. */
+	struct rte_flow_field_data src; /**< Source field. */
 	uint32_t width; /**< Number of bits to use from a source field. */
 };
 
-- 
2.34.1


^ permalink raw reply	[relevance 8%]

* [PATCH v3 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE
  @ 2024-01-15  9:13  3% ` Suanming Mou
  2024-01-15  9:13  8%   ` [PATCH v3 1/3] ethdev: rename action modify field data structure Suanming Mou
  0 siblings, 1 reply; 200+ results
From: Suanming Mou @ 2024-01-15  9:13 UTC (permalink / raw)
  To: orika; +Cc: dev

The new item type is added for the case user wants to match traffic
based on packet field compare result with other fields or immediate
value.

e.g. take advantage the compare item user will be able to accumulate
a IPv4/TCP packet's TCP data_offset and IPv4 IHL field to a tag
register, then compare the tag register with IPv4 header total length
to understand the packet has payload or not.

The supported operations can be as below:
 - RTE_FLOW_ITEM_COMPARE_EQ (equal)
 - RTE_FLOW_ITEM_COMPARE_NE (not equal)
 - RTE_FLOW_ITEM_COMPARE_LT (less than)
 - RTE_FLOW_ITEM_COMPARE_LE (less than or equal)
 - RTE_FLOW_ITEM_COMPARE_GT (great than)
 - RTE_FLOW_ITEM_COMPARE_GE (great than or equal)

V3:
 - fix code style missing empty line in rte_flow.rst.
 - fix missing the ABI change release notes.

V2:
 - Since modify field data struct is experiment, rename modify
   field data directly instead of adding new flow field struct.

Suanming Mou (3):
  ethdev: rename action modify field data structure
  ethdev: add compare item
  net/mlx5: add compare item support

 app/test-pmd/cmdline_flow.c                 | 416 +++++++++++++++++++-
 doc/guides/nics/features/default.ini        |   1 +
 doc/guides/nics/features/mlx5.ini           |   1 +
 doc/guides/nics/mlx5.rst                    |   7 +
 doc/guides/prog_guide/rte_flow.rst          |   9 +-
 doc/guides/rel_notes/release_24_03.rst      |   8 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |   7 +
 drivers/net/mlx5/mlx5_flow.c                |   4 +-
 drivers/net/mlx5/mlx5_flow.h                |   9 +-
 drivers/net/mlx5/mlx5_flow_dv.c             |  10 +-
 drivers/net/mlx5/mlx5_flow_hw.c             |  73 ++++
 lib/ethdev/rte_flow.c                       |   1 +
 lib/ethdev/rte_flow.h                       | 326 ++++++++-------
 13 files changed, 703 insertions(+), 169 deletions(-)

-- 
2.34.1


^ permalink raw reply	[relevance 3%]

* Re: [PATCH] bus/uacce: introduce UACCE bus
  2023-12-08  6:18  2% [PATCH] bus/uacce: introduce UACCE bus Chengwen Feng
@ 2024-01-15  8:14  0% ` lihuisong (C)
  2024-01-15 11:43  0%   ` fengchengwen
  2024-01-16  3:35  2% ` [PATCH v2] " Chengwen Feng
  1 sibling, 1 reply; 200+ results
From: lihuisong (C) @ 2024-01-15  8:14 UTC (permalink / raw)
  To: dev, Chengwen Feng
  Cc: tangkunshan@huawei.com >> Tangkunshan, Wangzhou (B),
	Thomas Monjalon

Hi chengwen,

lgtm,
with below to changes,
Acked-by: Huisong Li <lihuisong@huawei.com>


在 2023/12/8 14:18, Chengwen Feng 写道:
> UACCE (Unified/User-space-access-intended Accelerator Framework) was
> upstream to Linux kernel version 5.7, and it targets to provide Shared
> Virtual Addressing (SVA) between accelerators and processes. So
> accelerator can access any data structure of the main cpu. [1] for more
> information.
>
> This commit introduces UACCE bus, so that the accelerator devices could
> seen at DPDK and could be further registered as a compress, crypto, dma
> and ethdev device.
>
> [1] https://docs.kernel.org/misc-devices/uacce.html
>
> Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
> ---
>   MAINTAINERS                          |   4 +
>   drivers/bus/meson.build              |   1 +
>   drivers/bus/uacce/bus_uacce_driver.h | 254 ++++++++++
>   drivers/bus/uacce/meson.build        |  12 +
>   drivers/bus/uacce/uacce.c            | 702 +++++++++++++++++++++++++++
>   drivers/bus/uacce/version.map        |  15 +
>   6 files changed, 988 insertions(+)
>   create mode 100644 drivers/bus/uacce/bus_uacce_driver.h
>   create mode 100644 drivers/bus/uacce/meson.build
>   create mode 100644 drivers/bus/uacce/uacce.c
>   create mode 100644 drivers/bus/uacce/version.map
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 0d1c8126e3..89711029d5 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -604,6 +604,10 @@ Platform bus driver
>   M: Tomasz Duszynski <tduszynski@marvell.com>
>   F: drivers/bus/platform/
>   
> +UACCE bus driver
> +M: Chengwen Feng <fengchengwen@huawei.com>
> +F: drivers/bus/uacce/
> +
>   VDEV bus driver
>   F: drivers/bus/vdev/
>   F: app/test/test_vdev.c
> diff --git a/drivers/bus/meson.build b/drivers/bus/meson.build
> index a78b4283bf..d67db8576b 100644
> --- a/drivers/bus/meson.build
> +++ b/drivers/bus/meson.build
> @@ -9,6 +9,7 @@ drivers = [
>           'ifpga',
>           'pci',
>           'platform',
> +        'uacce',
>           'vdev',
>           'vmbus',
>   ]
> diff --git a/drivers/bus/uacce/bus_uacce_driver.h b/drivers/bus/uacce/bus_uacce_driver.h
> new file mode 100644
> index 0000000000..0276154658
> --- /dev/null
> +++ b/drivers/bus/uacce/bus_uacce_driver.h
> @@ -0,0 +1,254 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2023 HiSilicon Limited
> + */
> +
> +#ifndef BUS_UACCE_DRIVER_H
> +#define BUS_UACCE_DRIVER_H
> +
> +/**
> + * @file
> + *
> + * HiSilicon UACCE bus interface.
> + */
> +
> +#include <inttypes.h>
> +#include <stdlib.h>
> +#include <linux/types.h>
> +
> +#include <rte_compat.h>
> +#include <rte_devargs.h>
> +#include <dev_driver.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif /* __cplusplus */
> +
> +#define RTE_UACCE_DEV_PATH_SIZE		256
> +#define RTE_UACCE_API_NAME_SIZE		64
> +#define RTE_UACCE_ALGS_NAME_SIZE	384
> +#define RTE_UACCE_ATTR_MAX_SIZE		384
> +
> +/*
> + * Definition for queue file region type.
> + */
> +enum rte_uacce_qfrt {
> +	RTE_UACCE_QFRT_MMIO = 0, /**< Device mmio region. */
> +	RTE_UACCE_QFRT_DUS,      /**< Device user share region. */
> +	RTE_UACCE_QFRT_BUTT
> +};
> +
> +struct rte_uacce_driver;
> +
> +/**
> + * A structure describing a UACCE device.
> + */
> +struct rte_uacce_device {
> +	RTE_TAILQ_ENTRY(rte_uacce_device) next;  /**< Next in device list. */
> +	struct rte_device device;                /**< Inherit core device. */
> +	struct rte_uacce_driver *driver;         /**< Driver used in probing. */
> +	char name[RTE_DEV_NAME_MAX_LEN];         /**< Device name. */
> +	char dev_root[RTE_UACCE_DEV_PATH_SIZE];  /**< Sysfs path with device name. */
> +	char cdev_path[RTE_UACCE_DEV_PATH_SIZE]; /**< Device path in devfs. */
> +	char api[RTE_UACCE_API_NAME_SIZE];       /**< Device context type. */
> +	char algs[RTE_UACCE_ALGS_NAME_SIZE];     /**< Device supported algorithms. */
> +	uint32_t flags;                          /**< Device flags. */
> +	int numa_node;                           /**< NUMA node connection, -1 if unknown. */
> +	uint32_t qfrt_sz[RTE_UACCE_QFRT_BUTT];   /**< Queue file region type's size. */
> +};
> +
> +/**
> + * @internal
> + * Helper macro for drivers that need to convert to struct rte_uacce_device.
> + */
> +#define RTE_DEV_TO_UACCE_DEV(ptr) \
> +	container_of(ptr, struct rte_uacce_device, device)
> +
> +#define RTE_DEV_TO_UACCE_DEV_CONST(ptr) \
> +	container_of(ptr, const struct rte_uacce_device, device)
> +
> +/**
> + * A structure describing an ID for a UACCE driver. Each driver provides a
> + * table of these IDs for each device that it supports.
> + */
> +struct rte_uacce_id {
> +	const char *dev_api;   /**< Device context type. */
> +	/** Device algorithm.
> +	 * If this field is NULL, only dev_api is matched. Otherwise, in
> +	 * addition to match dev_api, dev_alg must be a subset of device's
> +	 * algs.
> +	 */
> +	const char *dev_alg;
> +};
> +
> +/**
> + * Initialization function for the driver called during probing.
> + */
> +typedef int (rte_uacce_probe_t)(struct rte_uacce_driver *, struct rte_uacce_device *);
> +
> +/**
> + * Uninitialization function for the driver called during hotplugging.
> + */
> +typedef int (rte_uacce_remove_t)(struct rte_uacce_device *);
> +
> +/**
> + * A structure describing a UACCE driver.
> + */
> +struct rte_uacce_driver {
> +	RTE_TAILQ_ENTRY(rte_uacce_driver) next;	/**< Next in list. */
> +	struct rte_driver driver;               /**< Inherit core driver. */
> +	struct rte_uacce_bus *bus;              /**< UACCE bus reference. */
> +	rte_uacce_probe_t *probe;               /**< Device probe function. */
> +	rte_uacce_remove_t *remove;             /**< Device remove function. */
> +	const struct rte_uacce_id *id_table;    /**< ID table, NULL terminated. */
> +};
> +
> +/**
> + * Get available queue number.
> + *
> + * @param dev
> + *   A pointer to a rte_uacce_device structure describing the device
> + *   to use.
> + *
> + * @note The available queues on the device may changes dynamically,
> + * for examples, other process may alloc or free queues.
> + *
> + * @return
> + *   0 on success. Otherwise negative value is returned.
> + */
> +__rte_internal
> +int rte_uacce_avail_queues(struct rte_uacce_device *dev);
> +
> +/*
> + * The queue context for a UACCE queue.
> + */
> +struct rte_uacce_qcontex {
> +	int fd;                       /**< The file descriptor associated to the queue. */
> +	struct rte_uacce_device *dev; /**< The device associated to the queue. */
> +	void *qfrt_base[RTE_UACCE_QFRT_BUTT]; /**< The qfrt mmap's memory base. */
> +};
> +
> +/**
> + * Alloc one queue.
> + *
> + * @param dev
> + *   A pointer to a rte_uacce_device structure describing the device to use.
> + * @param qctx
> + *   Pointer to queue context, which is used to store the queue information
> + *   that is successfully applied for.
> + *
> + * @return
> + *   0 on success. Otherwise negative value is returned.
> + */
> +__rte_internal
> +int rte_uacce_queue_alloc(struct rte_uacce_device *dev, struct rte_uacce_qcontex *qctx);
> +
> +/**
> + * Free one queue.
> + *
> + * @param qctx
> + *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
> + *
> + * @note Once the queue is freed, any operations on the queue (including
> + * control-plane and data-plane, and also read & write mmap region) are not
> + * allowed.
> + */
> +__rte_internal
> +void rte_uacce_queue_free(struct rte_uacce_qcontex *qctx);
> +
> +/**
> + * Start one queue.
> + *
> + * @param qctx
> + *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
> + *
> + * @return
> + *   0 on success. Otherwise negative value is returned.
> + */
> +__rte_internal
> +int rte_uacce_queue_start(struct rte_uacce_qcontex *qctx);
> +
> +/**
> + * Send ioctl command to one queue.
> + *
> + * @param qctx
> + *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
> + * @param cmd
> + *   ioctl command.
> + *   @note The nr must not conflict with the definition in Linux kerel:
> + *   include/uapi/misc/uacce/uacce.h. It is recommended that the driver
> + *   custom nr start from 64.
> + * @param arg
> + *   Command input & output buffer.
> + *
> + * @return
> + *   0 on success. Otherwise negative value is returned.
> + */
> +__rte_internal
> +int rte_uacce_queue_ioctl(struct rte_uacce_qcontex *qctx, unsigned long cmd, void *arg);
> +
> +/**
> + * Mmap queue file region.
> + *
> + * @param qctx
> + *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
> + * @param qfrt
> + *   The queue file region type. Must be RTE_UACCE_QFRT_MMIO or
> + *   RTE_UACCE_QFRT_DUS.
> + *
> + * @return
> + *   Non-NULL on success. Otherwise NULL is returned.
> + */
> +__rte_internal
> +void *rte_uacce_queue_mmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt);
> +
> +/**
> + * Unmap queue file region.
> + *
> + * @param qctx
> + *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
> + * @param qfrt
> + *   The queue file region type. Must be RTE_UACCE_QFRT_MMIO or
> + *   RTE_UACCE_QFRT_DUS.
> + *
> + * @return
> + *   Non-NULL on success. Otherwise NULL is returned.
> + */
> +__rte_internal
> +void rte_uacce_queue_unmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt);
> +
> +/**
> + * Register a UACCE driver.
> + *
> + * @param driver
> + *   A pointer to a rte_uacce_driver structure describing the driver to be
> + *   registered.
> + */
> +__rte_internal
> +void rte_uacce_register(struct rte_uacce_driver *driver);
> +
> +/**
> + * Unregister a UACCE driver.
> + *
> + * @param driver
> + *   A pointer to a rte_uacce_driver structure describing the driver to be
> + *   unregistered.
> + */
> +__rte_internal
> +void rte_uacce_unregister(struct rte_uacce_driver *driver);
> +
> +/**
> + * Helper for UACCE device registration from driver instance.
> + */
> +#define RTE_PMD_REGISTER_UACCE(nm, uacce_drv) \
> +		RTE_INIT(uacceinitfn_ ##nm) \
> +		{\
> +			(uacce_drv).driver.name = RTE_STR(nm);\
> +			rte_uacce_register(&uacce_drv); \
> +		} \
> +		RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
> +
> +#ifdef __cplusplus
> +}
> +#endif /* __cplusplus */
> +
> +#endif /* BUS_UACCE_DRIVER_H */
> diff --git a/drivers/bus/uacce/meson.build b/drivers/bus/uacce/meson.build
> new file mode 100644
> index 0000000000..b48d6db11a
> --- /dev/null
> +++ b/drivers/bus/uacce/meson.build
> @@ -0,0 +1,12 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2023 HiSilicon Limited.
> +
> +if not is_linux
> +    build = false
> +    reason = 'only supported on Linux'
> +endif
> +
> +sources = files('uacce.c')
> +driver_sdk_headers += files('bus_uacce_driver.h')
> +
> +deps += ['kvargs']
> diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
> new file mode 100644
> index 0000000000..8e824c44df
> --- /dev/null
> +++ b/drivers/bus/uacce/uacce.c
> @@ -0,0 +1,702 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2023 HiSilicon Limited
> + */
> +
> +#include <dirent.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/ioctl.h>
> +#include <sys/mman.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
> +
> +#include <rte_bitops.h>
> +#include <rte_common.h>
> +#include <rte_devargs.h>
> +#include <rte_errno.h>
> +#include <rte_log.h>
> +#include <rte_kvargs.h>
> +#include <bus_driver.h>
> +
> +#include "bus_uacce_driver.h"
> +
> +#define UACCE_BUS_CLASS_PATH	"/sys/class/uacce"
> +
> +/* UACCE device flag of SVA. */
> +#define UACCE_DEV_FLGA_SVA	RTE_BIT32(0)
> +
> +/* Support -a uacce:device-name when start DPDK application. */
> +#define UACCE_DEV_PREFIX	"uacce:"
> +
> +/*
> + * Structure describing the UACCE bus.
> + */
> +struct rte_uacce_bus {
> +	struct rte_bus bus;		            /* Inherit the generic class. */
> +	TAILQ_HEAD(, rte_uacce_device) device_list; /* List of devices. */
> +	TAILQ_HEAD(, rte_uacce_driver) driver_list; /* List of drivers. */
> +};
> +
> +/* Forward declaration of UACCE bus. */
> +static struct rte_uacce_bus uacce_bus;
> +
> +enum uacce_params {
> +	RTE_UACCE_PARAM_NAME,
> +};
> +
> +static const char *const uacce_params_keys[] = {
> +	[RTE_UACCE_PARAM_NAME] = "name",
> +	NULL,
> +};
> +
> +#define FOREACH_DEVICE_ON_UACCEBUS(p)	\
> +		RTE_TAILQ_FOREACH(p, &uacce_bus.device_list, next)
> +#define FOREACH_DRIVER_ON_UACCEBUS(p)	\
> +		RTE_TAILQ_FOREACH(p, &uacce_bus.driver_list, next)
> +
> +extern int uacce_bus_logtype;
> +#define UACCE_BUS_LOG(level, fmt, args...) \
> +	rte_log(RTE_LOG_ ## level, uacce_bus_logtype, "uacce: " fmt "\n", \
> +		##args)
> +#define UACCE_BUS_ERR(fmt, args...) UACCE_BUS_LOG(ERR, fmt, ##args)
> +#define UACCE_BUS_WARN(fmt, args...) UACCE_BUS_LOG(WARNING, fmt, ##args)
> +#define UACCE_BUS_INFO(fmt, args...) UACCE_BUS_LOG(INFO, fmt, ##args)
> +#define UACCE_BUS_DEBUG(fmt, args...) UACCE_BUS_LOG(DEBUG, fmt, ##args)
> +
> +
> +static struct rte_devargs *
> +uacce_devargs_lookup(const char *dev_name)
> +{
> +	char name[RTE_UACCE_DEV_PATH_SIZE] = {0};
> +	struct rte_devargs *devargs;
> +
> +	snprintf(name, sizeof(name), "%s%s", UACCE_DEV_PREFIX, dev_name);
> +	RTE_EAL_DEVARGS_FOREACH("uacce", devargs) {
> +		if (strcmp(devargs->name, name) == 0)
> +			return devargs;
> +	}
> +
> +	return NULL;
> +}
> +
> +static bool
> +uacce_ignore_device(const char *dev_name)
> +{
> +	struct rte_devargs *devargs = uacce_devargs_lookup(dev_name);
> +
> +	switch (uacce_bus.bus.conf.scan_mode) {
> +	case RTE_BUS_SCAN_ALLOWLIST:
> +		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
> +			return false;
> +		break;
> +	case RTE_BUS_SCAN_UNDEFINED:
> +	case RTE_BUS_SCAN_BLOCKLIST:
> +		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
> +			return false;
> +		break;
> +	}
> +
> +	return true;
> +}
> +
> +/*
> + * Returns the number of bytes read (removed last newline) on success.
> + * Otherwise negative value is returned.
> + */
> +static int
> +uacce_read_attr(const char *dev_root, const char *attr, char *buf, uint32_t sz)
> +{
> +	char filename[PATH_MAX] = {0};
> +	int ret;
> +	int fd;
> +	int i;
> +
> +	snprintf(filename, sizeof(filename), "%s/%s", dev_root, attr);
> +	fd = open(filename, O_RDONLY, 0);
> +	if (fd < 0) {
> +		UACCE_BUS_ERR("failed to open %s", filename);
> +		return -EIO;
> +	}
> +
> +	ret = read(fd, buf, sz);
> +	if (ret > 0) {
> +		/* Remove the last new line character. */
> +		for (i = ret - 1; i >= 0; i--) {
> +			if (buf[i] == '\n') {
> +				buf[i] = '\0';
> +				ret--;
> +				break;
> +			}
> +		}
> +	}
> +	if (ret <= 0) {
close(fd) is also needed here.
> +		UACCE_BUS_ERR("failed to read %s", filename);
> +		return -EIO;
> +	}
> +
> +	close(fd);
> +
> +	return ret;
> +}
> +
> +/* 0 on success. Otherwise negative value is returned. */
> +static int
> +uacce_read_attr_int(const char *dev_root, const char *attr, int *val)
> +{
> +	char buf[RTE_UACCE_ATTR_MAX_SIZE] = {0};
> +	char *s = NULL;
> +	int ret;
> +
> +	ret = uacce_read_attr(dev_root, attr, buf, sizeof(buf) - 1);
> +	if (ret < 0)
> +		return ret;
> +
> +	*val = strtol(buf, &s, 0);
> +	if (s[0] != '\0') {
> +		UACCE_BUS_ERR("read attr %s/%s expect an integer value", dev_root, attr);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +/* 0 on success. Otherwise negative value is returned. */
> +static int
> +uacce_read_attr_u32(const char *dev_root, const char *attr, uint32_t *val)
> +{
> +	char buf[RTE_UACCE_ATTR_MAX_SIZE] = {0};
> +	char *s = NULL;
> +	int ret;
> +
> +	ret = uacce_read_attr(dev_root, attr, buf, sizeof(buf) - 1);
> +	if (ret < 0)
> +		return ret;
> +
> +	*val = strtoul(buf, &s, 0);
> +	if (s[0] != '\0') {
> +		UACCE_BUS_ERR("read attr %s/%s expect an uint32 value", dev_root, attr);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +uacce_read_api(struct rte_uacce_device *dev)
> +{
> +	int ret = uacce_read_attr(dev->dev_root, "api", dev->api, sizeof(dev->api) - 1);
> +	if (ret < 0)
> +		return ret;
> +	return 0;
Could you use return uacce_read_attr()? it is more concise.
> +}
> +
> +static int
> +uacce_read_algs(struct rte_uacce_device *dev)
> +{
> +	int ret = uacce_read_attr(dev->dev_root, "algorithms", dev->algs, sizeof(dev->algs) - 1);
> +	if (ret < 0)
> +		return ret;
> +	return 0;
return uacce_read_attr()
> +}
> +
> +static int
> +uacce_read_flags(struct rte_uacce_device *dev)
> +{
> +	return uacce_read_attr_u32(dev->dev_root, "flags", &dev->flags);
> +}
> +
> +static void
> +uacce_read_numa_node(struct rte_uacce_device *dev)
> +{
> +	int ret = uacce_read_attr_int(dev->dev_root, "device/numa_node", &dev->numa_node);
> +	if (ret != 0) {
> +		UACCE_BUS_WARN("read attr numa_node failed! set to default");
> +		dev->numa_node = -1;
> +	}
> +}
> +
> +static int
> +uacce_read_qfrt_sz(struct rte_uacce_device *dev)
> +{
> +	int ret = uacce_read_attr_u32(dev->dev_root, "region_mmio_size",
> +				      &dev->qfrt_sz[RTE_UACCE_QFRT_MMIO]);
> +	if (ret != 0)
> +		return ret;
> +	return uacce_read_attr_u32(dev->dev_root, "region_dus_size",
> +				   &dev->qfrt_sz[RTE_UACCE_QFRT_DUS]);
> +}
> +
> +static int
> +uacce_verify(struct rte_uacce_device *dev)
> +{
> +	if (!(dev->flags & UACCE_DEV_FLGA_SVA)) {
> +		UACCE_BUS_WARN("device %s don't support SVA, skip it!", dev->name);
> +		return 1; /* >0 will skip this device. */
> +	}
> +
> +	return 0;
> +}
> +
> +/*
> + * Scan one UACCE sysfs entry, and fill the devices list from it.
> + * It reads api/algs/flags/numa_node/region-size (please refer Linux kernel:
> + * Documentation/ABI/testing/sysfs-driver-uacce) and stores them for later
> + * device-driver matching, driver init...
> + */
> +static int
> +uacce_scan_one(const char *dev_name)
> +{
> +	struct rte_uacce_device *dev = NULL;
This assignment for dev is redundant.
> +	int ret;
> +
> +	dev = calloc(1, sizeof(*dev));
> +	if (!dev)
> +		return -ENOMEM;
> +
> +	dev->device.bus = &uacce_bus.bus;
> +	dev->device.name = dev->name;
> +	dev->device.devargs = uacce_devargs_lookup(dev_name);
> +	snprintf(dev->name, sizeof(dev->name), "%s", dev_name);
> +	snprintf(dev->dev_root, sizeof(dev->dev_root), "%s/%s",
> +		 UACCE_BUS_CLASS_PATH, dev_name);
> +	snprintf(dev->cdev_path, sizeof(dev->cdev_path), "/dev/%s", dev_name);
> +
> +	ret = uacce_read_api(dev);
> +	if (ret != 0)
> +		goto err;
> +	ret = uacce_read_algs(dev);
> +	if (ret != 0)
> +		goto err;
> +	ret = uacce_read_flags(dev);
> +	if (ret != 0)
> +		goto err;
> +	uacce_read_numa_node(dev);
> +	ret = uacce_read_qfrt_sz(dev);
> +	if (ret != 0)
> +		goto err;
> +
> +	ret = uacce_verify(dev);
> +	if (ret != 0)
> +		goto err;
> +
> +	TAILQ_INSERT_TAIL(&uacce_bus.device_list, dev, next);
> +	return 0;
> +
> +err:
> +	free(dev);
> +	return ret;
> +}
> +
> +static int
> +uacce_scan(void)
> +{
> +	struct dirent *e;
> +	DIR *dir;
> +
> +	dir = opendir(UACCE_BUS_CLASS_PATH);
> +	if (dir == NULL) {
> +		UACCE_BUS_LOG(INFO, "open %s failed!", UACCE_BUS_CLASS_PATH);
> +		return 0;
Why return 0 here?
> +	}
> +
> +	while ((e = readdir(dir)) != NULL) {
> +		if (e->d_name[0] == '.')
> +			continue;
> +
> +		if (strlen(e->d_name) >= RTE_DEV_NAME_MAX_LEN) {
> +			UACCE_BUS_LOG(WARNING, "uacce device name %s too long, skip it!",
> +				      e->d_name);
> +			continue;
> +		}
> +
> +		if (uacce_ignore_device(e->d_name))
> +			continue;
> +
> +		if (uacce_scan_one(e->d_name) < 0)
> +			goto error;
> +	}
> +	closedir(dir);
> +	return 0;
> +
> +error:
> +	closedir(dir);
> +	return -1;
> +}
> +
> +static bool
> +uacce_match(const struct rte_uacce_driver *dr, const struct rte_uacce_device *dev)
> +{
> +	const struct rte_uacce_id *id_table;
> +	uint32_t len;
> +	char *map;
> +
> +	for (id_table = dr->id_table; id_table->dev_api != NULL; id_table++) {
> +		if (strcmp(id_table->dev_api, dev->api) != 0)
> +			continue;
> +
> +		if (id_table->dev_alg == NULL)
> +			return 1;
This func() should use "ture" or "false" as return value.
Should here return "false"?
> +
> +		/* The dev->algs's algrothims is separated by new line, for
> +		 * example: dev->algs could be: aaa\nbbbb\ncc, which has three
> +		 * algorithms: aaa, bbbb and cc.
> +		 * The id_table->dev_alg should be a single algrithm, e.g. bbbb.
> +		 */
> +		map = strstr(dev->algs, id_table->dev_alg);
> +		if (map == NULL)
> +			continue;
> +		if (map != dev->algs && map[-1] != '\n')
> +			continue;
> +		len = strlen(id_table->dev_alg);
> +		if (map[len] != '\0' && map[len] != '\n')
> +			continue;
> +
> +		return 1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +uacce_probe_one_driver(struct rte_uacce_driver *dr, struct rte_uacce_device *dev)
> +{
> +	const char *dev_name = dev->name;
> +	bool already_probed;
> +	int ret;
> +
> +	if (!uacce_match(dr, dev))
> +		/* Match of device and driver failed */
> +		return 1;
> +
> +	already_probed = rte_dev_is_probed(&dev->device);
> +	if (already_probed) {
> +		UACCE_BUS_INFO("device %s is already probed", dev_name);
> +		return -EEXIST;
> +	}
> +
> +	UACCE_BUS_DEBUG("probe device %s using driver %s", dev_name, dr->driver.name);
> +
> +	ret = dr->probe(dr, dev);
> +	if (ret != 0) {
> +		UACCE_BUS_ERR("probe device %s with driver %s failed %d",
> +			      dev_name, dr->driver.name, ret);
> +	} else {
> +		dev->device.driver = &dr->driver;
> +		dev->driver = dr;
> +		UACCE_BUS_DEBUG("probe device %s with driver %s success",
> +				dev_name, dr->driver.name);
> +	}
> +
> +	return ret;
> +}
> +
> +static int
> +uacce_probe_all_drivers(struct rte_uacce_device *dev)
> +{
> +	struct rte_uacce_driver *dr = NULL;
> +	int rc = 0;
reduntant assignment.
> +
> +	FOREACH_DRIVER_ON_UACCEBUS(dr) {
> +		rc = uacce_probe_one_driver(dr, dev);
> +		if (rc < 0)
> +			/* negative value is an error */
> +			return rc;
> +		if (rc > 0)
> +			/* positive value means driver doesn't support it */
> +			continue;
> +		return 0;
> +	}
> +	return 1;
> +}
> +
> +static int
> +uacce_probe(void)
> +{
> +	struct rte_uacce_device *dev = NULL;
> +	size_t probed = 0, failed = 0;
> +	int ret = 0;
This ret is reduntant assignment.
> +
> +	FOREACH_DEVICE_ON_UACCEBUS(dev) {
> +		probed++;
> +
> +		ret = uacce_probe_all_drivers(dev);
> +		if (ret < 0) {
> +			UACCE_BUS_LOG(ERR, "Requested device %s cannot be used",
> +				dev->name);
> +			rte_errno = errno;
> +			failed++;
> +		}
> +	}
> +
> +	return (probed && probed == failed) ? -1 : 0;
> +}
> +
> +static int
> +uacce_cleanup(void)
> +{
> +	struct rte_uacce_device *dev, *tmp_dev;
> +	int error = 0;
> +
> +	RTE_TAILQ_FOREACH_SAFE(dev, &uacce_bus.device_list, next, tmp_dev) {
> +		struct rte_uacce_driver *dr = dev->driver;
> +		int ret = 0;
> +
> +		if (dr == NULL || dr->remove == NULL)
> +			goto free;
> +
> +		ret = dr->remove(dev);
> +		if (ret < 0) {
> +			rte_errno = errno;
> +			error = -1;
> +		}
> +		dev->driver = NULL;
> +		dev->device.driver = NULL;
> +
> +free:
> +		memset(dev, 0, sizeof(*dev));
> +		free(dev);
> +	}
> +
> +	return error;
> +}
> +
> +static int
> +uacce_plug(struct rte_device *dev)
> +{
> +	return uacce_probe_all_drivers(RTE_DEV_TO_UACCE_DEV(dev));
> +}
> +
> +static int
> +uacce_detach_dev(struct rte_uacce_device *dev)
> +{
> +	struct rte_uacce_driver *dr;
> +	int ret = 0;
> +
> +	dr = dev->driver;
> +
> +	UACCE_BUS_DEBUG("detach device %s using driver: %s", dev->device.name, dr->driver.name);
> +
> +	if (dr->remove) {
> +		ret = dr->remove(dev);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	dev->driver = NULL;
> +	dev->device.driver = NULL;
> +
> +	return 0;
> +}
> +
> +static int
> +uacce_unplug(struct rte_device *dev)
> +{
> +	struct rte_uacce_device *uacce_dev;
> +	int ret;
> +
> +	uacce_dev = RTE_DEV_TO_UACCE_DEV(dev);
> +	ret = uacce_detach_dev(uacce_dev);
> +	if (ret == 0) {
> +		TAILQ_REMOVE(&uacce_bus.device_list, uacce_dev, next);
> +		rte_devargs_remove(dev->devargs);
> +		free(uacce_dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static struct rte_device *
> +uacce_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,  const void *data)
> +{
> +	const struct rte_uacce_device *uacce_start;
> +	struct rte_uacce_device *uacce_dev;
> +
> +	if (start != NULL) {
> +		uacce_start = RTE_DEV_TO_UACCE_DEV_CONST(start);
> +		uacce_dev = TAILQ_NEXT(uacce_start, next);
> +	} else {
> +		uacce_dev = TAILQ_FIRST(&uacce_bus.device_list);
> +	}
> +
> +	while (uacce_dev != NULL) {
> +		if (cmp(&uacce_dev->device, data) == 0)
> +			return &uacce_dev->device;
> +		uacce_dev = TAILQ_NEXT(uacce_dev, next);
> +	}
> +
> +	return NULL;
> +}
> +
> +static int
> +uacce_parse(const char *name, void *addr)
> +{
> +	const char **out = addr;
> +	int ret;
> +
> +	ret = strncmp(name, UACCE_DEV_PREFIX, strlen(UACCE_DEV_PREFIX));
> +
> +	if (ret == 0 && addr)
> +		*out = name;
> +
> +	return ret;
> +}
> +
> +static int
> +uacce_dev_match(const struct rte_device *dev, const void *_kvlist)
> +{
> +	const char *key = uacce_params_keys[RTE_UACCE_PARAM_NAME];
> +	const struct rte_kvargs *kvlist = _kvlist;
> +	const char *name;
> +
> +	/* no kvlist arg, all devices match. */
> +	if (kvlist == NULL)
> +		return 0;
> +
> +	/* if key is present in kvlist and does not match, filter device. */
> +	name = rte_kvargs_get(kvlist, key);
> +	if (name != NULL && strcmp(name, dev->name))
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static void *
> +uacce_dev_iterate(const void *start, const char *str,
> +		  const struct rte_dev_iterator *it __rte_unused)
> +{
> +	rte_bus_find_device_t find_device;
> +	struct rte_kvargs *kvargs = NULL;
> +	struct rte_device *dev;
> +
> +	if (str != NULL) {
> +		kvargs = rte_kvargs_parse(str, uacce_params_keys);
> +		if (kvargs == NULL) {
> +			UACCE_BUS_ERR("cannot parse argument list %s", str);
> +			return NULL;
> +		}
> +	}
> +	find_device = uacce_bus.bus.find_device;
> +	dev = find_device(start, uacce_dev_match, kvargs);
> +	rte_kvargs_free(kvargs);
> +	return dev;
> +}
> +
> +int
> +rte_uacce_avail_queues(struct rte_uacce_device *dev)
> +{
> +	int avails = 0;
> +	int ret;
> +
> +	ret = uacce_read_attr_int(dev->dev_root, "available_instances", &avails);
> +	if (ret == 0)
> +		ret = avails;
> +
> +	return ret;
> +}
> +
> +int
> +rte_uacce_queue_alloc(struct rte_uacce_device *dev, struct rte_uacce_qcontex *qctx)
> +{
> +	memset(qctx, 0, sizeof(*qctx));
> +
> +	qctx->fd = open(dev->cdev_path, O_RDWR | O_CLOEXEC);
> +	if (qctx->fd >= 0) {
> +		qctx->dev = dev;
> +		return 0;
> +	}
> +
> +	return -EIO;
> +}
> +
> +void
> +rte_uacce_queue_free(struct rte_uacce_qcontex *qctx)
> +{
> +	if (qctx->fd >= 0)
> +		close(qctx->fd);
> +	memset(qctx, 0, sizeof(*qctx));
> +	qctx->fd = -1;
> +}
> +
> +int
> +rte_uacce_queue_start(struct rte_uacce_qcontex *qctx)
> +{
> +#define UACCE_CMD_START_Q	_IO('W', 0)
> +	return ioctl(qctx->fd, UACCE_CMD_START_Q);
> +}
> +
> +int
> +rte_uacce_queue_ioctl(struct rte_uacce_qcontex *qctx, unsigned long cmd, void *arg)
> +{
> +	if (arg == NULL)
> +		return ioctl(qctx->fd, cmd);
> +
> +	return ioctl(qctx->fd, cmd, arg);
> +}
> +
> +void *
> +rte_uacce_queue_mmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt)
> +{
> +	size_t size = qctx->dev->qfrt_sz[qfrt];
> +	off_t off = qfrt * getpagesize();
> +	void *addr;
> +
> +	if (size == 0 || qctx->qfrt_base[qfrt] != NULL) {
> +		UACCE_BUS_ERR("failed to mmap for %s, size is zero or already mmapped!",
> +			      qctx->dev->name);
> +		return NULL;
> +	}
> +
> +	addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, qctx->fd, off);
> +	if (addr == MAP_FAILED) {
> +		UACCE_BUS_ERR("failed to mmap for %s, qfrt %d err %d!",
> +			      qctx->dev->name, qfrt, -errno);
> +		return NULL;
> +	}
> +	qctx->qfrt_base[qfrt] = addr;
> +
> +	return addr;
> +}
> +
> +void
> +rte_uacce_queue_unmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt)
> +{
> +	if (qctx->qfrt_base[qfrt] != NULL) {
> +		munmap(qctx->qfrt_base[qfrt], qctx->dev->qfrt_sz[qfrt]);
> +		qctx->qfrt_base[qfrt] = NULL;
> +	}
> +}
> +
> +void
> +rte_uacce_register(struct rte_uacce_driver *driver)
> +{
> +	TAILQ_INSERT_TAIL(&uacce_bus.driver_list, driver, next);
> +	driver->bus = &uacce_bus;
> +}
> +
> +void
> +rte_uacce_unregister(struct rte_uacce_driver *driver)
> +{
> +	TAILQ_REMOVE(&uacce_bus.driver_list, driver, next);
> +	driver->bus = NULL;
> +}
> +
> +static struct rte_uacce_bus uacce_bus = {
> +	.bus = {
> +		.scan = uacce_scan,
> +		.probe = uacce_probe,
> +		.cleanup = uacce_cleanup,
> +		.plug = uacce_plug,
> +		.unplug = uacce_unplug,
> +		.find_device = uacce_find_device,
> +		.parse = uacce_parse,
> +		.dev_iterate = uacce_dev_iterate,
> +	},
> +	.device_list = TAILQ_HEAD_INITIALIZER(uacce_bus.device_list),
> +	.driver_list = TAILQ_HEAD_INITIALIZER(uacce_bus.driver_list),
> +};
> +
> +RTE_REGISTER_BUS(uacce, uacce_bus.bus);
> +RTE_LOG_REGISTER_DEFAULT(uacce_bus_logtype, NOTICE);
> diff --git a/drivers/bus/uacce/version.map b/drivers/bus/uacce/version.map
> new file mode 100644
> index 0000000000..533b2ea0d8
> --- /dev/null
> +++ b/drivers/bus/uacce/version.map
> @@ -0,0 +1,15 @@
> +INTERNAL {
> +	global:
> +
> +	rte_uacce_avail_queues;
> +	rte_uacce_queue_alloc;
> +	rte_uacce_queue_free;
> +	rte_uacce_queue_ioctl;
> +	rte_uacce_queue_mmap;
> +	rte_uacce_queue_start;
> +	rte_uacce_queue_unmap;
> +	rte_uacce_register;
> +	rte_uacce_unregister;
> +
> +	local: *;
> +};

^ permalink raw reply	[relevance 0%]

* RE: [PATCH] build: fix linker warnings about undefined symbols
  2024-01-12 20:11  0%       ` Tyler Retzlaff
@ 2024-01-12 20:49  0%         ` Morten Brørup
  0 siblings, 0 replies; 200+ results
From: Morten Brørup @ 2024-01-12 20:49 UTC (permalink / raw)
  To: Tyler Retzlaff, Bruce Richardson; +Cc: dev

> From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com]
> Sent: Friday, 12 January 2024 21.11
> 
> On Thu, Jan 11, 2024 at 09:48:33AM +0000, Bruce Richardson wrote:
> > On Thu, Jan 11, 2024 at 10:38:05AM +0100, Morten Brørup wrote:
> > > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com]
> > > > Sent: Wednesday, 10 January 2024 17.58
> > > >
> > > > On Wed, Jan 10, 2024 at 03:01:03PM +0000, Bruce Richardson wrote:
> > > > > The default behaviour of "ld.lld" has changed, so it now prints
> out
> > > > > warnings about entries in the version.map file which don't
> exist in
> > > > > the current build. Since we use our version.map file simply to
> filter
> > > > > out the functions we don't want made public, we include in it
> all
> > > > > functions across all OS's and builds that we want public if
> present.
> > > > > This causes these ld warnings to be emitted, e.g. on BSD, which
> is
> > > > > missing functionality found on Linux. For example:
> > > > >
> > > > > * hpet functions in EAL
> > > > > * regexdev enqueue and dequeue burst
> > > > > * eventdev event_timer functions
> > > > >
> > > > > Easiest solution, without major rework of how we use our
> version.map
> > > > > files, and without dynamically generating them per-build, is to
> pass
> > > > > the --undefined-version flag to the linker, to restore the old
> > > > > behaviour.
> > > > >
> > > > > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > > > > ---
> > > >
> > > > Acked-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> > > >
> > > > i don't know if has ever been discussed but a way to achieve a
> similar
> > > > outcome would be to introduce a visibility macro allowing the
> data and
> > > > function symbols to be explicitly made visible while making the
> build
> > > > default hidden.
> > > >
> > > > https://gcc.gnu.org/wiki/Visibility
> > >
> > > This looks interesting!
> > > Declaring a function "public" directly in its header seems much
> simpler to manage than having to add it to the version.map file too.
> > >
> > > I wonder if function versioning is still supported if using this
> instead of version.map files?
> > > Of if there are other relevant reasons for continuing to use the
> version.map files instead of this?
> > >
> >
> > I don't see in that wiki page and details of how to mark symbols with
> > different ABI versions. For example, as well as listing what
> functions are
> > public, our version.map files also identify the ABI version (e.g.
> DPDK_24)
> > they belong to, or whether they are experimental or internal. Having
> them
> > all in the version file also makes it easy to see how many
> experimental
> > functions we have in each component.
> 
> you can use symver in combination with visibility default
> 
> https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
> 
> anyway just food for thought, it would get me out of having to hack &
> enhance the .def from .map generation and unfortunately even with that
> there are going to be cases where i still have to annotate the actual
> symbol export in code (for windows).
> 
> just thought a more unified approach for all might appeal.

Assuming that we truly want DPDK to support Windows, a more unified approach is a reasonable ask.

If we can eliminate the technical obstacles, we should pursue it.

We may have to sacrifice some "nice to have" advantages of the version.map files along the way, such as having easy access to the list of experimental functions in the version.map file.


^ permalink raw reply	[relevance 0%]

* Re: [PATCH] build: fix linker warnings about undefined symbols
  2024-01-11  9:48  4%     ` Bruce Richardson
@ 2024-01-12 20:11  0%       ` Tyler Retzlaff
  2024-01-12 20:49  0%         ` Morten Brørup
  0 siblings, 1 reply; 200+ results
From: Tyler Retzlaff @ 2024-01-12 20:11 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: Morten Brørup, dev

On Thu, Jan 11, 2024 at 09:48:33AM +0000, Bruce Richardson wrote:
> On Thu, Jan 11, 2024 at 10:38:05AM +0100, Morten Brørup wrote:
> > > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com]
> > > Sent: Wednesday, 10 January 2024 17.58
> > > 
> > > On Wed, Jan 10, 2024 at 03:01:03PM +0000, Bruce Richardson wrote:
> > > > The default behaviour of "ld.lld" has changed, so it now prints out
> > > > warnings about entries in the version.map file which don't exist in
> > > > the current build. Since we use our version.map file simply to filter
> > > > out the functions we don't want made public, we include in it all
> > > > functions across all OS's and builds that we want public if present.
> > > > This causes these ld warnings to be emitted, e.g. on BSD, which is
> > > > missing functionality found on Linux. For example:
> > > >
> > > > * hpet functions in EAL
> > > > * regexdev enqueue and dequeue burst
> > > > * eventdev event_timer functions
> > > >
> > > > Easiest solution, without major rework of how we use our version.map
> > > > files, and without dynamically generating them per-build, is to pass
> > > > the --undefined-version flag to the linker, to restore the old
> > > > behaviour.
> > > >
> > > > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > > > ---
> > > 
> > > Acked-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> > > 
> > > i don't know if has ever been discussed but a way to achieve a similar
> > > outcome would be to introduce a visibility macro allowing the data and
> > > function symbols to be explicitly made visible while making the build
> > > default hidden.
> > > 
> > > https://gcc.gnu.org/wiki/Visibility
> > 
> > This looks interesting!
> > Declaring a function "public" directly in its header seems much simpler to manage than having to add it to the version.map file too.
> > 
> > I wonder if function versioning is still supported if using this instead of version.map files?
> > Of if there are other relevant reasons for continuing to use the version.map files instead of this?
> > 
> 
> I don't see in that wiki page and details of how to mark symbols with
> different ABI versions. For example, as well as listing what functions are
> public, our version.map files also identify the ABI version (e.g. DPDK_24)
> they belong to, or whether they are experimental or internal. Having them
> all in the version file also makes it easy to see how many experimental
> functions we have in each component.

you can use symver in combination with visibility default

https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html

anyway just food for thought, it would get me out of having to hack &
enhance the .def from .map generation and unfortunately even with that
there are going to be cases where i still have to annotate the actual
symbol export in code (for windows).

just thought a more unified approach for all might appeal.

ty

> 
> /Bruce

^ permalink raw reply	[relevance 0%]

* [RFC v3] tap: rework the BPF header parsing
  2024-01-12 13:48  1% [PATCH] net/tap: Modified TAP BPF program as per the Kernel-version upgrade requirements madhuker.mythri
@ 2024-01-12 17:53  1% ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2024-01-12 17:53 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Cleanup the header parsing.
  - bpf load helpers
  - split IPv4 and IPv6 into seperate functions
  - drop incorrect VLAN header parsing
  - simplify the check for Ipv4 fragments
  - support IPv4 options
  - support IPv6 extension headers
  - fix the handling of L3 only hash
  - allow using non-default key
  - use standard network header structs
  - use temporary variables to avoid so many casts
  - stick to kernel data types (ie __u32)
  - fix support for non-default key

  - use new BPF map format based off of BTF
  - use system BPF headers and helpers

This is based of the BPF map work in earlier patch
from Madhuker Mythri <madhuker.mythri@oracle.com>

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
This is still work in progress.
Needs more testing.
Not sure it is worth splitting into smaller patches.

 drivers/net/tap/bpf/Makefile          |   14 +-
 drivers/net/tap/bpf/bpf_api.h         |  276 ---
 drivers/net/tap/bpf/bpf_elf.h         |   53 -
 drivers/net/tap/bpf/tap_bpf_program.c |  346 ++-
 drivers/net/tap/tap_bpf_api.c         |    5 +-
 drivers/net/tap/tap_bpf_insns.h       | 3288 +++++++++++++------------
 drivers/net/tap/tap_flow.c            |   43 +
 7 files changed, 1920 insertions(+), 2105 deletions(-)
 delete mode 100644 drivers/net/tap/bpf/bpf_api.h
 delete mode 100644 drivers/net/tap/bpf/bpf_elf.h

diff --git a/drivers/net/tap/bpf/Makefile b/drivers/net/tap/bpf/Makefile
index 9efeeb1bc704..20a51f1ef4e1 100644
--- a/drivers/net/tap/bpf/Makefile
+++ b/drivers/net/tap/bpf/Makefile
@@ -2,9 +2,14 @@
 # This file is not built as part of normal DPDK build.
 # It is used to generate the eBPF code for TAP RSS.
 
-CLANG=clang
-CLANG_OPTS=-O2
-TARGET=../tap_bpf_insns.h
+CLANG = clang
+CLANG_OPTS = -g -O2 -Wall -Wextra -target bpf
+
+TARGET = ../tap_bpf_insns.h
+
+# Get Clang's default includes on this system.
+CLANG_BPF_SYS_INCLUDES ?= $(shell $(CLANG) -v -E - </dev/null 2>&1 \
+	| sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }')
 
 all: $(TARGET)
 
@@ -12,8 +17,7 @@ clean:
 	rm tap_bpf_program.o $(TARGET)
 
 tap_bpf_program.o: tap_bpf_program.c
-	$(CLANG) $(CLANG_OPTS) -emit-llvm -c $< -o - | \
-	llc -march=bpf -filetype=obj -o $@
+	$(CLANG) $(CLANG_OPTS) $(CLANG_BPF_SYS_INCLUDES) -c $< -o $@
 
 $(TARGET): tap_bpf_program.o
 	python3 bpf_extract.py -stap_bpf_program.c -o $@ $<
diff --git a/drivers/net/tap/bpf/bpf_api.h b/drivers/net/tap/bpf/bpf_api.h
deleted file mode 100644
index 2638a8a4ac9a..000000000000
--- a/drivers/net/tap/bpf/bpf_api.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-
-#ifndef __BPF_API__
-#define __BPF_API__
-
-/* Note:
- *
- * This file can be included into eBPF kernel programs. It contains
- * a couple of useful helper functions, map/section ABI (bpf_elf.h),
- * misc macros and some eBPF specific LLVM built-ins.
- */
-
-#include <stdint.h>
-
-#include <linux/pkt_cls.h>
-#include <linux/bpf.h>
-#include <linux/filter.h>
-
-#include <asm/byteorder.h>
-
-#include "bpf_elf.h"
-
-/** libbpf pin type. */
-enum libbpf_pin_type {
-	LIBBPF_PIN_NONE,
-	/* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */
-	LIBBPF_PIN_BY_NAME,
-};
-
-/** Type helper macros. */
-
-#define __uint(name, val) int (*name)[val]
-#define __type(name, val) typeof(val) *name
-#define __array(name, val) typeof(val) *name[]
-
-/** Misc macros. */
-
-#ifndef __stringify
-# define __stringify(X)		#X
-#endif
-
-#ifndef __maybe_unused
-# define __maybe_unused		__attribute__((__unused__))
-#endif
-
-#ifndef offsetof
-# define offsetof(TYPE, MEMBER)	__builtin_offsetof(TYPE, MEMBER)
-#endif
-
-#ifndef likely
-# define likely(X)		__builtin_expect(!!(X), 1)
-#endif
-
-#ifndef unlikely
-# define unlikely(X)		__builtin_expect(!!(X), 0)
-#endif
-
-#ifndef htons
-# define htons(X)		__constant_htons((X))
-#endif
-
-#ifndef ntohs
-# define ntohs(X)		__constant_ntohs((X))
-#endif
-
-#ifndef htonl
-# define htonl(X)		__constant_htonl((X))
-#endif
-
-#ifndef ntohl
-# define ntohl(X)		__constant_ntohl((X))
-#endif
-
-#ifndef __inline__
-# define __inline__		__attribute__((always_inline))
-#endif
-
-/** Section helper macros. */
-
-#ifndef __section
-# define __section(NAME)						\
-	__attribute__((section(NAME), used))
-#endif
-
-#ifndef __section_tail
-# define __section_tail(ID, KEY)					\
-	__section(__stringify(ID) "/" __stringify(KEY))
-#endif
-
-#ifndef __section_xdp_entry
-# define __section_xdp_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_cls_entry
-# define __section_cls_entry						\
-	__section(ELF_SECTION_CLASSIFIER)
-#endif
-
-#ifndef __section_act_entry
-# define __section_act_entry						\
-	__section(ELF_SECTION_ACTION)
-#endif
-
-#ifndef __section_lwt_entry
-# define __section_lwt_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_license
-# define __section_license						\
-	__section(ELF_SECTION_LICENSE)
-#endif
-
-#ifndef __section_maps
-# define __section_maps							\
-	__section(ELF_SECTION_MAPS)
-#endif
-
-/** Declaration helper macros. */
-
-#ifndef BPF_LICENSE
-# define BPF_LICENSE(NAME)						\
-	char ____license[] __section_license = NAME
-#endif
-
-/** Classifier helper */
-
-#ifndef BPF_H_DEFAULT
-# define BPF_H_DEFAULT	-1
-#endif
-
-/** BPF helper functions for tc. Individual flags are in linux/bpf.h */
-
-#ifndef __BPF_FUNC
-# define __BPF_FUNC(NAME, ...)						\
-	(* NAME)(__VA_ARGS__) __maybe_unused
-#endif
-
-#ifndef BPF_FUNC
-# define BPF_FUNC(NAME, ...)						\
-	__BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME
-#endif
-
-/* Map access/manipulation */
-static void *BPF_FUNC(map_lookup_elem, void *map, const void *key);
-static int BPF_FUNC(map_update_elem, void *map, const void *key,
-		    const void *value, uint32_t flags);
-static int BPF_FUNC(map_delete_elem, void *map, const void *key);
-
-/* Time access */
-static uint64_t BPF_FUNC(ktime_get_ns);
-
-/* Debugging */
-
-/* FIXME: __attribute__ ((format(printf, 1, 3))) not possible unless
- * llvm bug https://llvm.org/bugs/show_bug.cgi?id=26243 gets resolved.
- * It would require ____fmt to be made const, which generates a reloc
- * entry (non-map).
- */
-static void BPF_FUNC(trace_printk, const char *fmt, int fmt_size, ...);
-
-#ifndef printt
-# define printt(fmt, ...)						\
-	({								\
-		char ____fmt[] = fmt;					\
-		trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__);	\
-	})
-#endif
-
-/* Random numbers */
-static uint32_t BPF_FUNC(get_prandom_u32);
-
-/* Tail calls */
-static void BPF_FUNC(tail_call, struct __sk_buff *skb, void *map,
-		     uint32_t index);
-
-/* System helpers */
-static uint32_t BPF_FUNC(get_smp_processor_id);
-static uint32_t BPF_FUNC(get_numa_node_id);
-
-/* Packet misc meta data */
-static uint32_t BPF_FUNC(get_cgroup_classid, struct __sk_buff *skb);
-static int BPF_FUNC(skb_under_cgroup, void *map, uint32_t index);
-
-static uint32_t BPF_FUNC(get_route_realm, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(get_hash_recalc, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(set_hash_invalid, struct __sk_buff *skb);
-
-/* Packet redirection */
-static int BPF_FUNC(redirect, int ifindex, uint32_t flags);
-static int BPF_FUNC(clone_redirect, struct __sk_buff *skb, int ifindex,
-		    uint32_t flags);
-
-/* Packet manipulation */
-static int BPF_FUNC(skb_load_bytes, struct __sk_buff *skb, uint32_t off,
-		    void *to, uint32_t len);
-static int BPF_FUNC(skb_store_bytes, struct __sk_buff *skb, uint32_t off,
-		    const void *from, uint32_t len, uint32_t flags);
-
-static int BPF_FUNC(l3_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(l4_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(csum_diff, const void *from, uint32_t from_size,
-		    const void *to, uint32_t to_size, uint32_t seed);
-static int BPF_FUNC(csum_update, struct __sk_buff *skb, uint32_t wsum);
-
-static int BPF_FUNC(skb_change_type, struct __sk_buff *skb, uint32_t type);
-static int BPF_FUNC(skb_change_proto, struct __sk_buff *skb, uint32_t proto,
-		    uint32_t flags);
-static int BPF_FUNC(skb_change_tail, struct __sk_buff *skb, uint32_t nlen,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_pull_data, struct __sk_buff *skb, uint32_t len);
-
-/* Event notification */
-static int __BPF_FUNC(skb_event_output, struct __sk_buff *skb, void *map,
-		      uint64_t index, const void *data, uint32_t size) =
-		      (void *) BPF_FUNC_perf_event_output;
-
-/* Packet vlan encap/decap */
-static int BPF_FUNC(skb_vlan_push, struct __sk_buff *skb, uint16_t proto,
-		    uint16_t vlan_tci);
-static int BPF_FUNC(skb_vlan_pop, struct __sk_buff *skb);
-
-/* Packet tunnel encap/decap */
-static int BPF_FUNC(skb_get_tunnel_key, struct __sk_buff *skb,
-		    struct bpf_tunnel_key *to, uint32_t size, uint32_t flags);
-static int BPF_FUNC(skb_set_tunnel_key, struct __sk_buff *skb,
-		    const struct bpf_tunnel_key *from, uint32_t size,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_get_tunnel_opt, struct __sk_buff *skb,
-		    void *to, uint32_t size);
-static int BPF_FUNC(skb_set_tunnel_opt, struct __sk_buff *skb,
-		    const void *from, uint32_t size);
-
-/** LLVM built-ins, mem*() routines work for constant size */
-
-#ifndef lock_xadd
-# define lock_xadd(ptr, val)	((void) __sync_fetch_and_add(ptr, val))
-#endif
-
-#ifndef memset
-# define memset(s, c, n)	__builtin_memset((s), (c), (n))
-#endif
-
-#ifndef memcpy
-# define memcpy(d, s, n)	__builtin_memcpy((d), (s), (n))
-#endif
-
-#ifndef memmove
-# define memmove(d, s, n)	__builtin_memmove((d), (s), (n))
-#endif
-
-/* FIXME: __builtin_memcmp() is not yet fully usable unless llvm bug
- * https://llvm.org/bugs/show_bug.cgi?id=26218 gets resolved. Also
- * this one would generate a reloc entry (non-map), otherwise.
- */
-#if 0
-#ifndef memcmp
-# define memcmp(a, b, n)	__builtin_memcmp((a), (b), (n))
-#endif
-#endif
-
-unsigned long long load_byte(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.byte");
-
-unsigned long long load_half(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.half");
-
-unsigned long long load_word(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.word");
-
-#endif /* __BPF_API__ */
diff --git a/drivers/net/tap/bpf/bpf_elf.h b/drivers/net/tap/bpf/bpf_elf.h
deleted file mode 100644
index ea8a11c95c0f..000000000000
--- a/drivers/net/tap/bpf/bpf_elf.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-#ifndef __BPF_ELF__
-#define __BPF_ELF__
-
-#include <asm/types.h>
-
-/* Note:
- *
- * Below ELF section names and bpf_elf_map structure definition
- * are not (!) kernel ABI. It's rather a "contract" between the
- * application and the BPF loader in tc. For compatibility, the
- * section names should stay as-is. Introduction of aliases, if
- * needed, are a possibility, though.
- */
-
-/* ELF section names, etc */
-#define ELF_SECTION_LICENSE	"license"
-#define ELF_SECTION_MAPS	"maps"
-#define ELF_SECTION_PROG	"prog"
-#define ELF_SECTION_CLASSIFIER	"classifier"
-#define ELF_SECTION_ACTION	"action"
-
-#define ELF_MAX_MAPS		64
-#define ELF_MAX_LICENSE_LEN	128
-
-/* Object pinning settings */
-#define PIN_NONE		0
-#define PIN_OBJECT_NS		1
-#define PIN_GLOBAL_NS		2
-
-/* ELF map definition */
-struct bpf_elf_map {
-	__u32 type;
-	__u32 size_key;
-	__u32 size_value;
-	__u32 max_elem;
-	__u32 flags;
-	__u32 id;
-	__u32 pinning;
-	__u32 inner_id;
-	__u32 inner_idx;
-};
-
-#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val)		\
-	struct ____btf_map_##name {				\
-		type_key key;					\
-		type_val value;					\
-	};							\
-	struct ____btf_map_##name				\
-	    __attribute__ ((section(".maps." #name), used))	\
-	    ____btf_map_##name = { }
-
-#endif /* __BPF_ELF__ */
diff --git a/drivers/net/tap/bpf/tap_bpf_program.c b/drivers/net/tap/bpf/tap_bpf_program.c
index f05aed021c30..0842fb437c4e 100644
--- a/drivers/net/tap/bpf/tap_bpf_program.c
+++ b/drivers/net/tap/bpf/tap_bpf_program.c
@@ -2,58 +2,36 @@
  * Copyright 2017 Mellanox Technologies, Ltd
  */
 
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <asm/types.h>
+
 #include <linux/in.h>
-#include <linux/if.h>
 #include <linux/if_ether.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
-#include <linux/if_tunnel.h>
-#include <linux/filter.h>
-
-#include "bpf_api.h"
-#include "bpf_elf.h"
-#include "../tap_rss.h"
+#include <linux/pkt_cls.h>
+#include <linux/bpf.h>
 
-/** Create IPv4 address */
-#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
-		(((b) & 0xff) << 16) | \
-		(((c) & 0xff) << 8)  | \
-		((d) & 0xff))
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
 
-#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
-		((b) & 0xff))
+#include "../tap_rss.h"
 
 /*
  * The queue number is offset by a unique QUEUE_OFFSET, to distinguish
  * packets that have gone through this rule (skb->cb[1] != 0) from others.
  */
 #define QUEUE_OFFSET		0x7cafe800
-#define PIN_GLOBAL_NS		2
-
-#define KEY_IDX			0
-#define BPF_MAP_ID_KEY	1
-
-struct vlan_hdr {
-	__be16 proto;
-	__be16 tci;
-};
-
-struct bpf_elf_map __attribute__((section("maps"), used))
-map_keys = {
-	.type           =       BPF_MAP_TYPE_HASH,
-	.id             =       BPF_MAP_ID_KEY,
-	.size_key       =       sizeof(__u32),
-	.size_value     =       sizeof(struct rss_key),
-	.max_elem       =       256,
-	.pinning        =       PIN_GLOBAL_NS,
-};
-
-__section("cls_q") int
+
+#define IP_MF		0x2000		/** IP header Flags **/
+#define IP_OFFSET	0x1FFF		/** IP header fragment offset **/
+
+struct {
+	__uint(type, BPF_MAP_TYPE_HASH);
+	__type(key, __u32);
+	__type(value, struct rss_key);
+	__uint(max_entries, 256);
+} map_keys SEC(".maps");
+
+SEC("cls_q") int
 match_q(struct __sk_buff *skb)
 {
 	__u32 queue = skb->cb[1];
@@ -71,7 +49,6 @@ match_q(struct __sk_buff *skb)
 	return TC_ACT_UNSPEC;
 }
 
-
 struct ipv4_l3_l4_tuple {
 	__u32    src_addr;
 	__u32    dst_addr;
@@ -80,176 +57,187 @@ struct ipv4_l3_l4_tuple {
 } __attribute__((packed));
 
 struct ipv6_l3_l4_tuple {
-	__u8        src_addr[16];
-	__u8        dst_addr[16];
+	__u32       src_addr[4];
+	__u32       dst_addr[4];
 	__u16       dport;
 	__u16       sport;
 } __attribute__((packed));
 
-static const __u8 def_rss_key[TAP_RSS_HASH_KEY_SIZE] = {
-	0xd1, 0x81, 0xc6, 0x2c,
-	0xf7, 0xf4, 0xdb, 0x5b,
-	0x19, 0x83, 0xa2, 0xfc,
-	0x94, 0x3e, 0x1a, 0xdb,
-	0xd9, 0x38, 0x9e, 0x6b,
-	0xd1, 0x03, 0x9c, 0x2c,
-	0xa7, 0x44, 0x99, 0xad,
-	0x59, 0x3d, 0x56, 0xd9,
-	0xf3, 0x25, 0x3c, 0x06,
-	0x2a, 0xdc, 0x1f, 0xfc,
-};
-
 static __u32  __attribute__((always_inline))
-rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
-		__u8 input_len)
+softrss_be(const __u32 *input_tuple, __u32 input_len, const void *rss_key)
 {
 	__u32 i, j, hash = 0;
+	const __u32 *key32 = rss_key;
+
 #pragma unroll
 	for (j = 0; j < input_len; j++) {
 #pragma unroll
 		for (i = 0; i < 32; i++) {
-			if (input_tuple[j] & (1U << (31 - i))) {
-				hash ^= ((const __u32 *)def_rss_key)[j] << i |
-				(__u32)((uint64_t)
-				(((const __u32 *)def_rss_key)[j + 1])
-					>> (32 - i));
-			}
+			if (input_tuple[j] & (1U << (31 - i)))
+				hash ^= key32[j] << i | key32[j + 1] >> (32 - i);
 		}
 	}
 	return hash;
 }
 
-static int __attribute__((always_inline))
-rss_l3_l4(struct __sk_buff *skb)
+static int
+parse_ipv4(struct __sk_buff *skb, const struct rss_key *rsskey, __u32 *hash)
 {
-	void *data_end = (void *)(long)skb->data_end;
-	void *data = (void *)(long)skb->data;
-	__u16 proto = (__u16)skb->protocol;
-	__u32 key_idx = 0xdeadbeef;
-	__u32 hash;
-	struct rss_key *rsskey;
-	__u64 off = ETH_HLEN;
-	int j;
-	__u8 *key = 0;
-	__u32 len;
-	__u32 queue = 0;
-	bool mf = 0;
-	__u16 frag_off = 0;
-
-	rsskey = map_lookup_elem(&map_keys, &key_idx);
-	if (!rsskey) {
-		printt("hash(): rss key is not configured\n");
+	struct iphdr iph;
+	__u32 off = 0;
+
+	if (bpf_skb_load_bytes_relative(skb, off, &iph, sizeof(iph), BPF_HDR_START_NET))
 		return TC_ACT_OK;
+	off += iph.ihl * 4;
+
+	struct ipv4_l3_l4_tuple v4_tuple = {
+		.src_addr = bpf_ntohl(iph.saddr),
+		.dst_addr = bpf_ntohl(iph.daddr),
+	};
+
+	if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3)) {
+		*hash = softrss_be((__u32 *)&v4_tuple, 2, rsskey->key);
+		return TC_ACT_RECLASSIFY;
 	}
-	key = (__u8 *)rsskey->key;
 
-	/* Get correct proto for 802.1ad */
-	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
-		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
-		    sizeof(proto) > data_end)
+	/* Get ports for non-fragmented TCP/UDP */
+	if ( (iph.frag_off & bpf_htons(IP_MF | IP_OFFSET)) != 0 &&
+	     (iph.protocol == IPPROTO_UDP || iph.protocol == IPPROTO_TCP)) {
+		__u16 src_dst_port[2];
+
+		if (bpf_skb_load_bytes_relative(skb, off, &src_dst_port, sizeof(src_dst_port),
+						BPF_HDR_START_NET))
 			return TC_ACT_OK;
-		proto = *(__u16 *)(data + ETH_ALEN * 2 +
-				   sizeof(struct vlan_hdr));
-		off += sizeof(struct vlan_hdr);
+
+		v4_tuple.sport = bpf_ntohs(src_dst_port[0]);
+		v4_tuple.dport = bpf_ntohs(src_dst_port[1]);
 	}
 
-	if (proto == htons(ETH_P_IP)) {
-		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
-			> data_end)
-			return TC_ACT_OK;
+	*hash = softrss_be((__u32 *)&v4_tuple, 3, rsskey->key);
 
-		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
-		__u8 *frag_off_addr = data + off + offsetof(struct iphdr, frag_off);
-		__u8 *prot_addr = data + off + offsetof(struct iphdr, protocol);
-		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
-		struct ipv4_l3_l4_tuple v4_tuple = {
-			.src_addr = IPv4(*(src_dst_addr + 0),
-					*(src_dst_addr + 1),
-					*(src_dst_addr + 2),
-					*(src_dst_addr + 3)),
-			.dst_addr = IPv4(*(src_dst_addr + 4),
-					*(src_dst_addr + 5),
-					*(src_dst_addr + 6),
-					*(src_dst_addr + 7)),
-			.sport = 0,
-			.dport = 0,
-		};
-		/** Fetch the L4-payer port numbers only in-case of TCP/UDP
-		 ** and also if the packet is not fragmented. Since fragmented
-		 ** chunks do not have L4 TCP/UDP header.
-		 **/
-		if (*prot_addr == IPPROTO_UDP || *prot_addr == IPPROTO_TCP) {
-			frag_off = PORT(*(frag_off_addr + 0),
-					*(frag_off_addr + 1));
-			mf = frag_off & 0x2000;
-			frag_off = frag_off & 0x1fff;
-			if (mf == 0 && frag_off == 0) {
-				v4_tuple.sport = PORT(*(src_dst_port + 0),
-						*(src_dst_port + 1));
-				v4_tuple.dport = PORT(*(src_dst_port + 2),
-						*(src_dst_port + 3));
-			}
-		}
-		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
-	} else if (proto == htons(ETH_P_IPV6)) {
-		if (data + off + sizeof(struct ipv6hdr) +
-					sizeof(__u32) > data_end)
-			return TC_ACT_OK;
-		__u8 *src_dst_addr = data + off +
-					offsetof(struct ipv6hdr, saddr);
-		__u8 *src_dst_port = data + off +
-					sizeof(struct ipv6hdr);
-		__u8 *next_hdr = data + off +
-					offsetof(struct ipv6hdr, nexthdr);
-
-		struct ipv6_l3_l4_tuple v6_tuple;
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.src_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + j));
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.dst_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + 4 + j));
-
-		/** Fetch the L4 header port-numbers only if next-header
-		 * is TCP/UDP **/
-		if (*next_hdr == IPPROTO_UDP || *next_hdr == IPPROTO_TCP) {
-			v6_tuple.sport = PORT(*(src_dst_port + 0),
-				      *(src_dst_port + 1));
-			v6_tuple.dport = PORT(*(src_dst_port + 2),
-				      *(src_dst_port + 3));
-		} else {
-			v6_tuple.sport = 0;
-			v6_tuple.dport = 0;
+	return TC_ACT_RECLASSIFY;
+}
+
+/* parse ipv6 extended headers, update offset and return next proto */
+static int
+skip_ip6_ext(__u16 proto, struct __sk_buff *skb, __u32 *off, int *frag)
+{
+	struct ext_hdr {
+		__u8 next_hdr;
+		__u8 len;
+	} xh;
+	unsigned int i;
+
+	*frag = 0;
+
+#define MAX_EXT_HDRS 5
+#pragma unroll
+	for (i = 0; i < MAX_EXT_HDRS; i++) {
+		switch (proto) {
+		case IPPROTO_HOPOPTS:
+		case IPPROTO_ROUTING:
+		case IPPROTO_DSTOPTS:
+			if (bpf_skb_load_bytes_relative(skb, *off, &xh, sizeof(xh), BPF_HDR_START_NET))
+				return -1;
+
+			*off += (xh.len + 1) * 8;
+			proto = xh.next_hdr;
+			break;
+		case IPPROTO_FRAGMENT:
+			if (bpf_skb_load_bytes_relative(skb, *off, &xh, sizeof(xh), BPF_HDR_START_NET))
+				return -1;
+
+			*off += 8;
+			proto = xh.next_hdr;
+			*frag = 1;
+			return proto; /* this is always the last ext hdr */
+		case IPPROTO_NONE:
+			return 0;
+		default:
+			return proto;
 		}
+	}
 
-		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
-	} else {
-		return TC_ACT_PIPE;
+	/* too many extension headers give up */
+	return -1;
+}
+
+static int
+parse_ipv6(struct __sk_buff *skb, const struct rss_key *rsskey, __u32 *hash)
+{
+	struct ipv6_l3_l4_tuple v6_tuple = { };
+	struct ipv6hdr ip6h;
+	__u32 off = 0, j;
+	int proto, frag;
+
+	if (bpf_skb_load_bytes_relative(skb, off, &ip6h, sizeof(ip6h), BPF_HDR_START_NET))
+		return TC_ACT_OK;
+	off += sizeof(ip6h);
+
+#pragma unroll
+	for (j = 0; j < 4; j++) {
+		v6_tuple.src_addr[j] = bpf_ntohl(ip6h.saddr.in6_u.u6_addr32[j]);
+		v6_tuple.dst_addr[j] = bpf_ntohl(ip6h.daddr.in6_u.u6_addr32[j]);
 	}
 
-	queue = rsskey->queues[(hash % rsskey->nb_queues) &
-				       (TAP_MAX_QUEUES - 1)];
-	skb->cb[1] = QUEUE_OFFSET + queue;
-	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
+	if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3)) {
+		*hash = softrss_be((__u32 *)&v6_tuple, 8, rsskey->key);
+		return TC_ACT_RECLASSIFY;
+	}
+
+	proto = skip_ip6_ext(ip6h.nexthdr, skb, &off, &frag);
+	if (proto < 0)
+		return TC_ACT_OK;
+
+	/* Fetch the L4 header port-numbers only if next-header is TCP/UDP */
+	if (!frag && (proto == IPPROTO_UDP || proto == IPPROTO_TCP)) {
+		__u16 src_dst_port[2];
+
+		if (bpf_skb_load_bytes_relative(skb, off, &src_dst_port, sizeof(src_dst_port),
+						BPF_HDR_START_NET))
+			return TC_ACT_OK;
+
+		v6_tuple.sport = bpf_ntohs(src_dst_port[0]);
+		v6_tuple.dport = bpf_ntohs(src_dst_port[1]);
+	}
 
+	*hash = softrss_be((__u32 *)&v6_tuple, 9, rsskey->key);
 	return TC_ACT_RECLASSIFY;
 }
 
-#define RSS(L)						\
-	__section(#L) int				\
-		L ## _hash(struct __sk_buff *skb)	\
-	{						\
-		return rss_ ## L (skb);			\
+SEC("l3_l4") int
+rss_l3_l4(struct __sk_buff *skb)
+{
+	const struct rss_key *rsskey;
+	__be16 proto = skb->protocol;
+	__u32 key_idx = 0xdeadbeef;
+	__u32 hash;
+	int ret;
+
+	rsskey = bpf_map_lookup_elem(&map_keys, &key_idx);
+	if (!rsskey) {
+		bpf_printk("hash(): rss key is not configured\n");
+		return TC_ACT_OK;
 	}
 
-RSS(l3_l4)
+	if (proto == bpf_htons(ETH_P_IP))
+		ret = parse_ipv4(skb, rsskey, &hash);
+	else if (proto == bpf_htons(ETH_P_IPV6))
+		ret = parse_ipv6(skb, rsskey, &hash);
+	else
+		ret = TC_ACT_PIPE;
+
+	if (ret == TC_ACT_RECLASSIFY) {
+		if (rsskey->nb_queues == 0) {
+			bpf_printk("hash(): num queues is zero?\n");
+			return TC_ACT_OK;
+		}
+
+		__u32 queue = rsskey->queues[(hash % rsskey->nb_queues) & (TAP_MAX_QUEUES - 1)];
+		skb->cb[1] = QUEUE_OFFSET + queue;
+	}
+
+	return ret;
+}
 
-BPF_LICENSE("Dual BSD/GPL");
+char _license[] SEC("license") = "Dual BSD/GPL";
diff --git a/drivers/net/tap/tap_bpf_api.c b/drivers/net/tap/tap_bpf_api.c
index 15283f8917ed..7e13d4b8b6ba 100644
--- a/drivers/net/tap/tap_bpf_api.c
+++ b/drivers/net/tap/tap_bpf_api.c
@@ -48,8 +48,9 @@ int tap_flow_bpf_cls_q(__u32 queue_idx)
  */
 int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
 {
-	l3_l4_hash_insns[4].imm = key_idx;
-	l3_l4_hash_insns[9].imm = map_fd;
+	l3_l4_hash_insns[1].imm = key_idx;
+	l3_l4_hash_insns[6].imm = map_fd;
+	l3_l4_hash_insns[6].src_reg = 1;
 
 	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
 		(struct bpf_insn *)l3_l4_hash_insns,
diff --git a/drivers/net/tap/tap_bpf_insns.h b/drivers/net/tap/tap_bpf_insns.h
index 53fa76c4e6b0..4999195b1486 100644
--- a/drivers/net/tap/tap_bpf_insns.h
+++ b/drivers/net/tap/tap_bpf_insns.h
@@ -24,1720 +24,1828 @@ static struct bpf_insn cls_q_insns[] = {
 };
 
 static struct bpf_insn l3_l4_hash_insns[] = {
-	{0xbf,    7,    1,        0, 0x00000000},
-	{0x61,    6,    7,       16, 0x00000000},
-	{0x61,    8,    7,       76, 0x00000000},
-	{0x61,    9,    7,       80, 0x00000000},
+	{0xbf,    9,    1,        0, 0x00000000},
+	{0x61,    6,    9,       16, 0x00000000},
 	{0x18,    1,    0,        0, 0xdeadbeef},
 	{0x00,    0,    0,        0, 0x00000000},
-	{0x63,   10,    1,       -4, 0x00000000},
+	{0x63,   10,    1,      -32, 0x00000000},
 	{0xbf,    2,   10,        0, 0x00000000},
-	{0x07,    2,    0,        0, 0xfffffffc},
+	{0x07,    2,    0,        0, 0xffffffe0},
 	{0x18,    1,    0,        0, 0x00000000},
 	{0x00,    0,    0,        0, 0x00000000},
 	{0x85,    0,    0,        0, 0x00000001},
-	{0x55,    0,    0,       21, 0x00000000},
-	{0xb7,    1,    0,        0, 0x00000a64},
-	{0x6b,   10,    1,      -16, 0x00000000},
-	{0x18,    1,    0,        0, 0x69666e6f},
-	{0x00,    0,    0,        0, 0x65727567},
-	{0x7b,   10,    1,      -24, 0x00000000},
-	{0x18,    1,    0,        0, 0x6e207369},
-	{0x00,    0,    0,        0, 0x6320746f},
-	{0x7b,   10,    1,      -32, 0x00000000},
-	{0x18,    1,    0,        0, 0x20737372},
-	{0x00,    0,    0,        0, 0x2079656b},
-	{0x7b,   10,    1,      -40, 0x00000000},
-	{0x18,    1,    0,        0, 0x68736168},
-	{0x00,    0,    0,        0, 0x203a2928},
-	{0x7b,   10,    1,      -48, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0x73,   10,    7,      -14, 0x00000000},
-	{0xbf,    1,   10,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0xffffffd0},
+	{0xbf,    7,    0,        0, 0x00000000},
+	{0x55,    7,    0,        6, 0x00000000},
+	{0x18,    1,    0,        0, 0x00000000},
+	{0x00,    0,    0,        0, 0x00000000},
 	{0xb7,    2,    0,        0, 0x00000023},
 	{0x85,    0,    0,        0, 0x00000006},
-	{0x05,    0,    0,     1680, 0x00000000},
-	{0xb7,    1,    0,        0, 0x0000000e},
-	{0x61,    2,    7,       20, 0x00000000},
-	{0x15,    2,    0,       10, 0x00000000},
-	{0x61,    2,    7,       28, 0x00000000},
-	{0x55,    2,    0,        8, 0x0000a888},
-	{0xbf,    2,    7,        0, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0xbf,    1,    8,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0x00000012},
-	{0x2d,    1,    9,     1670, 0x00000000},
-	{0xb7,    1,    0,        0, 0x00000012},
-	{0x69,    6,    8,       16, 0x00000000},
-	{0xbf,    7,    2,        0, 0x00000000},
+	{0xb7,    8,    0,        0, 0x00000000},
+	{0x05,    0,    0,      749, 0x00000000},
 	{0x57,    6,    0,        0, 0x0000ffff},
-	{0x7b,   10,    7,      -56, 0x00000000},
-	{0x15,    6,    0,      443, 0x0000dd86},
-	{0xb7,    7,    0,        0, 0x00000003},
-	{0x55,    6,    0,     1662, 0x00000008},
-	{0x0f,    8,    1,        0, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0xbf,    1,    8,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0x00000018},
-	{0x2d,    1,    9,     1657, 0x00000000},
-	{0xb7,    1,    0,        0, 0x00000000},
-	{0x71,    3,    8,       12, 0x00000000},
-	{0x71,    2,    8,        9, 0x00000000},
-	{0x15,    2,    0,        1, 0x00000011},
-	{0x55,    2,    0,       21, 0x00000006},
-	{0x71,    2,    8,        7, 0x00000000},
-	{0x71,    4,    8,        6, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x67,    5,    0,        0, 0x00000008},
-	{0x57,    5,    0,        0, 0x00001f00},
-	{0x4f,    5,    2,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x4f,    4,    5,        0, 0x00000000},
-	{0x55,    4,    0,       12, 0x00000000},
-	{0xbf,    2,    8,        0, 0x00000000},
-	{0x07,    2,    0,        0, 0x00000014},
-	{0x71,    4,    2,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000018},
-	{0x71,    1,    2,        1, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000010},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    4,    2,        3, 0x00000000},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    2,    2,        2, 0x00000000},
-	{0x67,    2,    0,        0, 0x00000008},
-	{0x4f,    1,    2,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000038},
-	{0xc7,    4,    0,        0, 0x00000038},
+	{0x15,    6,    0,      704, 0x0000dd86},
+	{0xb7,    8,    0,        0, 0x00000003},
+	{0x55,    6,    0,      745, 0x00000008},
+	{0xb7,    8,    0,        0, 0x00000000},
+	{0xbf,    3,   10,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0xffffffe8},
+	{0xbf,    1,    9,        0, 0x00000000},
 	{0xb7,    2,    0,        0, 0x00000000},
-	{0x65,    4,    0,        1, 0xffffffff},
-	{0xb7,    7,    0,        0, 0x2cc681d1},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x598d03a2},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb31a0745},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x66340e8a},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xcc681d15},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000004},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x98d03a2b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000002},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x31a07456},
-	{0x71,    4,    8,       13, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6340e8ad},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc681d15b},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d03a2b7},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1a07456f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x340e8ade},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x681d15bd},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd03a2b7b},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa07456f6},
-	{0x71,    3,    8,       14, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x40e8aded},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000038},
-	{0xc7,    4,    0,        0, 0x00000038},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0x81d15bdb},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x03a2b7b7},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x07456f6f},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x0e8adedf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1d15bdbf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000004},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3a2b7b7e},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000002},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7456f6fd},
-	{0x71,    4,    8,       15, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe8adedfa},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd15bdbf4},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa2b7b7e9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x456f6fd3},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8adedfa7},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x15bdbf4f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x2b7b7e9e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x56f6fd3d},
-	{0x71,    3,    8,       16, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xadedfa7b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000038},
-	{0xc7,    4,    0,        0, 0x00000038},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5bdbf4f7},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb7b7e9ef},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6f6fd3df},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xdedfa7bf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xbdbf4f7f},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000004},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7b7e9eff},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000002},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf6fd3dff},
-	{0x71,    4,    8,       17, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xedfa7bfe},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdbf4f7fc},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb7e9eff9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6fd3dff2},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdfa7bfe5},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbf4f7fca},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7e9eff94},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfd3dff28},
-	{0x71,    3,    8,       18, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfa7bfe51},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x67,    6,    0,        0, 0x00000038},
-	{0xc7,    6,    0,        0, 0x00000038},
-	{0xbf,    4,    5,        0, 0x00000000},
-	{0xa7,    4,    0,        0, 0xf4f7fca2},
-	{0x6d,    2,    6,        1, 0x00000000},
-	{0xbf,    4,    5,        0, 0x00000000},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000040},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xe9eff945},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000020},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd3dff28a},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000010},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xa7bfe514},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000008},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x4f7fca28},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x9eff9450},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x3dff28a0},
-	{0x71,    5,    8,       19, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x7bfe5141},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    7,    4,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf7fca283},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    7,    4,        0, 0x00000000},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xeff94506},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xdff28a0c},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xbfe51418},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7fca2831},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xff945063},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xff28a0c6},
-	{0x57,    5,    0,        0, 0x00000001},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xfe51418c},
-	{0xbf,    4,    1,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000020},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0xbf,    3,    7,        0, 0x00000000},
-	{0xa7,    3,    0,        0, 0xfca28319},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    3,    7,        0, 0x00000000},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0xb7,    4,    0,        0, 0x00000014},
+	{0xb7,    5,    0,        0, 0x00000001},
+	{0x85,    0,    0,        0, 0x00000044},
+	{0x55,    0,    0,      699, 0x00000000},
+	{0x61,    8,   10,       -8, 0x00000000},
+	{0xdc,    8,    0,        0, 0x00000020},
+	{0x61,    6,   10,      -12, 0x00000000},
+	{0xdc,    6,    0,        0, 0x00000020},
+	{0x71,    1,    7,      128, 0x00000000},
+	{0x57,    1,    0,        0, 0x00000001},
+	{0x15,    1,    0,      731, 0x00000000},
+	{0xb7,    1,    0,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x40000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf9450633},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        6, 0x00000000},
+	{0x61,    1,    7,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000001},
+	{0x61,    2,    7,        4, 0x00000000},
+	{0x77,    2,    0,        0, 0x0000001f},
+	{0x57,    2,    0,        0, 0x00000001},
+	{0x4f,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x20000000},
-	{0x79,    6,   10,      -56, 0x00000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf28a0c67},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000002},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000001e},
+	{0x57,    3,    0,        0, 0x00000003},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x10000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xe51418ce},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000003},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000001d},
+	{0x57,    3,    0,        0, 0x00000007},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x08000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xca28319d},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000004},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000001c},
+	{0x57,    3,    0,        0, 0x0000000f},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x04000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x9450633b},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000005},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000001b},
+	{0x57,    3,    0,        0, 0x0000001f},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x02000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x28a0c676},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000006},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000001a},
+	{0x57,    3,    0,        0, 0x0000003f},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x01000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x51418ced},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000007},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000019},
+	{0x57,    3,    0,        0, 0x0000007f},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00800000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xa28319db},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000008},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000018},
+	{0x57,    3,    0,        0, 0x000000ff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00400000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x450633b6},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000009},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000017},
+	{0x57,    3,    0,        0, 0x000001ff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00200000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8a0c676c},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000000a},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000016},
+	{0x57,    3,    0,        0, 0x000003ff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00100000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x1418ced8},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000000b},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000015},
+	{0x57,    3,    0,        0, 0x000007ff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00080000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x28319db1},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000000c},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000014},
+	{0x57,    3,    0,        0, 0x00000fff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00040000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x50633b63},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000000d},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000013},
+	{0x57,    3,    0,        0, 0x00001fff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00020000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xa0c676c6},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000000e},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000012},
+	{0x57,    3,    0,        0, 0x00003fff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00010000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x418ced8d},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000000f},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000011},
+	{0x57,    3,    0,        0, 0x00007fff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00008000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8319db1a},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000010},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000010},
+	{0x57,    3,    0,        0, 0x0000ffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00004000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x0633b634},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000011},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000000f},
+	{0x57,    3,    0,        0, 0x0001ffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00002000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x0c676c68},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000012},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000000e},
+	{0x57,    3,    0,        0, 0x0003ffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00001000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x18ced8d1},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000013},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000000d},
+	{0x57,    3,    0,        0, 0x0007ffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000800},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x319db1a3},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000014},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000000c},
+	{0x57,    3,    0,        0, 0x000fffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000400},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x633b6347},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000015},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000000b},
+	{0x57,    3,    0,        0, 0x001fffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000200},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xc676c68f},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000016},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000000a},
+	{0x57,    3,    0,        0, 0x003fffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000100},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8ced8d1f},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000017},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000009},
+	{0x57,    3,    0,        0, 0x007fffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000080},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x19db1a3e},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000018},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000008},
+	{0x57,    3,    0,        0, 0x00ffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000040},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x33b6347d},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000019},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000007},
+	{0x57,    3,    0,        0, 0x01ffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000020},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x676c68fa},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000001a},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000006},
+	{0x57,    3,    0,        0, 0x03ffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000010},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xced8d1f4},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000001b},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000005},
+	{0x57,    3,    0,        0, 0x07ffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000008},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x9db1a3e9},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000001c},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000004},
+	{0x57,    3,    0,        0, 0x0fffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000004},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x3b6347d2},
-	{0xbf,    2,    1,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000001d},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000003},
+	{0x57,    3,    0,        0, 0x1fffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000002},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x76c68fa5},
-	{0x57,    1,    0,        0, 0x00000001},
-	{0x15,    1,    0,     1194, 0x00000000},
-	{0xa7,    3,    0,        0, 0xed8d1f4a},
-	{0x05,    0,    0,     1192, 0x00000000},
-	{0x0f,    8,    1,        0, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0xbf,    1,    8,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0x0000002c},
-	{0x2d,    1,    9,     1216, 0x00000000},
-	{0x61,    2,    8,        8, 0x00000000},
-	{0xdc,    2,    0,        0, 0x00000040},
-	{0xc7,    2,    0,        0, 0x00000020},
-	{0x71,    3,    8,        6, 0x00000000},
-	{0x15,    3,    0,        2, 0x00000011},
-	{0xb7,    1,    0,        0, 0x00000000},
-	{0x55,    3,    0,       12, 0x00000006},
-	{0xbf,    3,    8,        0, 0x00000000},
-	{0x07,    3,    0,        0, 0x00000028},
-	{0x71,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000018},
-	{0x71,    1,    3,        1, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000010},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    4,    3,        3, 0x00000000},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    3,    3,        2, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000008},
-	{0x4f,    1,    3,        0, 0x00000000},
-	{0xbf,    4,    2,        0, 0x00000000},
-	{0x77,    4,    0,        0, 0x0000001f},
-	{0x57,    4,    0,        0, 0x2cc681d1},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x598d03a2},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb31a0745},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x66340e8a},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xcc681d15},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x98d03a2b},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x31a07456},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x6340e8ad},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xc681d15b},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x8d03a2b7},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00200000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x1a07456f},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x340e8ade},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x681d15bd},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd03a2b7b},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xa07456f6},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00010000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x40e8aded},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x81d15bdb},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00004000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x03a2b7b7},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x07456f6f},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x0e8adedf},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x1d15bdbf},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x3a2b7b7e},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x7456f6fd},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xe8adedfa},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd15bdbf4},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xa2b7b7e9},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x456f6fd3},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x8adedfa7},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x15bdbf4f},
-	{0x61,    3,    8,       12, 0x00000000},
-	{0xbf,    5,    2,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x2b7b7e9e},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    2,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x56f6fd3d},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    2,    0,        0, 0x00000001},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xadedfa7b},
-	{0xb7,    2,    0,        0, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0x5bdbf4f7},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000001e},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000002},
+	{0x57,    3,    0,        0, 0x3fffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0x57,    6,    0,        0, 0x00000001},
+	{0x15,    6,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000001f},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000001},
+	{0x57,    3,    0,        0, 0x7fffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    1,        0, 0x00000000},
+	{0xbf,    1,    2,        0, 0x00000000},
+	{0xbf,    3,    7,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0x00000004},
+	{0xbf,    2,    7,        0, 0x00000000},
+	{0x07,    2,    0,        0, 0x00000008},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x40000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb7b7e9ef},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000001},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001f},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x20000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6f6fd3df},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000002},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001e},
+	{0x57,    5,    0,        0, 0x00000003},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x10000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdedfa7bf},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000003},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001d},
+	{0x57,    5,    0,        0, 0x00000007},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x08000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbdbf4f7f},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000004},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001c},
+	{0x57,    5,    0,        0, 0x0000000f},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x04000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7b7e9eff},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000005},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001b},
+	{0x57,    5,    0,        0, 0x0000001f},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x02000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf6fd3dff},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000006},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001a},
+	{0x57,    5,    0,        0, 0x0000003f},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x01000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xedfa7bfe},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000007},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000019},
+	{0x57,    5,    0,        0, 0x0000007f},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00800000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdbf4f7fc},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000018},
+	{0x57,    5,    0,        0, 0x000000ff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00400000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb7e9eff9},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000009},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000017},
+	{0x57,    5,    0,        0, 0x000001ff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00200000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6fd3dff2},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000a},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000016},
+	{0x57,    5,    0,        0, 0x000003ff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00100000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdfa7bfe5},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000b},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000015},
+	{0x57,    5,    0,        0, 0x000007ff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00080000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbf4f7fca},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000c},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000014},
+	{0x57,    5,    0,        0, 0x00000fff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00040000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7e9eff94},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000d},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000013},
+	{0x57,    5,    0,        0, 0x00001fff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00020000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfd3dff28},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000e},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000012},
+	{0x57,    5,    0,        0, 0x00003fff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00010000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfa7bfe51},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000f},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000011},
+	{0x57,    5,    0,        0, 0x00007fff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00008000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf4f7fca2},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000010},
+	{0x57,    5,    0,        0, 0x0000ffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00004000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe9eff945},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000011},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000f},
+	{0x57,    5,    0,        0, 0x0001ffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00002000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd3dff28a},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000012},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000e},
+	{0x57,    5,    0,        0, 0x0003ffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00001000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa7bfe514},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000013},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000d},
+	{0x57,    5,    0,        0, 0x0007ffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000800},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x4f7fca28},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000014},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000c},
+	{0x57,    5,    0,        0, 0x000fffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000400},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x9eff9450},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000015},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000b},
+	{0x57,    5,    0,        0, 0x001fffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000200},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3dff28a0},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000016},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000a},
+	{0x57,    5,    0,        0, 0x003fffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000100},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7bfe5141},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000017},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000009},
+	{0x57,    5,    0,        0, 0x007fffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000080},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf7fca283},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000018},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000008},
+	{0x57,    5,    0,        0, 0x00ffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xeff94506},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000019},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000007},
+	{0x57,    5,    0,        0, 0x01ffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdff28a0c},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001a},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000006},
+	{0x57,    5,    0,        0, 0x03ffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbfe51418},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001b},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000005},
+	{0x57,    5,    0,        0, 0x07ffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7fca2831},
-	{0x61,    4,    8,       16, 0x00000000},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000004},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xff945063},
-	{0xdc,    4,    0,        0, 0x00000040},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000002},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xff28a0c6},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfe51418c},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0xfca28319},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf9450633},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf28a0c67},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe51418ce},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xca28319d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9450633b},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x28a0c676},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x51418ced},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa28319db},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x450633b6},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00200000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8a0c676c},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1418ced8},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x28319db1},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x50633b63},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa0c676c6},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00010000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x418ced8d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8319db1a},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00004000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x0633b634},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x0c676c68},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x18ced8d1},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x319db1a3},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x633b6347},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc676c68f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8ced8d1f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x19db1a3e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x33b6347d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x676c68fa},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xced8d1f4},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9db1a3e9},
-	{0x61,    3,    8,       20, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3b6347d2},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x76c68fa5},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xed8d1f4a},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdb1a3e94},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001c},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000004},
+	{0x57,    5,    0,        0, 0x0fffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001d},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000003},
+	{0x57,    5,    0,        0, 0x1fffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001e},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000002},
+	{0x57,    5,    0,        0, 0x3fffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    1,        0, 0x00000000},
+	{0xbf,    1,    4,        0, 0x00000000},
+	{0x57,    8,    0,        0, 0x00000001},
+	{0x15,    8,    0,        8, 0x00000000},
+	{0x61,    3,    3,        0, 0x00000000},
+	{0x67,    3,    0,        0, 0x0000001f},
+	{0x61,    2,    2,        0, 0x00000000},
+	{0x77,    2,    0,        0, 0x00000001},
+	{0x57,    2,    0,        0, 0x7fffffff},
+	{0x4f,    3,    2,        0, 0x00000000},
+	{0xaf,    3,    1,        0, 0x00000000},
+	{0xbf,    1,    3,        0, 0x00000000},
+	{0x63,   10,    1,      -28, 0x00000000},
+	{0xb7,    8,    0,        0, 0x00000001},
+	{0x05,    0,    0,        6, 0x00000000},
+	{0xbf,    3,   10,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0xffffffe4},
+	{0xbf,    1,    9,        0, 0x00000000},
+	{0xbf,    2,    7,        0, 0x00000000},
+	{0x85,    0,    1,        0, 0xffffffff},
+	{0xbf,    8,    0,        0, 0x00000000},
+	{0xbf,    1,    8,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000020},
+	{0x77,    1,    0,        0, 0x00000020},
+	{0x55,    1,    0,       33, 0x00000001},
+	{0x71,    2,    7,      201, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000008},
+	{0x71,    1,    7,      200, 0x00000000},
+	{0x4f,    2,    1,        0, 0x00000000},
+	{0x71,    3,    7,      202, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000010},
+	{0x71,    1,    7,      203, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000018},
+	{0x4f,    1,    3,        0, 0x00000000},
+	{0x4f,    1,    2,        0, 0x00000000},
+	{0x55,    1,    0,        4, 0x00000000},
+	{0x18,    1,    0,        0, 0x00000023},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xb7,    2,    0,        0, 0x0000001d},
+	{0x05,    0,    0,     -734, 0x00000000},
+	{0x61,    2,   10,      -28, 0x00000000},
+	{0x9f,    2,    1,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x0000000f},
+	{0x67,    2,    0,        0, 0x00000002},
+	{0x0f,    7,    2,        0, 0x00000000},
+	{0x71,    1,    7,      137, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000008},
+	{0x71,    2,    7,      136, 0x00000000},
+	{0x4f,    1,    2,        0, 0x00000000},
+	{0x71,    2,    7,      138, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000010},
+	{0x71,    3,    7,      139, 0x00000000},
+	{0x67,    3,    0,        0, 0x00000018},
+	{0x4f,    3,    2,        0, 0x00000000},
+	{0x4f,    3,    1,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0x7cafe800},
+	{0x63,    9,    3,       52, 0x00000000},
+	{0xb7,    8,    0,        0, 0x00000001},
+	{0xbf,    0,    8,        0, 0x00000000},
+	{0x95,    0,    0,        0, 0x00000000},
+	{0x7b,   10,    9,      -40, 0x00000000},
+	{0xb7,    9,    0,        0, 0x00000000},
+	{0x69,    2,   10,      -18, 0x00000000},
+	{0x57,    2,    0,        0, 0x0000ff3f},
+	{0xb7,    1,    0,        0, 0x00000000},
+	{0x15,    2,    0,       18, 0x00000000},
+	{0x71,    2,   10,      -24, 0x00000000},
+	{0x71,    3,   10,      -15, 0x00000000},
+	{0x15,    3,    0,        1, 0x00000011},
+	{0x55,    3,    0,       14, 0x00000006},
+	{0x67,    2,    0,        0, 0x00000002},
+	{0x57,    2,    0,        0, 0x0000003c},
+	{0xbf,    3,   10,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0xffffffe4},
+	{0x79,    1,   10,      -40, 0x00000000},
+	{0xb7,    4,    0,        0, 0x00000004},
+	{0xb7,    5,    0,        0, 0x00000001},
+	{0x85,    0,    0,        0, 0x00000044},
+	{0x55,    0,    0,     1033, 0x00000000},
+	{0x69,    1,   10,      -26, 0x00000000},
+	{0x67,    1,    0,        0, 0x00000010},
+	{0x69,    2,   10,      -28, 0x00000000},
+	{0x4f,    1,    2,        0, 0x00000000},
+	{0xdc,    1,    0,        0, 0x00000020},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x40000000},
+	{0x15,    2,    0,        6, 0x00000000},
+	{0x61,    9,    7,        0, 0x00000000},
+	{0x67,    9,    0,        0, 0x00000001},
+	{0x61,    2,    7,        4, 0x00000000},
+	{0x77,    2,    0,        0, 0x0000001f},
+	{0x57,    2,    0,        0, 0x00000001},
+	{0x4f,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x20000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000002},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000001e},
+	{0x57,    3,    0,        0, 0x00000003},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x10000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000003},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000001d},
+	{0x57,    3,    0,        0, 0x00000007},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x08000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000004},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000001c},
+	{0x57,    3,    0,        0, 0x0000000f},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x04000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000005},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000001b},
+	{0x57,    3,    0,        0, 0x0000001f},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x02000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000006},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000001a},
+	{0x57,    3,    0,        0, 0x0000003f},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x01000000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000007},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000019},
+	{0x57,    3,    0,        0, 0x0000007f},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00800000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000008},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000018},
+	{0x57,    3,    0,        0, 0x000000ff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00400000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000009},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000017},
+	{0x57,    3,    0,        0, 0x000001ff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00200000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000000a},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000016},
+	{0x57,    3,    0,        0, 0x000003ff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00100000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000000b},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000015},
+	{0x57,    3,    0,        0, 0x000007ff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00080000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000000c},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000014},
+	{0x57,    3,    0,        0, 0x00000fff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00040000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000000d},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000013},
+	{0x57,    3,    0,        0, 0x00001fff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00020000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000000e},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000012},
+	{0x57,    3,    0,        0, 0x00003fff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00010000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000000f},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000011},
+	{0x57,    3,    0,        0, 0x00007fff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00008000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000010},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000010},
+	{0x57,    3,    0,        0, 0x0000ffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00004000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000011},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000000f},
+	{0x57,    3,    0,        0, 0x0001ffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00002000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000012},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000000e},
+	{0x57,    3,    0,        0, 0x0003ffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00001000},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000013},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000000d},
+	{0x57,    3,    0,        0, 0x0007ffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00000800},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000014},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000000c},
+	{0x57,    3,    0,        0, 0x000fffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00000400},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000015},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000000b},
+	{0x57,    3,    0,        0, 0x001fffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00000200},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000016},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x0000000a},
+	{0x57,    3,    0,        0, 0x003fffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00000100},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000017},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000009},
+	{0x57,    3,    0,        0, 0x007fffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00000080},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000018},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000008},
+	{0x57,    3,    0,        0, 0x00ffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00000040},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x00000019},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000007},
+	{0x57,    3,    0,        0, 0x01ffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00000020},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000001a},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000006},
+	{0x57,    3,    0,        0, 0x03ffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00000010},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000001b},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000005},
+	{0x57,    3,    0,        0, 0x07ffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00000008},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000001c},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000004},
+	{0x57,    3,    0,        0, 0x0fffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00000004},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000001d},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000003},
+	{0x57,    3,    0,        0, 0x1fffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    2,    6,        0, 0x00000000},
+	{0x57,    2,    0,        0, 0x00000002},
+	{0x15,    2,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000001e},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000002},
+	{0x57,    3,    0,        0, 0x3fffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0x57,    6,    0,        0, 0x00000001},
+	{0x15,    6,    0,        8, 0x00000000},
+	{0x61,    2,    7,        0, 0x00000000},
+	{0x67,    2,    0,        0, 0x0000001f},
+	{0x61,    3,    7,        4, 0x00000000},
+	{0x77,    3,    0,        0, 0x00000001},
+	{0x57,    3,    0,        0, 0x7fffffff},
+	{0x4f,    2,    3,        0, 0x00000000},
+	{0xaf,    2,    9,        0, 0x00000000},
+	{0xbf,    9,    2,        0, 0x00000000},
+	{0xbf,    3,    7,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0x00000004},
+	{0xbf,    2,    7,        0, 0x00000000},
+	{0x07,    2,    0,        0, 0x00000008},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x40000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb6347d28},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000001},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001f},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x20000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6c68fa51},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000002},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001e},
+	{0x57,    5,    0,        0, 0x00000003},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x10000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd8d1f4a3},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000003},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001d},
+	{0x57,    5,    0,        0, 0x00000007},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x08000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb1a3e946},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000004},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001c},
+	{0x57,    5,    0,        0, 0x0000000f},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x04000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6347d28d},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000005},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001b},
+	{0x57,    5,    0,        0, 0x0000001f},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x02000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc68fa51a},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000006},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001a},
+	{0x57,    5,    0,        0, 0x0000003f},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x01000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d1f4a35},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000007},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000019},
+	{0x57,    5,    0,        0, 0x0000007f},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00800000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1a3e946b},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000018},
+	{0x57,    5,    0,        0, 0x000000ff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00400000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x347d28d7},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000009},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000017},
+	{0x57,    5,    0,        0, 0x000001ff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00200000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x68fa51ae},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000a},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000016},
+	{0x57,    5,    0,        0, 0x000003ff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00100000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd1f4a35c},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000b},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000015},
+	{0x57,    5,    0,        0, 0x000007ff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00080000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa3e946b9},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000c},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000014},
+	{0x57,    5,    0,        0, 0x00000fff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00040000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x47d28d73},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000d},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000013},
+	{0x57,    5,    0,        0, 0x00001fff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00020000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8fa51ae7},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000e},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000012},
+	{0x57,    5,    0,        0, 0x00003fff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00010000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1f4a35cf},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000f},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000011},
+	{0x57,    5,    0,        0, 0x00007fff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00008000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3e946b9e},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000010},
+	{0x57,    5,    0,        0, 0x0000ffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00004000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7d28d73c},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000011},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000f},
+	{0x57,    5,    0,        0, 0x0001ffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00002000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfa51ae78},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000012},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000e},
+	{0x57,    5,    0,        0, 0x0003ffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00001000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf4a35cf1},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000013},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000d},
+	{0x57,    5,    0,        0, 0x0007ffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000800},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe946b9e3},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000014},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000c},
+	{0x57,    5,    0,        0, 0x000fffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000400},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd28d73c7},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000015},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000b},
+	{0x57,    5,    0,        0, 0x001fffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000200},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa51ae78e},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000016},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000a},
+	{0x57,    5,    0,        0, 0x003fffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000100},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x4a35cf1c},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000017},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000009},
+	{0x57,    5,    0,        0, 0x007fffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000080},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x946b9e38},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000018},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000008},
+	{0x57,    5,    0,        0, 0x00ffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x28d73c71},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000019},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000007},
+	{0x57,    5,    0,        0, 0x01ffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x51ae78e3},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001a},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000006},
+	{0x57,    5,    0,        0, 0x03ffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa35cf1c6},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001b},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000005},
+	{0x57,    5,    0,        0, 0x07ffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x46b9e38d},
-	{0x61,    4,    8,       24, 0x00000000},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000004},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d73c71b},
-	{0xdc,    4,    0,        0, 0x00000040},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000002},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1ae78e36},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x35cf1c6c},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6b9e38d9},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xd73c71b2},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xae78e364},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5cf1c6c9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb9e38d92},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x73c71b25},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe78e364b},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xcf1c6c96},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9e38d92c},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3c71b259},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00200000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x78e364b2},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf1c6c964},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe38d92c9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc71b2593},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8e364b27},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00010000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1c6c964e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x38d92c9c},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00004000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x71b25938},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe364b270},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc6c964e0},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8d92c9c0},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1b259380},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x364b2700},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6c964e01},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xd92c9c03},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb2593807},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x64b2700f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc964e01e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x92c9c03d},
-	{0x61,    3,    8,       28, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x2593807a},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x4b2700f4},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x964e01e8},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0x2c9c03d1},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001c},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000004},
+	{0x57,    5,    0,        0, 0x0fffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001d},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000003},
+	{0x57,    5,    0,        0, 0x1fffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    8,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    3,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001e},
+	{0x61,    5,    2,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000002},
+	{0x57,    5,    0,        0, 0x3fffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0x57,    8,    0,        0, 0x00000001},
+	{0x15,    8,    0,        8, 0x00000000},
+	{0x61,    3,    3,        0, 0x00000000},
+	{0x67,    3,    0,        0, 0x0000001f},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x77,    4,    0,        0, 0x00000001},
+	{0x57,    4,    0,        0, 0x7fffffff},
+	{0x4f,    3,    4,        0, 0x00000000},
+	{0xaf,    3,    9,        0, 0x00000000},
+	{0xbf,    9,    3,        0, 0x00000000},
+	{0xbf,    3,    7,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0x0000000c},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x40000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x593807a3},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000001},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001f},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x20000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb2700f46},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000002},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001e},
+	{0x57,    5,    0,        0, 0x00000003},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x10000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x64e01e8d},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000003},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001d},
+	{0x57,    5,    0,        0, 0x00000007},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x08000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc9c03d1a},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000004},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001c},
+	{0x57,    5,    0,        0, 0x0000000f},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x04000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x93807a35},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000005},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001b},
+	{0x57,    5,    0,        0, 0x0000001f},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x02000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x2700f46b},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000006},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000001a},
+	{0x57,    5,    0,        0, 0x0000003f},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x01000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x4e01e8d6},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000007},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000019},
+	{0x57,    5,    0,        0, 0x0000007f},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00800000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x9c03d1ad},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000008},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000018},
+	{0x57,    5,    0,        0, 0x000000ff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00400000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3807a35b},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000009},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000017},
+	{0x57,    5,    0,        0, 0x000001ff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00200000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x700f46b6},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000a},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000016},
+	{0x57,    5,    0,        0, 0x000003ff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00100000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe01e8d6c},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000b},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000015},
+	{0x57,    5,    0,        0, 0x000007ff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00080000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc03d1ad9},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000c},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000014},
+	{0x57,    5,    0,        0, 0x00000fff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00040000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x807a35b3},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000d},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000013},
+	{0x57,    5,    0,        0, 0x00001fff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00020000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x00f46b66},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000e},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000012},
+	{0x57,    5,    0,        0, 0x00003fff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00010000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x01e8d6cc},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000000f},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000011},
+	{0x57,    5,    0,        0, 0x00007fff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00008000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x03d1ad99},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000010},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000010},
+	{0x57,    5,    0,        0, 0x0000ffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00004000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x07a35b32},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000011},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000f},
+	{0x57,    5,    0,        0, 0x0001ffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00002000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x0f46b665},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000012},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000e},
+	{0x57,    5,    0,        0, 0x0003ffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00001000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1e8d6cca},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000013},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000d},
+	{0x57,    5,    0,        0, 0x0007ffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000800},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3d1ad994},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000014},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000c},
+	{0x57,    5,    0,        0, 0x000fffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000400},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7a35b328},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000015},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000b},
+	{0x57,    5,    0,        0, 0x001fffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000200},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf46b6651},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000016},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x0000000a},
+	{0x57,    5,    0,        0, 0x003fffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000100},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe8d6cca2},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000017},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000009},
+	{0x57,    5,    0,        0, 0x007fffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000080},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd1ad9944},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000018},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000008},
+	{0x57,    5,    0,        0, 0x00ffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa35b3289},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000019},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000007},
+	{0x57,    5,    0,        0, 0x01ffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x46b66512},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001a},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000006},
+	{0x57,    5,    0,        0, 0x03ffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d6cca25},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001b},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000005},
+	{0x57,    5,    0,        0, 0x07ffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1ad9944a},
-	{0x61,    4,    8,       32, 0x00000000},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000004},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x35b32894},
-	{0xdc,    4,    0,        0, 0x00000040},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000002},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6b665129},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd6cca253},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0xad9944a7},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5b32894f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb665129f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6cca253e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xd9944a7d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb32894fb},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x665129f6},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xcca253ec},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9944a7d9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x32894fb2},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00200000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x65129f65},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xca253eca},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x944a7d95},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x2894fb2a},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5129f655},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00010000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa253ecab},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x44a7d956},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00004000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x894fb2ac},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x129f6558},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x253ecab1},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x4a7d9563},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x94fb2ac7},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x29f6558f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x53ecab1e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa7d9563d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x4fb2ac7a},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9f6558f5},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3ecab1ea},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7d9563d5},
-	{0x61,    3,    8,       36, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xfb2ac7ab},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf6558f56},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xecab1eac},
-	{0xbf,    4,    7,        0, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd9563d59},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    4,    7,        0, 0x00000000},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x40000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb2ac7ab2},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x20000000},
-	{0x79,    6,   10,      -56, 0x00000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x6558f564},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x10000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xcab1eac8},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x08000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x9563d590},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x04000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x2ac7ab20},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x02000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x558f5641},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x01000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xab1eac83},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00800000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x563d5906},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00400000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xac7ab20c},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00200000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x58f56418},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00100000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb1eac831},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00080000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x63d59063},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00040000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xc7ab20c7},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00020000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x8f56418f},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00010000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x1eac831e},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00008000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x3d59063c},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00004000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x7ab20c78},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00002000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xf56418f0},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00001000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xeac831e1},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000800},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd59063c2},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000400},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xab20c784},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000200},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x56418f09},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000100},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xac831e12},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000080},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x59063c25},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000040},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb20c784b},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000020},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x6418f097},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000010},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xc831e12f},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000008},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x9063c25f},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x20c784be},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x418f097c},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x831e12f9},
-	{0xbf,    5,    1,        0, 0x00000000},
-	{0x67,    5,    0,        0, 0x00000020},
-	{0xc7,    5,    0,        0, 0x00000020},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0xa7,    3,    0,        0, 0x063c25f3},
-	{0x6d,    2,    5,        1, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x40000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x0c784be7},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x20000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x18f097cf},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x10000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x31e12f9f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x08000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x63c25f3f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x04000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xc784be7f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x02000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8f097cff},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x01000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x1e12f9fe},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00800000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x3c25f3fc},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00400000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x784be7f8},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00200000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf097cff0},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00100000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xe12f9fe0},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00080000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xc25f3fc1},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00040000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x84be7f83},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00020000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x097cff07},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00010000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x12f9fe0f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00008000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x25f3fc1f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00004000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x4be7f83f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00002000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x97cff07f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00001000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x2f9fe0fe},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000800},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x5f3fc1fd},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000400},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xbe7f83fb},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000200},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x7cff07f7},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000100},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf9fe0fee},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000080},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf3fc1fdc},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000040},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xe7f83fb8},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000020},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xcff07f70},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000010},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x9fe0fee1},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000008},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x3fc1fdc2},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000004},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x7f83fb85},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000002},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xff07f70a},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001c},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000004},
+	{0x57,    5,    0,        0, 0x0fffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000004},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001d},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000003},
+	{0x57,    5,    0,        0, 0x1fffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
+	{0x57,    4,    0,        0, 0x00000002},
+	{0x15,    4,    0,        8, 0x00000000},
+	{0x61,    4,    2,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x0000001e},
+	{0x61,    5,    3,        0, 0x00000000},
+	{0x77,    5,    0,        0, 0x00000002},
+	{0x57,    5,    0,        0, 0x3fffffff},
+	{0x4f,    4,    5,        0, 0x00000000},
+	{0xaf,    4,    9,        0, 0x00000000},
+	{0xbf,    9,    4,        0, 0x00000000},
 	{0x57,    1,    0,        0, 0x00000001},
-	{0x15,    1,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xfe0fee15},
-	{0x71,    1,    0,      201, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000008},
-	{0x71,    2,    0,      200, 0x00000000},
+	{0x15,    1,    0,        8, 0x00000000},
+	{0x61,    1,    2,        0, 0x00000000},
+	{0x67,    1,    0,        0, 0x0000001f},
+	{0x61,    2,    3,        0, 0x00000000},
+	{0x77,    2,    0,        0, 0x00000001},
+	{0x57,    2,    0,        0, 0x7fffffff},
 	{0x4f,    1,    2,        0, 0x00000000},
-	{0x71,    2,    0,      202, 0x00000000},
-	{0x67,    2,    0,        0, 0x00000010},
-	{0x71,    4,    0,      203, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000018},
-	{0x4f,    4,    2,        0, 0x00000000},
-	{0x4f,    4,    1,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000020},
-	{0x77,    3,    0,        0, 0x00000020},
-	{0x9f,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x0000000f},
-	{0x67,    3,    0,        0, 0x00000002},
-	{0x0f,    0,    3,        0, 0x00000000},
-	{0x71,    1,    0,      137, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000008},
-	{0x71,    2,    0,      136, 0x00000000},
-	{0x4f,    1,    2,        0, 0x00000000},
-	{0x71,    2,    0,      138, 0x00000000},
-	{0x67,    2,    0,        0, 0x00000010},
-	{0x71,    3,    0,      139, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000018},
-	{0x4f,    3,    2,        0, 0x00000000},
-	{0x4f,    3,    1,        0, 0x00000000},
-	{0x07,    3,    0,        0, 0x7cafe800},
-	{0x63,    6,    3,       52, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000001},
-	{0xbf,    0,    7,        0, 0x00000000},
-	{0x95,    0,    0,        0, 0x00000000},
+	{0xaf,    1,    9,        0, 0x00000000},
+	{0xbf,    9,    1,        0, 0x00000000},
+	{0x63,   10,    9,      -28, 0x00000000},
+	{0xb7,    8,    0,        0, 0x00000001},
+	{0x79,    9,   10,      -40, 0x00000000},
+	{0x05,    0,    0,    -1091, 0x00000000},
+	{0xb7,    8,    0,        0, 0x00000000},
+	{0x79,    9,   10,      -40, 0x00000000},
+	{0x05,    0,    0,    -1094, 0x00000000},
 };
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index ed4d42f92f9f..5fe0bea88b0a 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -11,6 +11,7 @@
 
 #include <rte_byteorder.h>
 #include <rte_jhash.h>
+#include <rte_thash.h>
 #include <rte_malloc.h>
 #include <rte_eth_tap.h>
 #include <tap_flow.h>
@@ -2053,6 +2054,20 @@ static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
 	return err;
 }
 
+/* Default RSS hash key also used for ConnectX-3. */
+static const uint8_t rss_hash_default_key[] = {
+	0x2c, 0xc6, 0x81, 0xd1,
+	0x5b, 0xdb, 0xf4, 0xf7,
+	0xfc, 0xa2, 0x83, 0x19,
+	0xdb, 0x1a, 0x3e, 0x94,
+	0x6b, 0x9e, 0x38, 0xd9,
+	0x2c, 0x9c, 0x03, 0xd1,
+	0xad, 0x99, 0x44, 0xa7,
+	0xd9, 0x56, 0x3d, 0x59,
+	0x06, 0x3c, 0x25, 0xf3,
+	0xfc, 0x1f, 0xdc, 0x2a,
+};
+
 /**
  * Add RSS hash calculations and queue selection
  *
@@ -2073,6 +2088,7 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 {
 	/* 4096 is the maximum number of instructions for a BPF program */
 	unsigned int i;
+	const uint8_t *key_in;
 	int err;
 	struct rss_key rss_entry = { .hash_fields = 0,
 				     .key_size = 0 };
@@ -2087,6 +2103,29 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
 			 "a nonzero RSS encapsulation level is not supported");
 
+	if (rss->queue_num == 0 || rss->queue_num >= TAP_MAX_QUEUES)
+		return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+					  "invalid number of queues");
+
+	/* allow RSS key_len 0 in case of NULL (default) RSS key. */
+	if (rss->key_len == 0) {
+		if (rss->key != NULL)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+						  &rss->key_len, "RSS hash key length 0");
+		key_in = rss_hash_default_key;
+	} else {
+		if (rss->key_len != TAP_RSS_HASH_KEY_SIZE)
+			return rte_flow_error_set
+				(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				 "RSS hash invalid key length");
+		if (rss->key == NULL)
+			return rte_flow_error_set
+				(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				 "RSS hash key is NULL");
+		key_in = rss->key;
+	}
+
 	/* Get a new map key for a new RSS rule */
 	err = bpf_rss_key(KEY_CMD_GET, &flow->key_idx);
 	if (err < 0) {
@@ -2104,6 +2143,10 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
 	rss_entry.hash_fields =
 		(1 << HASH_FIELD_IPV4_L3_L4) | (1 << HASH_FIELD_IPV6_L3_L4);
 
+	/* Copy and convert RSS key to bigendian for software toeplitz */
+	rte_convert_rss_key((const uint32_t *)key_in, (uint32_t *)rss_entry.key,
+			    TAP_RSS_HASH_KEY_SIZE);
+
 	/* Add this RSS entry to map */
 	err = tap_flow_bpf_update_rss_elem(pmd->map_fd,
 				&flow->key_idx, &rss_entry);
-- 
2.43.0


^ permalink raw reply	[relevance 1%]

* Re: [dpdk-dev] [v1] ethdev: support Tx queue used count
    2024-01-12  8:02  4%   ` David Marchand
  @ 2024-01-12 16:52  3%   ` Stephen Hemminger
  2024-01-18  9:47  3%   ` [dpdk-dev] [v2] " jerinj
  3 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2024-01-12 16:52 UTC (permalink / raw)
  To: jerinj
  Cc: dev, Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko,
	ferruh.yigit, ajit.khaparde, aboyer, beilei.xing,
	bruce.richardson, chas3, chenbo.xia, ciara.loftus, dsinghrawat,
	ed.czeck, evgenys, grive, g.singh, zhouguoyang, haiyue.wang,
	hkalra, heinrich.kuhn, hemant.agrawal, hyonkim, igorch,
	irusskikh, jgrajcia, jasvinder.singh, jianwang, jiawenwu,
	jingjing.wu, johndale, john.miller, linville, keith.wiles,
	kirankumark, oulijun, lironh, longli, mw, spinler, matan,
	matt.peters, maxime.coquelin, mk, humin29, pnalla, ndabilpuram,
	qiming.yang, qi.z.zhang, radhac, rahul.lakkireddy, rmody,
	rosen.xu, sachin.saxena, skoteshwar, shshaikh, shaibran,
	shepard.siegel, asomalap, somnath.kotur, sthemmin,
	steven.webster, skori, mtetsuyah, vburru, viacheslavo,
	xiao.w.wang, cloud.wangxiaoyun, yisen.zhuang, yongwang,
	xuanziyang2, cristian.dumitrescu

On Thu, 11 Jan 2024 20:47:44 +0530
<jerinj@marvell.com> wrote:

> @@ -116,7 +119,9 @@ struct rte_eth_fp_ops {
>  	eth_tx_descriptor_status_t tx_descriptor_status;
>  	/** Copy used mbufs from Tx mbuf ring into Rx. */
>  	eth_recycle_tx_mbufs_reuse_t recycle_tx_mbufs_reuse;
> -	uintptr_t reserved2[2];
> +	/** Get the number of used Tx descriptors. */
> +	eth_tx_queue_count_t tx_queue_count;
> +	uintptr_t reserved2[1];
>  	/**@}*/

This does introduce the question of were the reserved fields checked
in earlier versions. (ie. must be NULL).  But since the DPDK only expects rte_eth_fp_ops
to come from driver, and we don't guarantee ABI for driver API's, it is not a problem.

^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [v1] ethdev: support Tx queue used count
  2024-01-12 12:11  3%     ` David Marchand
@ 2024-01-12 14:25  3%       ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2024-01-12 14:25 UTC (permalink / raw)
  To: David Marchand
  Cc: jerinj, dev, Thomas Monjalon, Andrew Rybchenko, ferruh.yigit,
	ajit.khaparde, aboyer, beilei.xing, bruce.richardson, chas3,
	chenbo.xia, ciara.loftus, dsinghrawat, ed.czeck, evgenys, grive,
	g.singh, zhouguoyang, haiyue.wang, hkalra, heinrich.kuhn,
	hemant.agrawal, hyonkim, igorch, irusskikh, jgrajcia,
	jasvinder.singh, jianwang, jiawenwu, jingjing.wu, johndale,
	john.miller, linville, keith.wiles, kirankumark, oulijun, lironh,
	longli, mw, spinler, matan, matt.peters, maxime.coquelin, mk,
	humin29, pnalla, ndabilpuram, qiming.yang, qi.z.zhang, radhac,
	rahul.lakkireddy, rmody, rosen.xu, sachin.saxena, skoteshwar,
	shshaikh, shaibran, shepard.siegel, asomalap, somnath.kotur,
	sthemmin, steven.webster, skori, mtetsuyah, vburru, viacheslavo,
	xiao.w.wang, cloud.wangxiaoyun, yisen.zhuang, yongwang,
	xuanziyang2, cristian.dumitrescu

On 1/12/2024 12:11 PM, David Marchand wrote:
> CAUTION: This message has originated from an External Source. Please use proper judgment and caution when opening attachments, clicking links, or responding to this email.
> 
> 
> On Fri, Jan 12, 2024 at 12:34 PM Ferruh Yigit <ferruh.yigit@amd.com> wrote:
>>> diff --git a/lib/ethdev/rte_ethdev_core.h b/lib/ethdev/rte_ethdev_core.h
>>> index 4bfaf79c6c..d3f09f390d 100644
>>> --- a/lib/ethdev/rte_ethdev_core.h
>>> +++ b/lib/ethdev/rte_ethdev_core.h
>>> @@ -60,6 +60,9 @@ typedef uint16_t (*eth_recycle_tx_mbufs_reuse_t)(void *txq,
>>>  /** @internal Refill Rx descriptors with the recycling mbufs */
>>>  typedef void (*eth_recycle_rx_descriptors_refill_t)(void *rxq, uint16_t nb);
>>>
>>> +/** @internal Get number of used descriptors on a transmit queue. */
>>> +typedef int (*eth_tx_queue_count_t)(void *txq);
>>> +
>>
>> Can you please move it above 'tx_descriptor_status', to keep same order
>> kept in many other locations:
>> rx_queue_count
>> rx_descriptor_status
>> tx_queue_count
>> tx_descriptor_status
>>
>>
>>>  /**
>>>   * @internal
>>>   * Structure used to hold opaque pointers to internal ethdev Rx/Tx
>>> @@ -116,7 +119,9 @@ struct rte_eth_fp_ops {
>>>       eth_tx_descriptor_status_t tx_descriptor_status;
>>>       /** Copy used mbufs from Tx mbuf ring into Rx. */
>>>       eth_recycle_tx_mbufs_reuse_t recycle_tx_mbufs_reuse;
>>> -     uintptr_t reserved2[2];
>>> +     /** Get the number of used Tx descriptors. */
>>> +     eth_tx_queue_count_t tx_queue_count;
>>>
>>
>> Similarly, can you please move it above 'tx_descriptor_status'?
> 
> Moving fields in rte_eth_fp_ops (where fast-path API ops are) breaks
> the applications ABI.
> 

You are right, what about put a TODO note or deprecation notice to move
it in next ABI break release?


^ permalink raw reply	[relevance 3%]

* [PATCH] net/tap: Modified TAP BPF program as per the Kernel-version upgrade requirements.
@ 2024-01-12 13:48  1% madhuker.mythri
  2024-01-12 17:53  1% ` [RFC v3] tap: rework the BPF header parsing Stephen Hemminger
  0 siblings, 1 reply; 200+ results
From: madhuker.mythri @ 2024-01-12 13:48 UTC (permalink / raw)
  To: stephen; +Cc: dev, ferruh.yigit, Madhuker Mythri

From: Madhuker Mythri <madhuker.mythri@oracle.com>

When multiple queues configured, internally RSS will be enabled and thus TAP BPF RSS byte-code will be loaded on to the Kernel using BPF system calls.

Here, the problem is loading the existing BPF byte-code to the Kernel-5.15 and above versions throws errors, i.e: Kernel BPF verifier not accepted this existing BPF byte-code and system calls return error code "-7" as follows:
------------------------
rss_add_actions(): Failed to load BPF section l3_l4 (7): Argument list too long
------------------------

RCA:  These errors started coming after from the Kernel-5.15 version, in which lots of new BPF verification restrictions were added for safe execution of byte-code on to the Kernel, due to which existing BPF program verification does not pass.
Here are the major BPF verifier restrictions observed:
1) Need to use new BPF maps structure.
2) Kernel SKB data pointer access not allowed, instead use the BPF helper functions.
3) Undefined loops were not allowed(which are bounded by a variable value).
4) unreachable instructions(like: undefined array access).

After addressing all these Kernel BPF verifier restrictions able to load the BPF byte-code onto the Kernel successfully.

Verified with the latest DPDK-23.11 code, using the python extracted
BPF instructions able to load sucessfully on to the Kernel tap device.

Bugzilla Id: 1329

Signed-off-by: Madhuker Mythri <madhuker.mythri@oracle.com>
---
 drivers/net/tap/bpf/Makefile          |    6 +-
 drivers/net/tap/bpf/bpf_api.h         |  276 ---
 drivers/net/tap/bpf/bpf_elf.h         |   53 -
 drivers/net/tap/bpf/tap_bpf_program.c |  233 +--
 drivers/net/tap/tap_bpf_api.c         |    5 +-
 drivers/net/tap/tap_bpf_insns.h       | 2300 ++++++++++++++-----------
 6 files changed, 1416 insertions(+), 1457 deletions(-)
 delete mode 100644 drivers/net/tap/bpf/bpf_api.h
 delete mode 100644 drivers/net/tap/bpf/bpf_elf.h

diff --git a/drivers/net/tap/bpf/Makefile b/drivers/net/tap/bpf/Makefile
index 9efeeb1bc7..218aeaac45 100644
--- a/drivers/net/tap/bpf/Makefile
+++ b/drivers/net/tap/bpf/Makefile
@@ -6,14 +6,16 @@ CLANG=clang
 CLANG_OPTS=-O2
 TARGET=../tap_bpf_insns.h
 
+CLANG_BPF_SYS_INCLUDES ?= $(shell $(CLANG) -v -E - </dev/null 2>&1 \
+	| sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }')
+
 all: $(TARGET)
 
 clean:
 	rm tap_bpf_program.o $(TARGET)
 
 tap_bpf_program.o: tap_bpf_program.c
-	$(CLANG) $(CLANG_OPTS) -emit-llvm -c $< -o - | \
-	llc -march=bpf -filetype=obj -o $@
+	$(CLANG) $(CLANG_OPTS) $(CLANG_BPF_SYS_INCLUDES) -target bpf -c $< -g -o $@
 
 $(TARGET): tap_bpf_program.o
 	python3 bpf_extract.py -stap_bpf_program.c -o $@ $<
diff --git a/drivers/net/tap/bpf/bpf_api.h b/drivers/net/tap/bpf/bpf_api.h
deleted file mode 100644
index 2638a8a4ac..0000000000
--- a/drivers/net/tap/bpf/bpf_api.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-
-#ifndef __BPF_API__
-#define __BPF_API__
-
-/* Note:
- *
- * This file can be included into eBPF kernel programs. It contains
- * a couple of useful helper functions, map/section ABI (bpf_elf.h),
- * misc macros and some eBPF specific LLVM built-ins.
- */
-
-#include <stdint.h>
-
-#include <linux/pkt_cls.h>
-#include <linux/bpf.h>
-#include <linux/filter.h>
-
-#include <asm/byteorder.h>
-
-#include "bpf_elf.h"
-
-/** libbpf pin type. */
-enum libbpf_pin_type {
-	LIBBPF_PIN_NONE,
-	/* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */
-	LIBBPF_PIN_BY_NAME,
-};
-
-/** Type helper macros. */
-
-#define __uint(name, val) int (*name)[val]
-#define __type(name, val) typeof(val) *name
-#define __array(name, val) typeof(val) *name[]
-
-/** Misc macros. */
-
-#ifndef __stringify
-# define __stringify(X)		#X
-#endif
-
-#ifndef __maybe_unused
-# define __maybe_unused		__attribute__((__unused__))
-#endif
-
-#ifndef offsetof
-# define offsetof(TYPE, MEMBER)	__builtin_offsetof(TYPE, MEMBER)
-#endif
-
-#ifndef likely
-# define likely(X)		__builtin_expect(!!(X), 1)
-#endif
-
-#ifndef unlikely
-# define unlikely(X)		__builtin_expect(!!(X), 0)
-#endif
-
-#ifndef htons
-# define htons(X)		__constant_htons((X))
-#endif
-
-#ifndef ntohs
-# define ntohs(X)		__constant_ntohs((X))
-#endif
-
-#ifndef htonl
-# define htonl(X)		__constant_htonl((X))
-#endif
-
-#ifndef ntohl
-# define ntohl(X)		__constant_ntohl((X))
-#endif
-
-#ifndef __inline__
-# define __inline__		__attribute__((always_inline))
-#endif
-
-/** Section helper macros. */
-
-#ifndef __section
-# define __section(NAME)						\
-	__attribute__((section(NAME), used))
-#endif
-
-#ifndef __section_tail
-# define __section_tail(ID, KEY)					\
-	__section(__stringify(ID) "/" __stringify(KEY))
-#endif
-
-#ifndef __section_xdp_entry
-# define __section_xdp_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_cls_entry
-# define __section_cls_entry						\
-	__section(ELF_SECTION_CLASSIFIER)
-#endif
-
-#ifndef __section_act_entry
-# define __section_act_entry						\
-	__section(ELF_SECTION_ACTION)
-#endif
-
-#ifndef __section_lwt_entry
-# define __section_lwt_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_license
-# define __section_license						\
-	__section(ELF_SECTION_LICENSE)
-#endif
-
-#ifndef __section_maps
-# define __section_maps							\
-	__section(ELF_SECTION_MAPS)
-#endif
-
-/** Declaration helper macros. */
-
-#ifndef BPF_LICENSE
-# define BPF_LICENSE(NAME)						\
-	char ____license[] __section_license = NAME
-#endif
-
-/** Classifier helper */
-
-#ifndef BPF_H_DEFAULT
-# define BPF_H_DEFAULT	-1
-#endif
-
-/** BPF helper functions for tc. Individual flags are in linux/bpf.h */
-
-#ifndef __BPF_FUNC
-# define __BPF_FUNC(NAME, ...)						\
-	(* NAME)(__VA_ARGS__) __maybe_unused
-#endif
-
-#ifndef BPF_FUNC
-# define BPF_FUNC(NAME, ...)						\
-	__BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME
-#endif
-
-/* Map access/manipulation */
-static void *BPF_FUNC(map_lookup_elem, void *map, const void *key);
-static int BPF_FUNC(map_update_elem, void *map, const void *key,
-		    const void *value, uint32_t flags);
-static int BPF_FUNC(map_delete_elem, void *map, const void *key);
-
-/* Time access */
-static uint64_t BPF_FUNC(ktime_get_ns);
-
-/* Debugging */
-
-/* FIXME: __attribute__ ((format(printf, 1, 3))) not possible unless
- * llvm bug https://llvm.org/bugs/show_bug.cgi?id=26243 gets resolved.
- * It would require ____fmt to be made const, which generates a reloc
- * entry (non-map).
- */
-static void BPF_FUNC(trace_printk, const char *fmt, int fmt_size, ...);
-
-#ifndef printt
-# define printt(fmt, ...)						\
-	({								\
-		char ____fmt[] = fmt;					\
-		trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__);	\
-	})
-#endif
-
-/* Random numbers */
-static uint32_t BPF_FUNC(get_prandom_u32);
-
-/* Tail calls */
-static void BPF_FUNC(tail_call, struct __sk_buff *skb, void *map,
-		     uint32_t index);
-
-/* System helpers */
-static uint32_t BPF_FUNC(get_smp_processor_id);
-static uint32_t BPF_FUNC(get_numa_node_id);
-
-/* Packet misc meta data */
-static uint32_t BPF_FUNC(get_cgroup_classid, struct __sk_buff *skb);
-static int BPF_FUNC(skb_under_cgroup, void *map, uint32_t index);
-
-static uint32_t BPF_FUNC(get_route_realm, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(get_hash_recalc, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(set_hash_invalid, struct __sk_buff *skb);
-
-/* Packet redirection */
-static int BPF_FUNC(redirect, int ifindex, uint32_t flags);
-static int BPF_FUNC(clone_redirect, struct __sk_buff *skb, int ifindex,
-		    uint32_t flags);
-
-/* Packet manipulation */
-static int BPF_FUNC(skb_load_bytes, struct __sk_buff *skb, uint32_t off,
-		    void *to, uint32_t len);
-static int BPF_FUNC(skb_store_bytes, struct __sk_buff *skb, uint32_t off,
-		    const void *from, uint32_t len, uint32_t flags);
-
-static int BPF_FUNC(l3_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(l4_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(csum_diff, const void *from, uint32_t from_size,
-		    const void *to, uint32_t to_size, uint32_t seed);
-static int BPF_FUNC(csum_update, struct __sk_buff *skb, uint32_t wsum);
-
-static int BPF_FUNC(skb_change_type, struct __sk_buff *skb, uint32_t type);
-static int BPF_FUNC(skb_change_proto, struct __sk_buff *skb, uint32_t proto,
-		    uint32_t flags);
-static int BPF_FUNC(skb_change_tail, struct __sk_buff *skb, uint32_t nlen,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_pull_data, struct __sk_buff *skb, uint32_t len);
-
-/* Event notification */
-static int __BPF_FUNC(skb_event_output, struct __sk_buff *skb, void *map,
-		      uint64_t index, const void *data, uint32_t size) =
-		      (void *) BPF_FUNC_perf_event_output;
-
-/* Packet vlan encap/decap */
-static int BPF_FUNC(skb_vlan_push, struct __sk_buff *skb, uint16_t proto,
-		    uint16_t vlan_tci);
-static int BPF_FUNC(skb_vlan_pop, struct __sk_buff *skb);
-
-/* Packet tunnel encap/decap */
-static int BPF_FUNC(skb_get_tunnel_key, struct __sk_buff *skb,
-		    struct bpf_tunnel_key *to, uint32_t size, uint32_t flags);
-static int BPF_FUNC(skb_set_tunnel_key, struct __sk_buff *skb,
-		    const struct bpf_tunnel_key *from, uint32_t size,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_get_tunnel_opt, struct __sk_buff *skb,
-		    void *to, uint32_t size);
-static int BPF_FUNC(skb_set_tunnel_opt, struct __sk_buff *skb,
-		    const void *from, uint32_t size);
-
-/** LLVM built-ins, mem*() routines work for constant size */
-
-#ifndef lock_xadd
-# define lock_xadd(ptr, val)	((void) __sync_fetch_and_add(ptr, val))
-#endif
-
-#ifndef memset
-# define memset(s, c, n)	__builtin_memset((s), (c), (n))
-#endif
-
-#ifndef memcpy
-# define memcpy(d, s, n)	__builtin_memcpy((d), (s), (n))
-#endif
-
-#ifndef memmove
-# define memmove(d, s, n)	__builtin_memmove((d), (s), (n))
-#endif
-
-/* FIXME: __builtin_memcmp() is not yet fully usable unless llvm bug
- * https://llvm.org/bugs/show_bug.cgi?id=26218 gets resolved. Also
- * this one would generate a reloc entry (non-map), otherwise.
- */
-#if 0
-#ifndef memcmp
-# define memcmp(a, b, n)	__builtin_memcmp((a), (b), (n))
-#endif
-#endif
-
-unsigned long long load_byte(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.byte");
-
-unsigned long long load_half(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.half");
-
-unsigned long long load_word(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.word");
-
-#endif /* __BPF_API__ */
diff --git a/drivers/net/tap/bpf/bpf_elf.h b/drivers/net/tap/bpf/bpf_elf.h
deleted file mode 100644
index ea8a11c95c..0000000000
--- a/drivers/net/tap/bpf/bpf_elf.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-#ifndef __BPF_ELF__
-#define __BPF_ELF__
-
-#include <asm/types.h>
-
-/* Note:
- *
- * Below ELF section names and bpf_elf_map structure definition
- * are not (!) kernel ABI. It's rather a "contract" between the
- * application and the BPF loader in tc. For compatibility, the
- * section names should stay as-is. Introduction of aliases, if
- * needed, are a possibility, though.
- */
-
-/* ELF section names, etc */
-#define ELF_SECTION_LICENSE	"license"
-#define ELF_SECTION_MAPS	"maps"
-#define ELF_SECTION_PROG	"prog"
-#define ELF_SECTION_CLASSIFIER	"classifier"
-#define ELF_SECTION_ACTION	"action"
-
-#define ELF_MAX_MAPS		64
-#define ELF_MAX_LICENSE_LEN	128
-
-/* Object pinning settings */
-#define PIN_NONE		0
-#define PIN_OBJECT_NS		1
-#define PIN_GLOBAL_NS		2
-
-/* ELF map definition */
-struct bpf_elf_map {
-	__u32 type;
-	__u32 size_key;
-	__u32 size_value;
-	__u32 max_elem;
-	__u32 flags;
-	__u32 id;
-	__u32 pinning;
-	__u32 inner_id;
-	__u32 inner_idx;
-};
-
-#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val)		\
-	struct ____btf_map_##name {				\
-		type_key key;					\
-		type_val value;					\
-	};							\
-	struct ____btf_map_##name				\
-	    __attribute__ ((section(".maps." #name), used))	\
-	    ____btf_map_##name = { }
-
-#endif /* __BPF_ELF__ */
diff --git a/drivers/net/tap/bpf/tap_bpf_program.c b/drivers/net/tap/bpf/tap_bpf_program.c
index f05aed021c..00f224f734 100644
--- a/drivers/net/tap/bpf/tap_bpf_program.c
+++ b/drivers/net/tap/bpf/tap_bpf_program.c
@@ -2,67 +2,42 @@
  * Copyright 2017 Mellanox Technologies, Ltd
  */
 
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <asm/types.h>
 #include <linux/in.h>
-#include <linux/if.h>
 #include <linux/if_ether.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
-#include <linux/if_tunnel.h>
-#include <linux/filter.h>
-
-#include "bpf_api.h"
-#include "bpf_elf.h"
+#include <linux/udp.h>
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+#include <bpf/bpf_endian.h>
+#include <linux/pkt_cls.h>
 #include "../tap_rss.h"
 
-/** Create IPv4 address */
-#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
-		(((b) & 0xff) << 16) | \
-		(((c) & 0xff) << 8)  | \
-		((d) & 0xff))
-
-#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
-		((b) & 0xff))
-
 /*
  * The queue number is offset by a unique QUEUE_OFFSET, to distinguish
  * packets that have gone through this rule (skb->cb[1] != 0) from others.
  */
 #define QUEUE_OFFSET		0x7cafe800
-#define PIN_GLOBAL_NS		2
 
-#define KEY_IDX			0
-#define BPF_MAP_ID_KEY	1
+#define IP_MF		0x2000		/** IP header Flags **/
+#define IP_OFFSET	0x1FFF		/** IP header fragment offset **/
 
-struct vlan_hdr {
-	__be16 proto;
-	__be16 tci;
-};
 
-struct bpf_elf_map __attribute__((section("maps"), used))
-map_keys = {
-	.type           =       BPF_MAP_TYPE_HASH,
-	.id             =       BPF_MAP_ID_KEY,
-	.size_key       =       sizeof(__u32),
-	.size_value     =       sizeof(struct rss_key),
-	.max_elem       =       256,
-	.pinning        =       PIN_GLOBAL_NS,
-};
+struct  {
+	__uint(type,       BPF_MAP_TYPE_HASH);
+	__type(key,  __u32);
+	__type(value,     struct rss_key);
+	__uint(max_entries,      256);
+} map_keys SEC(".maps");
 
-__section("cls_q") int
-match_q(struct __sk_buff *skb)
+SEC("cls_q")
+int match_q(struct __sk_buff *skb)
 {
 	__u32 queue = skb->cb[1];
-	/* queue is set by tap_flow_bpf_cls_q() before load */
 	volatile __u32 q = 0xdeadbeef;
 	__u32 match_queue = QUEUE_OFFSET + q;
 
-	/* printt("match_q$i() queue = %d\n", queue); */
-
 	if (queue != match_queue)
 		return TC_ACT_OK;
 
@@ -71,7 +46,6 @@ match_q(struct __sk_buff *skb)
 	return TC_ACT_UNSPEC;
 }
 
-
 struct ipv4_l3_l4_tuple {
 	__u32    src_addr;
 	__u32    dst_addr;
@@ -86,6 +60,16 @@ struct ipv6_l3_l4_tuple {
 	__u16       sport;
 } __attribute__((packed));
 
+struct neth {
+	struct iphdr iph;
+	struct udphdr udph;
+} __attribute__((packed));
+
+struct net6h {
+	struct ipv6hdr ip6h;
+	struct udphdr udph;
+} __attribute__((packed));
+
 static const __u8 def_rss_key[TAP_RSS_HASH_KEY_SIZE] = {
 	0xd1, 0x81, 0xc6, 0x2c,
 	0xf7, 0xf4, 0xdb, 0x5b,
@@ -99,18 +83,18 @@ static const __u8 def_rss_key[TAP_RSS_HASH_KEY_SIZE] = {
 	0x2a, 0xdc, 0x1f, 0xfc,
 };
 
-static __u32  __attribute__((always_inline))
-rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
-		__u8 input_len)
+static __u64  __attribute__((always_inline))
+rte_softrss_be(const __u32 *input_tuple, __u8 input_len)
 {
-	__u32 i, j, hash = 0;
-#pragma unroll
+	__u32 i, j;
+	__u64 hash = 0;
+#pragma clang loop unroll(full)
 	for (j = 0; j < input_len; j++) {
-#pragma unroll
+#pragma clang loop unroll(full)
 		for (i = 0; i < 32; i++) {
 			if (input_tuple[j] & (1U << (31 - i))) {
 				hash ^= ((const __u32 *)def_rss_key)[j] << i |
-				(__u32)((uint64_t)
+				(__u32)((__u64)
 				(((const __u32 *)def_rss_key)[j + 1])
 					>> (32 - i));
 			}
@@ -119,137 +103,76 @@ rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
 	return hash;
 }
 
-static int __attribute__((always_inline))
+SEC("l3_l4")
+int __attribute__((always_inline))
 rss_l3_l4(struct __sk_buff *skb)
 {
-	void *data_end = (void *)(long)skb->data_end;
-	void *data = (void *)(long)skb->data;
-	__u16 proto = (__u16)skb->protocol;
+	struct neth nh;
+	struct net6h n6h;
 	__u32 key_idx = 0xdeadbeef;
-	__u32 hash;
+	__u64 hash;
 	struct rss_key *rsskey;
-	__u64 off = ETH_HLEN;
-	int j;
-	__u8 *key = 0;
+	int j, k, ret;
 	__u32 len;
 	__u32 queue = 0;
-	bool mf = 0;
-	__u16 frag_off = 0;
 
-	rsskey = map_lookup_elem(&map_keys, &key_idx);
-	if (!rsskey) {
-		printt("hash(): rss key is not configured\n");
+	rsskey = bpf_map_lookup_elem(&map_keys, &key_idx);
+	if (rsskey == NULL) {
 		return TC_ACT_OK;
 	}
-	key = (__u8 *)rsskey->key;
 
-	/* Get correct proto for 802.1ad */
-	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
-		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
-		    sizeof(proto) > data_end)
-			return TC_ACT_OK;
-		proto = *(__u16 *)(data + ETH_ALEN * 2 +
-				   sizeof(struct vlan_hdr));
-		off += sizeof(struct vlan_hdr);
-	}
-
-	if (proto == htons(ETH_P_IP)) {
-		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
-			> data_end)
-			return TC_ACT_OK;
-
-		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
-		__u8 *frag_off_addr = data + off + offsetof(struct iphdr, frag_off);
-		__u8 *prot_addr = data + off + offsetof(struct iphdr, protocol);
-		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
+	if (bpf_skb_load_bytes_relative(skb, 0, &nh, sizeof(nh), BPF_HDR_START_NET))
+		return TC_ACT_OK;
+	if (nh.iph.version == 4) {
 		struct ipv4_l3_l4_tuple v4_tuple = {
-			.src_addr = IPv4(*(src_dst_addr + 0),
-					*(src_dst_addr + 1),
-					*(src_dst_addr + 2),
-					*(src_dst_addr + 3)),
-			.dst_addr = IPv4(*(src_dst_addr + 4),
-					*(src_dst_addr + 5),
-					*(src_dst_addr + 6),
-					*(src_dst_addr + 7)),
+			.src_addr = bpf_ntohl(nh.iph.saddr),
+			.dst_addr = bpf_ntohl(nh.iph.daddr),
 			.sport = 0,
 			.dport = 0,
 		};
-		/** Fetch the L4-payer port numbers only in-case of TCP/UDP
-		 ** and also if the packet is not fragmented. Since fragmented
-		 ** chunks do not have L4 TCP/UDP header.
-		 **/
-		if (*prot_addr == IPPROTO_UDP || *prot_addr == IPPROTO_TCP) {
-			frag_off = PORT(*(frag_off_addr + 0),
-					*(frag_off_addr + 1));
-			mf = frag_off & 0x2000;
-			frag_off = frag_off & 0x1fff;
-			if (mf == 0 && frag_off == 0) {
-				v4_tuple.sport = PORT(*(src_dst_port + 0),
-						*(src_dst_port + 1));
-				v4_tuple.dport = PORT(*(src_dst_port + 2),
-						*(src_dst_port + 3));
+		if (nh.iph.protocol == IPPROTO_UDP || nh.iph.protocol == IPPROTO_TCP) {
+			/** Is IP fragmented **/
+			if ((nh.iph.frag_off & bpf_htons(IP_MF | IP_OFFSET)) == 0) {
+				v4_tuple.sport = bpf_ntohs(nh.udph.source);
+				v4_tuple.dport = bpf_ntohs(nh.udph.dest);
 			}
 		}
-		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
-	} else if (proto == htons(ETH_P_IPV6)) {
-		if (data + off + sizeof(struct ipv6hdr) +
-					sizeof(__u32) > data_end)
-			return TC_ACT_OK;
-		__u8 *src_dst_addr = data + off +
-					offsetof(struct ipv6hdr, saddr);
-		__u8 *src_dst_port = data + off +
-					sizeof(struct ipv6hdr);
-		__u8 *next_hdr = data + off +
-					offsetof(struct ipv6hdr, nexthdr);
-
+		hash = rte_softrss_be((__u32 *)&v4_tuple, 3);
+	} else if (nh.iph.version == 6) {
 		struct ipv6_l3_l4_tuple v6_tuple;
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.src_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + j));
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.dst_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + 4 + j));
-
-		/** Fetch the L4 header port-numbers only if next-header
-		 * is TCP/UDP **/
-		if (*next_hdr == IPPROTO_UDP || *next_hdr == IPPROTO_TCP) {
-			v6_tuple.sport = PORT(*(src_dst_port + 0),
-				      *(src_dst_port + 1));
-			v6_tuple.dport = PORT(*(src_dst_port + 2),
-				      *(src_dst_port + 3));
-		} else {
+		if (bpf_skb_load_bytes_relative(skb, 0, &n6h, sizeof(n6h), BPF_HDR_START_NET))
+			return TC_ACT_OK;
+#pragma clang loop unroll(full)
+		for (j = 0; j < 4; j++) {
+			*((__u32 *)&v6_tuple.src_addr + j) =
+							bpf_ntohl(n6h.ip6h.saddr.in6_u.u6_addr32[j]);
+			*((__u32 *)&v6_tuple.dst_addr + j) =
+							bpf_ntohl(n6h.ip6h.daddr.in6_u.u6_addr32[j]);
+		}
+		if (n6h.ip6h.nexthdr == IPPROTO_UDP || n6h.ip6h.nexthdr == IPPROTO_UDP) {
+			v6_tuple.sport = bpf_ntohs(n6h.udph.source);
+			v6_tuple.dport = bpf_ntohs(n6h.udph.dest);
+		}
+		else {
 			v6_tuple.sport = 0;
 			v6_tuple.dport = 0;
 		}
-
-		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
+		hash = rte_softrss_be((__u32 *)&v6_tuple, 9);
 	} else {
 		return TC_ACT_PIPE;
 	}
 
-	queue = rsskey->queues[(hash % rsskey->nb_queues) &
-				       (TAP_MAX_QUEUES - 1)];
-	skb->cb[1] = QUEUE_OFFSET + queue;
-	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
+	hash = (hash % rsskey->nb_queues) & (TAP_MAX_QUEUES - 1);
+#pragma clang loop unroll(full)
+	for (k = 0; k < TAP_MAX_QUEUES; k++) {
+		if(k == hash)
+			queue = rsskey->queues[k];
+	}
 
-	return TC_ACT_RECLASSIFY;
-}
+	skb->cb[1] = (__u32)(QUEUE_OFFSET + queue);
 
-#define RSS(L)						\
-	__section(#L) int				\
-		L ## _hash(struct __sk_buff *skb)	\
-	{						\
-		return rss_ ## L (skb);			\
-	}
+	return TC_ACT_RECLASSIFY;
 
-RSS(l3_l4)
+}
 
-BPF_LICENSE("Dual BSD/GPL");
+char _license[] SEC("license") = "Dual BSD/GPL";
diff --git a/drivers/net/tap/tap_bpf_api.c b/drivers/net/tap/tap_bpf_api.c
index 15283f8917..7e13d4b8b6 100644
--- a/drivers/net/tap/tap_bpf_api.c
+++ b/drivers/net/tap/tap_bpf_api.c
@@ -48,8 +48,9 @@ int tap_flow_bpf_cls_q(__u32 queue_idx)
  */
 int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
 {
-	l3_l4_hash_insns[4].imm = key_idx;
-	l3_l4_hash_insns[9].imm = map_fd;
+	l3_l4_hash_insns[1].imm = key_idx;
+	l3_l4_hash_insns[6].imm = map_fd;
+	l3_l4_hash_insns[6].src_reg = 1;
 
 	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
 		(struct bpf_insn *)l3_l4_hash_insns,
diff --git a/drivers/net/tap/tap_bpf_insns.h b/drivers/net/tap/tap_bpf_insns.h
index 53fa76c4e6..523dfe7656 100644
--- a/drivers/net/tap/tap_bpf_insns.h
+++ b/drivers/net/tap/tap_bpf_insns.h
@@ -24,395 +24,411 @@ static struct bpf_insn cls_q_insns[] = {
 };
 
 static struct bpf_insn l3_l4_hash_insns[] = {
-	{0xbf,    7,    1,        0, 0x00000000},
-	{0x61,    6,    7,       16, 0x00000000},
-	{0x61,    8,    7,       76, 0x00000000},
-	{0x61,    9,    7,       80, 0x00000000},
+	{0xbf,    6,    1,        0, 0x00000000},
 	{0x18,    1,    0,        0, 0xdeadbeef},
 	{0x00,    0,    0,        0, 0x00000000},
-	{0x63,   10,    1,       -4, 0x00000000},
+	{0x63,   10,    1,      -84, 0x00000000},
 	{0xbf,    2,   10,        0, 0x00000000},
-	{0x07,    2,    0,        0, 0xfffffffc},
+	{0x07,    2,    0,        0, 0xffffffac},
 	{0x18,    1,    0,        0, 0x00000000},
 	{0x00,    0,    0,        0, 0x00000000},
 	{0x85,    0,    0,        0, 0x00000001},
-	{0x55,    0,    0,       21, 0x00000000},
-	{0xb7,    1,    0,        0, 0x00000a64},
-	{0x6b,   10,    1,      -16, 0x00000000},
-	{0x18,    1,    0,        0, 0x69666e6f},
-	{0x00,    0,    0,        0, 0x65727567},
-	{0x7b,   10,    1,      -24, 0x00000000},
-	{0x18,    1,    0,        0, 0x6e207369},
-	{0x00,    0,    0,        0, 0x6320746f},
-	{0x7b,   10,    1,      -32, 0x00000000},
-	{0x18,    1,    0,        0, 0x20737372},
-	{0x00,    0,    0,        0, 0x2079656b},
-	{0x7b,   10,    1,      -40, 0x00000000},
-	{0x18,    1,    0,        0, 0x68736168},
-	{0x00,    0,    0,        0, 0x203a2928},
-	{0x7b,   10,    1,      -48, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0x73,   10,    7,      -14, 0x00000000},
-	{0xbf,    1,   10,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0xffffffd0},
-	{0xb7,    2,    0,        0, 0x00000023},
-	{0x85,    0,    0,        0, 0x00000006},
-	{0x05,    0,    0,     1680, 0x00000000},
-	{0xb7,    1,    0,        0, 0x0000000e},
-	{0x61,    2,    7,       20, 0x00000000},
-	{0x15,    2,    0,       10, 0x00000000},
-	{0x61,    2,    7,       28, 0x00000000},
-	{0x55,    2,    0,        8, 0x0000a888},
-	{0xbf,    2,    7,        0, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0xbf,    1,    8,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0x00000012},
-	{0x2d,    1,    9,     1670, 0x00000000},
-	{0xb7,    1,    0,        0, 0x00000012},
-	{0x69,    6,    8,       16, 0x00000000},
-	{0xbf,    7,    2,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x0000ffff},
-	{0x7b,   10,    7,      -56, 0x00000000},
-	{0x15,    6,    0,      443, 0x0000dd86},
-	{0xb7,    7,    0,        0, 0x00000003},
-	{0x55,    6,    0,     1662, 0x00000008},
-	{0x0f,    8,    1,        0, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0xbf,    1,    8,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0x00000018},
-	{0x2d,    1,    9,     1657, 0x00000000},
+	{0xbf,    7,    0,        0, 0x00000000},
+	{0xb7,    8,    0,        0, 0x00000000},
+	{0x15,    7,    0,     2064, 0x00000000},
+	{0xbf,    3,   10,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0xffffffe0},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0xb7,    2,    0,        0, 0x00000000},
+	{0xb7,    4,    0,        0, 0x0000001c},
+	{0xb7,    5,    0,        0, 0x00000001},
+	{0x85,    0,    0,        0, 0x00000044},
+	{0x55,    0,    0,     2056, 0x00000000},
+	{0x71,    1,   10,      -32, 0x00000000},
+	{0x77,    1,    0,        0, 0x00000004},
+	{0x15,    1,    0,      503, 0x00000006},
+	{0xb7,    8,    0,        0, 0x00000003},
+	{0x55,    1,    0,     2051, 0x00000004},
 	{0xb7,    1,    0,        0, 0x00000000},
-	{0x71,    3,    8,       12, 0x00000000},
-	{0x71,    2,    8,        9, 0x00000000},
+	{0x61,    4,   10,      -20, 0x00000000},
+	{0xdc,    4,    0,        0, 0x00000040},
+	{0xc7,    4,    0,        0, 0x00000020},
+	{0x71,    2,   10,      -23, 0x00000000},
 	{0x15,    2,    0,        1, 0x00000011},
-	{0x55,    2,    0,       21, 0x00000006},
-	{0x71,    2,    8,        7, 0x00000000},
-	{0x71,    4,    8,        6, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x67,    5,    0,        0, 0x00000008},
-	{0x57,    5,    0,        0, 0x00001f00},
-	{0x4f,    5,    2,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x4f,    4,    5,        0, 0x00000000},
-	{0x55,    4,    0,       12, 0x00000000},
-	{0xbf,    2,    8,        0, 0x00000000},
-	{0x07,    2,    0,        0, 0x00000014},
-	{0x71,    4,    2,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000018},
-	{0x71,    1,    2,        1, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000010},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    4,    2,        3, 0x00000000},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    2,    2,        2, 0x00000000},
-	{0x67,    2,    0,        0, 0x00000008},
-	{0x4f,    1,    2,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000038},
-	{0xc7,    4,    0,        0, 0x00000038},
+	{0x55,    2,    0,        5, 0x00000006},
+	{0x69,    2,   10,      -26, 0x00000000},
+	{0x57,    2,    0,        0, 0x0000ff3f},
+	{0x55,    2,    0,        2, 0x00000000},
+	{0x61,    1,   10,      -12, 0x00000000},
+	{0xdc,    1,    0,        0, 0x00000020},
 	{0xb7,    2,    0,        0, 0x00000000},
+	{0xb7,    5,    0,        0, 0x00000000},
 	{0x65,    4,    0,        1, 0xffffffff},
-	{0xb7,    7,    0,        0, 0x2cc681d1},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x598d03a2},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb31a0745},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x66340e8a},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xcc681d15},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000004},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x98d03a2b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000002},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x31a07456},
-	{0x71,    4,    8,       13, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
+	{0xb7,    5,    0,        0, 0x2cc681d1},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x40000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6340e8ad},
+	{0xa7,    5,    0,        0, 0x598d03a2},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc681d15b},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x20000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xb31a0745},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
+	{0x57,    3,    0,        0, 0x10000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d03a2b7},
+	{0xa7,    5,    0,        0, 0x66340e8a},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
+	{0x57,    3,    0,        0, 0x08000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xcc681d15},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x04000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x98d03a2b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x02000000},
+	{0x15,    3,    0,        1, 0x00000000},
+	{0xa7,    5,    0,        0, 0x31a07456},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x01000000},
+	{0x15,    3,    0,        1, 0x00000000},
+	{0xa7,    5,    0,        0, 0x6340e8ad},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00800000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xc681d15b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00400000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x8d03a2b7},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00200000},
 	{0x15,    3,    0,        1, 0x00000000},
 	{0xa7,    5,    0,        0, 0x1a07456f},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
+	{0x57,    3,    0,        0, 0x00100000},
 	{0x15,    3,    0,        1, 0x00000000},
 	{0xa7,    5,    0,        0, 0x340e8ade},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
+	{0x57,    3,    0,        0, 0x00080000},
 	{0x15,    3,    0,        1, 0x00000000},
 	{0xa7,    5,    0,        0, 0x681d15bd},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd03a2b7b},
+	{0x57,    3,    0,        0, 0x00040000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xd03a2b7b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
+	{0x57,    3,    0,        0, 0x00020000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xa07456f6},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00010000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa07456f6},
-	{0x71,    3,    8,       14, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
 	{0xa7,    5,    0,        0, 0x40e8aded},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000038},
-	{0xc7,    4,    0,        0, 0x00000038},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0x81d15bdb},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x03a2b7b7},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x07456f6f},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x0e8adedf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1d15bdbf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000004},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3a2b7b7e},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000002},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7456f6fd},
-	{0x71,    4,    8,       15, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe8adedfa},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd15bdbf4},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00008000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x81d15bdb},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
+	{0x57,    3,    0,        0, 0x00004000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa2b7b7e9},
+	{0xa7,    5,    0,        0, 0x03a2b7b7},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
+	{0x57,    3,    0,        0, 0x00002000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x456f6fd3},
+	{0xa7,    5,    0,        0, 0x07456f6f},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
+	{0x57,    3,    0,        0, 0x00001000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8adedfa7},
+	{0xa7,    5,    0,        0, 0x0e8adedf},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
+	{0x57,    3,    0,        0, 0x00000800},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x15bdbf4f},
+	{0xa7,    5,    0,        0, 0x1d15bdbf},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
+	{0x57,    3,    0,        0, 0x00000400},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x2b7b7e9e},
+	{0xa7,    5,    0,        0, 0x3a2b7b7e},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x56f6fd3d},
-	{0x71,    3,    8,       16, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xadedfa7b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000038},
-	{0xc7,    4,    0,        0, 0x00000038},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5bdbf4f7},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb7b7e9ef},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6f6fd3df},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xdedfa7bf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xbdbf4f7f},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000004},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7b7e9eff},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000002},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf6fd3dff},
-	{0x71,    4,    8,       17, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
+	{0x57,    3,    0,        0, 0x00000200},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xedfa7bfe},
+	{0xa7,    5,    0,        0, 0x7456f6fd},
 	{0xbf,    3,    4,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdbf4f7fc},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000100},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xe8adedfa},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000080},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xd15bdbf4},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb7e9eff9},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xa2b7b7e9},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000020},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6fd3dff2},
+	{0xa7,    5,    0,        0, 0x456f6fd3},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdfa7bfe5},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x8adedfa7},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000008},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbf4f7fca},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7e9eff94},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfd3dff28},
-	{0x71,    3,    8,       18, 0x00000000},
+	{0xa7,    5,    0,        0, 0x15bdbf4f},
+	{0x61,    3,   10,      -16, 0x00000000},
+	{0xbf,    0,    4,        0, 0x00000000},
+	{0x57,    0,    0,        0, 0x00000004},
+	{0x15,    0,    0,        1, 0x00000000},
+	{0xa7,    5,    0,        0, 0x2b7b7e9e},
+	{0xdc,    3,    0,        0, 0x00000040},
+	{0xbf,    0,    4,        0, 0x00000000},
+	{0x57,    0,    0,        0, 0x00000002},
+	{0x15,    0,    0,        1, 0x00000000},
+	{0xa7,    5,    0,        0, 0x56f6fd3d},
+	{0xc7,    3,    0,        0, 0x00000020},
 	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfa7bfe51},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x67,    6,    0,        0, 0x00000038},
-	{0xc7,    6,    0,        0, 0x00000038},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xadedfa7b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    5,        0, 0x00000000},
-	{0xa7,    4,    0,        0, 0xf4f7fca2},
-	{0x6d,    2,    6,        1, 0x00000000},
+	{0xa7,    4,    0,        0, 0x5bdbf4f7},
+	{0x6d,    2,    3,        1, 0x00000000},
 	{0xbf,    4,    5,        0, 0x00000000},
 	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000040},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xb7b7e9ef},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
 	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xe9eff945},
+	{0xa7,    4,    0,        0, 0x6f6fd3df},
 	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000020},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xdedfa7bf},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xbdbf4f7f},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
 	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd3dff28a},
+	{0xa7,    4,    0,        0, 0x7b7e9eff},
 	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000010},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xf6fd3dff},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x01000000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xedfa7bfe},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xdbf4f7fc},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xb7e9eff9},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
 	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xa7bfe514},
+	{0xa7,    4,    0,        0, 0x6fd3dff2},
 	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000008},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xdfa7bfe5},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xbf4f7fca},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
 	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x4f7fca28},
+	{0xa7,    4,    0,        0, 0x7e9eff94},
 	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xfd3dff28},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xfa7bfe51},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xf4f7fca2},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xe9eff945},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xd3dff28a},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xa7bfe514},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
 	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x9eff9450},
+	{0xa7,    4,    0,        0, 0x4f7fca28},
 	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0x9eff9450},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
 	{0x15,    5,    0,        1, 0x00000000},
 	{0xa7,    4,    0,        0, 0x3dff28a0},
-	{0x71,    5,    8,       19, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x15,    5,    0,        1, 0x00000000},
 	{0xa7,    4,    0,        0, 0x7bfe5141},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    7,    4,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf7fca283},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    7,    4,        0, 0x00000000},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xeff94506},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xdff28a0c},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xbfe51418},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7fca2831},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xff945063},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xff28a0c6},
-	{0x57,    5,    0,        0, 0x00000001},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xf7fca283},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xeff94506},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xdff28a0c},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xbfe51418},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
 	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xfe51418c},
-	{0xbf,    4,    1,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000020},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0xbf,    3,    7,        0, 0x00000000},
-	{0xa7,    3,    0,        0, 0xfca28319},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    3,    7,        0, 0x00000000},
+	{0xa7,    4,    0,        0, 0x7fca2831},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000004},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xff945063},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000002},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xff28a0c6},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xfe51418c},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    3,        0, 0x00000000},
+	{0xbf,    5,    1,        0, 0x00000000},
+	{0x67,    5,    0,        0, 0x00000020},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x18,    0,    0,        0, 0xfca28319},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0xaf,    3,    0,        0, 0x00000000},
+	{0x6d,    2,    5,        1, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x40000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf9450633},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xf9450633},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x20000000},
-	{0x79,    6,   10,      -56, 0x00000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf28a0c67},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xf28a0c67},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x10000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xe51418ce},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xe51418ce},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x08000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xca28319d},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xca28319d},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x04000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x9450633b},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0x9450633b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x02000000},
 	{0x15,    2,    0,        1, 0x00000000},
@@ -423,16 +439,20 @@ static struct bpf_insn l3_l4_hash_insns[] = {
 	{0xa7,    3,    0,        0, 0x51418ced},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00800000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xa28319db},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xa28319db},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00400000},
 	{0x15,    2,    0,        1, 0x00000000},
 	{0xa7,    3,    0,        0, 0x450633b6},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00200000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8a0c676c},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0x8a0c676c},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00100000},
 	{0x15,    2,    0,        1, 0x00000000},
@@ -447,16 +467,20 @@ static struct bpf_insn l3_l4_hash_insns[] = {
 	{0xa7,    3,    0,        0, 0x50633b63},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00020000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xa0c676c6},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xa0c676c6},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00010000},
 	{0x15,    2,    0,        1, 0x00000000},
 	{0xa7,    3,    0,        0, 0x418ced8d},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00008000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8319db1a},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0x8319db1a},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00004000},
 	{0x15,    2,    0,        1, 0x00000000},
@@ -479,12 +503,16 @@ static struct bpf_insn l3_l4_hash_insns[] = {
 	{0xa7,    3,    0,        0, 0x633b6347},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000200},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xc676c68f},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xc676c68f},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000100},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8ced8d1f},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0x8ced8d1f},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000080},
 	{0x15,    2,    0,        1, 0x00000000},
@@ -499,12 +527,16 @@ static struct bpf_insn l3_l4_hash_insns[] = {
 	{0xa7,    3,    0,        0, 0x676c68fa},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000010},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xced8d1f4},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xced8d1f4},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000008},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x9db1a3e9},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0x9db1a3e9},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000004},
 	{0x15,    2,    0,        1, 0x00000000},
@@ -514,1078 +546,1336 @@ static struct bpf_insn l3_l4_hash_insns[] = {
 	{0x15,    2,    0,        1, 0x00000000},
 	{0xa7,    3,    0,        0, 0x76c68fa5},
 	{0x57,    1,    0,        0, 0x00000001},
-	{0x15,    1,    0,     1194, 0x00000000},
-	{0xa7,    3,    0,        0, 0xed8d1f4a},
-	{0x05,    0,    0,     1192, 0x00000000},
-	{0x0f,    8,    1,        0, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0xbf,    1,    8,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0x0000002c},
-	{0x2d,    1,    9,     1216, 0x00000000},
-	{0x61,    2,    8,        8, 0x00000000},
-	{0xdc,    2,    0,        0, 0x00000040},
-	{0xc7,    2,    0,        0, 0x00000020},
-	{0x71,    3,    8,        6, 0x00000000},
-	{0x15,    3,    0,        2, 0x00000011},
+	{0x15,    1,    0,     1482, 0x00000000},
+	{0x18,    1,    0,        0, 0xed8d1f4a},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0x05,    0,    0,     1478, 0x00000000},
+	{0xbf,    3,   10,        0, 0x00000000},
+	{0x07,    3,    0,        0, 0xffffffb0},
+	{0xbf,    1,    6,        0, 0x00000000},
+	{0xb7,    2,    0,        0, 0x00000000},
+	{0xb7,    4,    0,        0, 0x00000030},
+	{0xb7,    5,    0,        0, 0x00000001},
+	{0x85,    0,    0,        0, 0x00000044},
+	{0x55,    0,    0,     1542, 0x00000000},
+	{0xb7,    2,    0,        0, 0x00000000},
+	{0x61,    4,   10,      -72, 0x00000000},
+	{0xdc,    4,    0,        0, 0x00000040},
+	{0xc7,    4,    0,        0, 0x00000020},
+	{0x71,    3,   10,      -74, 0x00000000},
 	{0xb7,    1,    0,        0, 0x00000000},
-	{0x55,    3,    0,       12, 0x00000006},
-	{0xbf,    3,    8,        0, 0x00000000},
-	{0x07,    3,    0,        0, 0x00000028},
-	{0x71,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000018},
-	{0x71,    1,    3,        1, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000010},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    4,    3,        3, 0x00000000},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    3,    3,        2, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000008},
-	{0x4f,    1,    3,        0, 0x00000000},
-	{0xbf,    4,    2,        0, 0x00000000},
-	{0x77,    4,    0,        0, 0x0000001f},
-	{0x57,    4,    0,        0, 0x2cc681d1},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x55,    3,    0,        2, 0x00000011},
+	{0x61,    1,   10,      -40, 0x00000000},
+	{0xdc,    1,    0,        0, 0x00000020},
+	{0xb7,    5,    0,        0, 0x00000000},
+	{0x65,    4,    0,        1, 0xffffffff},
+	{0xb7,    5,    0,        0, 0x2cc681d1},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x40000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x598d03a2},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x598d03a2},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb31a0745},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xb31a0745},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x10000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x66340e8a},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x66340e8a},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xcc681d15},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xcc681d15},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x98d03a2b},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x98d03a2b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x02000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x31a07456},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x31a07456},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x01000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x6340e8ad},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x6340e8ad},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xc681d15b},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xc681d15b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x8d03a2b7},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x8d03a2b7},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00200000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x1a07456f},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x1a07456f},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00100000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x340e8ade},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x340e8ade},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00080000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x681d15bd},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x681d15bd},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd03a2b7b},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xd03a2b7b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xa07456f6},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xa07456f6},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00010000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x40e8aded},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x40e8aded},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x81d15bdb},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x81d15bdb},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00004000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x03a2b7b7},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x03a2b7b7},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00002000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x07456f6f},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x07456f6f},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00001000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x0e8adedf},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x0e8adedf},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000800},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x1d15bdbf},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x1d15bdbf},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000400},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x3a2b7b7e},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x3a2b7b7e},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000200},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x7456f6fd},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x7456f6fd},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xe8adedfa},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xe8adedfa},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd15bdbf4},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xd15bdbf4},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xa2b7b7e9},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xa2b7b7e9},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000020},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x456f6fd3},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x456f6fd3},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x8adedfa7},
-	{0xbf,    3,    2,        0, 0x00000000},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x8adedfa7},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000008},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x15bdbf4f},
-	{0x61,    3,    8,       12, 0x00000000},
-	{0xbf,    5,    2,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x2b7b7e9e},
+	{0xa7,    5,    0,        0, 0x15bdbf4f},
+	{0x61,    3,   10,      -68, 0x00000000},
+	{0xbf,    0,    4,        0, 0x00000000},
+	{0x57,    0,    0,        0, 0x00000004},
+	{0x15,    0,    0,        1, 0x00000000},
+	{0xa7,    5,    0,        0, 0x2b7b7e9e},
 	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    2,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x56f6fd3d},
+	{0xbf,    0,    4,        0, 0x00000000},
+	{0x57,    0,    0,        0, 0x00000002},
+	{0x15,    0,    0,        1, 0x00000000},
+	{0xa7,    5,    0,        0, 0x56f6fd3d},
 	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    2,    0,        0, 0x00000001},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xadedfa7b},
-	{0xb7,    2,    0,        0, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0x5bdbf4f7},
+	{0x57,    4,    0,        0, 0x00000001},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xadedfa7b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
+	{0xa7,    4,    0,        0, 0x5bdbf4f7},
 	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x40000000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xb7b7e9ef},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x20000000},
+	{0x15,    5,    0,        1, 0x00000000},
+	{0xa7,    4,    0,        0, 0x6f6fd3df},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x10000000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xdedfa7bf},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x08000000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xbdbf4f7f},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x04000000},
+	{0x15,    5,    0,        1, 0x00000000},
+	{0xa7,    4,    0,        0, 0x7b7e9eff},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x02000000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xf6fd3dff},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x01000000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xedfa7bfe},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00800000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xdbf4f7fc},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00400000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xb7e9eff9},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00200000},
+	{0x15,    5,    0,        1, 0x00000000},
+	{0xa7,    4,    0,        0, 0x6fd3dff2},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00100000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xdfa7bfe5},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00080000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xbf4f7fca},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00040000},
+	{0x15,    5,    0,        1, 0x00000000},
+	{0xa7,    4,    0,        0, 0x7e9eff94},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00020000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xfd3dff28},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00010000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xfa7bfe51},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00008000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xf4f7fca2},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00004000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xe9eff945},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00002000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xd3dff28a},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00001000},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xa7bfe514},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000800},
+	{0x15,    5,    0,        1, 0x00000000},
+	{0xa7,    4,    0,        0, 0x4f7fca28},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000400},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0x9eff9450},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000200},
+	{0x15,    5,    0,        1, 0x00000000},
+	{0xa7,    4,    0,        0, 0x3dff28a0},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000100},
+	{0x15,    5,    0,        1, 0x00000000},
+	{0xa7,    4,    0,        0, 0x7bfe5141},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000080},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xf7fca283},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000040},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xeff94506},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000020},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xdff28a0c},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000010},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xbfe51418},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    5,        0, 0x00000000},
+	{0xbf,    5,    3,        0, 0x00000000},
+	{0x57,    5,    0,        0, 0x00000008},
+	{0x15,    5,    0,        1, 0x00000000},
+	{0xa7,    4,    0,        0, 0x7fca2831},
+	{0x61,    5,   10,      -64, 0x00000000},
+	{0xbf,    0,    3,        0, 0x00000000},
+	{0x57,    0,    0,        0, 0x00000004},
+	{0x15,    0,    0,        3, 0x00000000},
+	{0x18,    0,    0,        0, 0xff945063},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    0,        0, 0x00000000},
+	{0xdc,    5,    0,        0, 0x00000040},
+	{0xbf,    0,    3,        0, 0x00000000},
+	{0x57,    0,    0,        0, 0x00000002},
+	{0x15,    0,    0,        3, 0x00000000},
+	{0x18,    0,    0,        0, 0xff28a0c6},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    0,        0, 0x00000000},
+	{0xc7,    5,    0,        0, 0x00000020},
+	{0x57,    3,    0,        0, 0x00000001},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xfe51418c},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    4,    3,        0, 0x00000000},
+	{0x18,    0,    0,        0, 0xfca28319},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0xaf,    3,    0,        0, 0x00000000},
+	{0x6d,    2,    5,        1, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x40000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb7b7e9ef},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xf9450633},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x20000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6f6fd3df},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xf28a0c67},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x10000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdedfa7bf},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xe51418ce},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x08000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbdbf4f7f},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xca28319d},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x04000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7b7e9eff},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x9450633b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x02000000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf6fd3dff},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x28a0c676},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x01000000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xedfa7bfe},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x51418ced},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00800000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdbf4f7fc},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xa28319db},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00400000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb7e9eff9},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x450633b6},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00200000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6fd3dff2},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x8a0c676c},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00100000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdfa7bfe5},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x1418ced8},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00080000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbf4f7fca},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x28319db1},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00040000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7e9eff94},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x50633b63},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00020000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfd3dff28},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xa0c676c6},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00010000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfa7bfe51},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x418ced8d},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00008000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf4f7fca2},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x8319db1a},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00004000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe9eff945},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x0633b634},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00002000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd3dff28a},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x0c676c68},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00001000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa7bfe514},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x18ced8d1},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000800},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x4f7fca28},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x319db1a3},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000400},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x9eff9450},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x633b6347},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000200},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3dff28a0},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xc676c68f},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000100},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7bfe5141},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x8ced8d1f},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000080},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf7fca283},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x19db1a3e},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000040},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xeff94506},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x33b6347d},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000020},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdff28a0c},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0xa7,    3,    0,        0, 0x676c68fa},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbfe51418},
-	{0xbf,    4,    3,        0, 0x00000000},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xced8d1f4},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0xbf,    4,    5,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7fca2831},
-	{0x61,    4,    8,       16, 0x00000000},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000004},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xff945063},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x9db1a3e9},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    4,        0, 0x00000000},
+	{0x61,    4,   10,      -60, 0x00000000},
+	{0xbf,    0,    5,        0, 0x00000000},
+	{0x57,    0,    0,        0, 0x00000004},
+	{0x15,    0,    0,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x3b6347d2},
 	{0xdc,    4,    0,        0, 0x00000040},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000002},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xff28a0c6},
+	{0xbf,    0,    5,        0, 0x00000000},
+	{0x57,    0,    0,        0, 0x00000002},
+	{0x15,    0,    0,        1, 0x00000000},
+	{0xa7,    3,    0,        0, 0x76c68fa5},
 	{0xc7,    4,    0,        0, 0x00000020},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfe51418c},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0xfca28319},
+	{0x57,    5,    0,        0, 0x00000001},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0xed8d1f4a},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    5,        0, 0x00000000},
+	{0x18,    5,    0,        0, 0xdb1a3e94},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xbf,    0,    3,        0, 0x00000000},
+	{0xaf,    0,    5,        0, 0x00000000},
 	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
+	{0xbf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf9450633},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xb6347d28},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x20000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf28a0c67},
+	{0xa7,    0,    0,        0, 0x6c68fa51},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe51418ce},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xd8d1f4a3},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xca28319d},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xb1a3e946},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x04000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9450633b},
+	{0xa7,    0,    0,        0, 0x6347d28d},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x28a0c676},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xc68fa51a},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x51418ced},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x8d1f4a35},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00800000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa28319db},
+	{0xa7,    0,    0,        0, 0x1a3e946b},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00400000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x450633b6},
+	{0xa7,    0,    0,        0, 0x347d28d7},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00200000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8a0c676c},
+	{0xa7,    0,    0,        0, 0x68fa51ae},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1418ced8},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xd1f4a35c},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x28319db1},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xa3e946b9},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00040000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x50633b63},
+	{0xa7,    0,    0,        0, 0x47d28d73},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa0c676c6},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x8fa51ae7},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00010000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x418ced8d},
+	{0xa7,    0,    0,        0, 0x1f4a35cf},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00008000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8319db1a},
+	{0xa7,    0,    0,        0, 0x3e946b9e},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00004000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x0633b634},
+	{0xa7,    0,    0,        0, 0x7d28d73c},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x0c676c68},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xfa51ae78},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x18ced8d1},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xf4a35cf1},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x319db1a3},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xe946b9e3},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x633b6347},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xd28d73c7},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc676c68f},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xa51ae78e},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000100},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8ced8d1f},
+	{0xa7,    0,    0,        0, 0x4a35cf1c},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x19db1a3e},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x946b9e38},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000040},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x33b6347d},
+	{0xa7,    0,    0,        0, 0x28d73c71},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000020},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x676c68fa},
+	{0xa7,    0,    0,        0, 0x51ae78e3},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xced8d1f4},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xa35cf1c6},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000008},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9db1a3e9},
-	{0x61,    3,    8,       20, 0x00000000},
+	{0xa7,    0,    0,        0, 0x46b9e38d},
+	{0x61,    3,   10,      -56, 0x00000000},
 	{0xbf,    5,    4,        0, 0x00000000},
 	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3b6347d2},
+	{0x15,    5,    0,        3, 0x00000000},
+	{0x18,    5,    0,        0, 0x8d73c71b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    5,        0, 0x00000000},
 	{0xdc,    3,    0,        0, 0x00000040},
 	{0xbf,    5,    4,        0, 0x00000000},
 	{0x57,    5,    0,        0, 0x00000002},
 	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x76c68fa5},
+	{0xa7,    0,    0,        0, 0x1ae78e36},
 	{0xc7,    3,    0,        0, 0x00000020},
 	{0x57,    4,    0,        0, 0x00000001},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xed8d1f4a},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdb1a3e94},
+	{0xa7,    0,    0,        0, 0x35cf1c6c},
+	{0xbf,    5,    0,        0, 0x00000000},
+	{0xa7,    5,    0,        0, 0x6b9e38d9},
 	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
+	{0xbf,    5,    0,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x40000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb6347d28},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xd73c71b2},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x20000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6c68fa51},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xae78e364},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x10000000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd8d1f4a3},
+	{0xa7,    5,    0,        0, 0x5cf1c6c9},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x08000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb1a3e946},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xb9e38d92},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x04000000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6347d28d},
+	{0xa7,    5,    0,        0, 0x73c71b25},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x02000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc68fa51a},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xe78e364b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x01000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d1f4a35},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xcf1c6c96},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00800000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1a3e946b},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x9e38d92c},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00400000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x347d28d7},
+	{0xa7,    5,    0,        0, 0x3c71b259},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00200000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x68fa51ae},
+	{0xa7,    5,    0,        0, 0x78e364b2},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00100000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd1f4a35c},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xf1c6c964},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00080000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa3e946b9},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xe38d92c9},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00040000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x47d28d73},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xc71b2593},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00020000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8fa51ae7},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x8e364b27},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00010000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1f4a35cf},
+	{0xa7,    5,    0,        0, 0x1c6c964e},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00008000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3e946b9e},
+	{0xa7,    5,    0,        0, 0x38d92c9c},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00004000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7d28d73c},
+	{0xa7,    5,    0,        0, 0x71b25938},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00002000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfa51ae78},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xe364b270},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00001000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf4a35cf1},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xc6c964e0},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000800},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe946b9e3},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x8d92c9c0},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000400},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd28d73c7},
+	{0xa7,    5,    0,        0, 0x1b259380},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000200},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa51ae78e},
+	{0xa7,    5,    0,        0, 0x364b2700},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000100},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x4a35cf1c},
+	{0xa7,    5,    0,        0, 0x6c964e01},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000080},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x946b9e38},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xd92c9c03},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x28d73c71},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xb2593807},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000020},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x51ae78e3},
+	{0xa7,    5,    0,        0, 0x64b2700f},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa35cf1c6},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xc964e01e},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x46b9e38d},
-	{0x61,    4,    8,       24, 0x00000000},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000004},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d73c71b},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x92c9c03d},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
+	{0x61,    4,   10,      -52, 0x00000000},
+	{0xbf,    0,    3,        0, 0x00000000},
+	{0x57,    0,    0,        0, 0x00000004},
+	{0x15,    0,    0,        1, 0x00000000},
+	{0xa7,    5,    0,        0, 0x2593807a},
 	{0xdc,    4,    0,        0, 0x00000040},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000002},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1ae78e36},
+	{0xbf,    0,    3,        0, 0x00000000},
+	{0x57,    0,    0,        0, 0x00000002},
+	{0x15,    0,    0,        1, 0x00000000},
+	{0xa7,    5,    0,        0, 0x4b2700f4},
 	{0xc7,    4,    0,        0, 0x00000020},
 	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x35cf1c6c},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6b9e38d9},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x964e01e8},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0xbf,    0,    5,        0, 0x00000000},
+	{0xa7,    0,    0,        0, 0x2c9c03d1},
 	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
+	{0xbf,    0,    5,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x40000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xd73c71b2},
+	{0xa7,    0,    0,        0, 0x593807a3},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xae78e364},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xb2700f46},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x10000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5cf1c6c9},
+	{0xa7,    0,    0,        0, 0x64e01e8d},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb9e38d92},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xc9c03d1a},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x73c71b25},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x93807a35},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x02000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe78e364b},
+	{0xa7,    0,    0,        0, 0x2700f46b},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x01000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xcf1c6c96},
+	{0xa7,    0,    0,        0, 0x4e01e8d6},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9e38d92c},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x9c03d1ad},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00400000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3c71b259},
+	{0xa7,    0,    0,        0, 0x3807a35b},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00200000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x78e364b2},
+	{0xa7,    0,    0,        0, 0x700f46b6},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf1c6c964},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xe01e8d6c},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe38d92c9},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xc03d1ad9},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc71b2593},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x807a35b3},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00020000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8e364b27},
+	{0xa7,    0,    0,        0, 0x00f46b66},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00010000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1c6c964e},
+	{0xa7,    0,    0,        0, 0x01e8d6cc},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00008000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x38d92c9c},
+	{0xa7,    0,    0,        0, 0x03d1ad99},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00004000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x71b25938},
+	{0xa7,    0,    0,        0, 0x07a35b32},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00002000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe364b270},
+	{0xa7,    0,    0,        0, 0x0f46b665},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00001000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc6c964e0},
+	{0xa7,    0,    0,        0, 0x1e8d6cca},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000800},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8d92c9c0},
+	{0xa7,    0,    0,        0, 0x3d1ad994},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000400},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1b259380},
+	{0xa7,    0,    0,        0, 0x7a35b328},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x364b2700},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xf46b6651},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6c964e01},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xe8d6cca2},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xd92c9c03},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xd1ad9944},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb2593807},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xa35b3289},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000020},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x64b2700f},
+	{0xa7,    0,    0,        0, 0x46b66512},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc964e01e},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x8d6cca25},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000008},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x92c9c03d},
-	{0x61,    3,    8,       28, 0x00000000},
+	{0xa7,    0,    0,        0, 0x1ad9944a},
+	{0x61,    3,   10,      -48, 0x00000000},
 	{0xbf,    5,    4,        0, 0x00000000},
 	{0x57,    5,    0,        0, 0x00000004},
 	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x2593807a},
+	{0xa7,    0,    0,        0, 0x35b32894},
 	{0xdc,    3,    0,        0, 0x00000040},
 	{0xbf,    5,    4,        0, 0x00000000},
 	{0x57,    5,    0,        0, 0x00000002},
 	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x4b2700f4},
+	{0xa7,    0,    0,        0, 0x6b665129},
 	{0xc7,    3,    0,        0, 0x00000020},
 	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x964e01e8},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0x2c9c03d1},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xd6cca253},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    4,        0, 0x00000000},
+	{0x18,    4,    0,        0, 0xad9944a7},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xbf,    5,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
+	{0xbf,    5,    0,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x40000000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x593807a3},
+	{0xa7,    5,    0,        0, 0x5b32894f},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x20000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb2700f46},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xb665129f},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x10000000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x64e01e8d},
+	{0xa7,    5,    0,        0, 0x6cca253e},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x08000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc9c03d1a},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xd9944a7d},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x04000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x93807a35},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xb32894fb},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x02000000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x2700f46b},
+	{0xa7,    5,    0,        0, 0x665129f6},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x01000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x4e01e8d6},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xcca253ec},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00800000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x9c03d1ad},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x9944a7d9},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00400000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3807a35b},
+	{0xa7,    5,    0,        0, 0x32894fb2},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00200000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x700f46b6},
+	{0xa7,    5,    0,        0, 0x65129f65},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00100000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe01e8d6c},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xca253eca},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00080000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc03d1ad9},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x944a7d95},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00040000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x807a35b3},
+	{0xa7,    5,    0,        0, 0x2894fb2a},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00020000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x00f46b66},
+	{0xa7,    5,    0,        0, 0x5129f655},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00010000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x01e8d6cc},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xa253ecab},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00008000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x03d1ad99},
+	{0xa7,    5,    0,        0, 0x44a7d956},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00004000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x07a35b32},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x894fb2ac},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00002000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x0f46b665},
+	{0xa7,    5,    0,        0, 0x129f6558},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00001000},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1e8d6cca},
+	{0xa7,    5,    0,        0, 0x253ecab1},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000800},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3d1ad994},
+	{0xa7,    5,    0,        0, 0x4a7d9563},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000400},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7a35b328},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x94fb2ac7},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000200},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf46b6651},
+	{0xa7,    5,    0,        0, 0x29f6558f},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000100},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe8d6cca2},
+	{0xa7,    5,    0,        0, 0x53ecab1e},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000080},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd1ad9944},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0xa7d9563d},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000040},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa35b3289},
+	{0xa7,    5,    0,        0, 0x4fb2ac7a},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x46b66512},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    4,    0,        0, 0x9f6558f5},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    4,        0, 0x00000000},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000010},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d6cca25},
+	{0xa7,    5,    0,        0, 0x3ecab1ea},
 	{0xbf,    4,    3,        0, 0x00000000},
 	{0x57,    4,    0,        0, 0x00000008},
 	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1ad9944a},
-	{0x61,    4,    8,       32, 0x00000000},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000004},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x35b32894},
+	{0xa7,    5,    0,        0, 0x7d9563d5},
+	{0x61,    4,   10,      -44, 0x00000000},
+	{0xbf,    0,    3,        0, 0x00000000},
+	{0x57,    0,    0,        0, 0x00000004},
+	{0x15,    0,    0,        3, 0x00000000},
+	{0x18,    0,    0,        0, 0xfb2ac7ab},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    0,        0, 0x00000000},
 	{0xdc,    4,    0,        0, 0x00000040},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000002},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6b665129},
+	{0xbf,    0,    3,        0, 0x00000000},
+	{0x57,    0,    0,        0, 0x00000002},
+	{0x15,    0,    0,        3, 0x00000000},
+	{0x18,    0,    0,        0, 0xf6558f56},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    0,        0, 0x00000000},
 	{0xc7,    4,    0,        0, 0x00000020},
 	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd6cca253},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0xad9944a7},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xecab1eac},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    5,    3,        0, 0x00000000},
+	{0x18,    3,    0,        0, 0xd9563d59},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xbf,    0,    5,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
+	{0xbf,    0,    5,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5b32894f},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xb2ac7ab2},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x20000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb665129f},
+	{0xa7,    0,    0,        0, 0x6558f564},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6cca253e},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xcab1eac8},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xd9944a7d},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x9563d590},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x04000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb32894fb},
+	{0xa7,    0,    0,        0, 0x2ac7ab20},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x02000000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x665129f6},
+	{0xa7,    0,    0,        0, 0x558f5641},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xcca253ec},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xab1eac83},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00800000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9944a7d9},
+	{0xa7,    0,    0,        0, 0x563d5906},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x32894fb2},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xac7ab20c},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00200000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x65129f65},
+	{0xa7,    0,    0,        0, 0x58f56418},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xca253eca},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xb1eac831},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00080000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x944a7d95},
+	{0xa7,    0,    0,        0, 0x63d59063},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x2894fb2a},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xc7ab20c7},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5129f655},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x8f56418f},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00010000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa253ecab},
+	{0xa7,    0,    0,        0, 0x1eac831e},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00008000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x44a7d956},
+	{0xa7,    0,    0,        0, 0x3d59063c},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00004000},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x894fb2ac},
+	{0xa7,    0,    0,        0, 0x7ab20c78},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x129f6558},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xf56418f0},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x253ecab1},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xeac831e1},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x4a7d9563},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xd59063c2},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x94fb2ac7},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xab20c784},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000200},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x29f6558f},
+	{0xa7,    0,    0,        0, 0x56418f09},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x53ecab1e},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xac831e12},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000080},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa7d9563d},
+	{0xa7,    0,    0,        0, 0x59063c25},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x4fb2ac7a},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xb20c784b},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000020},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9f6558f5},
+	{0xa7,    0,    0,        0, 0x6418f097},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3ecab1ea},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0xc831e12f},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
 	{0xbf,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x00000008},
+	{0x15,    3,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x9063c25f},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
+	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000004},
 	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7d9563d5},
-	{0x61,    3,    8,       36, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xfb2ac7ab},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf6558f56},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xecab1eac},
-	{0xbf,    4,    7,        0, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd9563d59},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    4,    7,        0, 0x00000000},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x40000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb2ac7ab2},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x20000000},
-	{0x79,    6,   10,      -56, 0x00000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x6558f564},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x10000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xcab1eac8},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x08000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x9563d590},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x04000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x2ac7ab20},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x02000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x558f5641},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x01000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xab1eac83},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00800000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x563d5906},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00400000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xac7ab20c},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00200000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x58f56418},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00100000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb1eac831},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00080000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x63d59063},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00040000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xc7ab20c7},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00020000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x8f56418f},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00010000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x1eac831e},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00008000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x3d59063c},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00004000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x7ab20c78},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00002000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xf56418f0},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00001000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xeac831e1},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000800},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd59063c2},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000400},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xab20c784},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000200},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x56418f09},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000100},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xac831e12},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000080},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x59063c25},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000040},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb20c784b},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000020},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x6418f097},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000010},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xc831e12f},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000008},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x9063c25f},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x20c784be},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x418f097c},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x831e12f9},
-	{0xbf,    5,    1,        0, 0x00000000},
-	{0x67,    5,    0,        0, 0x00000020},
-	{0xc7,    5,    0,        0, 0x00000020},
+	{0xa7,    0,    0,        0, 0x20c784be},
 	{0xbf,    3,    4,        0, 0x00000000},
+	{0x57,    3,    0,        0, 0x00000002},
+	{0x15,    3,    0,        1, 0x00000000},
+	{0xa7,    0,    0,        0, 0x418f097c},
+	{0x57,    4,    0,        0, 0x00000001},
+	{0x15,    4,    0,        3, 0x00000000},
+	{0x18,    3,    0,        0, 0x831e12f9},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    0,    3,        0, 0x00000000},
+	{0xbf,    4,    1,        0, 0x00000000},
+	{0x67,    4,    0,        0, 0x00000020},
+	{0xc7,    4,    0,        0, 0x00000020},
+	{0xbf,    3,    0,        0, 0x00000000},
 	{0xa7,    3,    0,        0, 0x063c25f3},
-	{0x6d,    2,    5,        1, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
+	{0x6d,    2,    4,        1, 0x00000000},
+	{0xbf,    3,    0,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x40000000},
 	{0x15,    2,    0,        1, 0x00000000},
@@ -1604,12 +1894,16 @@ static struct bpf_insn l3_l4_hash_insns[] = {
 	{0xa7,    3,    0,        0, 0x63c25f3f},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x04000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xc784be7f},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xc784be7f},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x02000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8f097cff},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0x8f097cff},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x01000000},
 	{0x15,    2,    0,        1, 0x00000000},
@@ -1624,20 +1918,28 @@ static struct bpf_insn l3_l4_hash_insns[] = {
 	{0xa7,    3,    0,        0, 0x784be7f8},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00200000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf097cff0},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xf097cff0},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00100000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xe12f9fe0},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xe12f9fe0},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00080000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xc25f3fc1},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xc25f3fc1},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00040000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x84be7f83},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0x84be7f83},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00020000},
 	{0x15,    2,    0,        1, 0x00000000},
@@ -1656,8 +1958,10 @@ static struct bpf_insn l3_l4_hash_insns[] = {
 	{0xa7,    3,    0,        0, 0x4be7f83f},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00002000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x97cff07f},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0x97cff07f},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00001000},
 	{0x15,    2,    0,        1, 0x00000000},
@@ -1668,32 +1972,44 @@ static struct bpf_insn l3_l4_hash_insns[] = {
 	{0xa7,    3,    0,        0, 0x5f3fc1fd},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000400},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xbe7f83fb},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xbe7f83fb},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000200},
 	{0x15,    2,    0,        1, 0x00000000},
 	{0xa7,    3,    0,        0, 0x7cff07f7},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000100},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf9fe0fee},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xf9fe0fee},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000080},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf3fc1fdc},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xf3fc1fdc},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000040},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xe7f83fb8},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xe7f83fb8},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000020},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xcff07f70},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xcff07f70},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000010},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x9fe0fee1},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0x9fe0fee1},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000008},
 	{0x15,    2,    0,        1, 0x00000000},
@@ -1704,40 +2020,86 @@ static struct bpf_insn l3_l4_hash_insns[] = {
 	{0xa7,    3,    0,        0, 0x7f83fb85},
 	{0xbf,    2,    1,        0, 0x00000000},
 	{0x57,    2,    0,        0, 0x00000002},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xff07f70a},
+	{0x15,    2,    0,        3, 0x00000000},
+	{0x18,    2,    0,        0, 0xff07f70a},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    2,        0, 0x00000000},
 	{0x57,    1,    0,        0, 0x00000001},
-	{0x15,    1,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xfe0fee15},
-	{0x71,    1,    0,      201, 0x00000000},
+	{0x15,    1,    0,        3, 0x00000000},
+	{0x18,    1,    0,        0, 0xfe0fee15},
+	{0x00,    0,    0,        0, 0x00000000},
+	{0xaf,    3,    1,        0, 0x00000000},
+	{0x71,    1,    7,      201, 0x00000000},
 	{0x67,    1,    0,        0, 0x00000008},
-	{0x71,    2,    0,      200, 0x00000000},
+	{0x71,    2,    7,      200, 0x00000000},
 	{0x4f,    1,    2,        0, 0x00000000},
-	{0x71,    2,    0,      202, 0x00000000},
+	{0x71,    2,    7,      202, 0x00000000},
 	{0x67,    2,    0,        0, 0x00000010},
-	{0x71,    4,    0,      203, 0x00000000},
+	{0x71,    4,    7,      203, 0x00000000},
 	{0x67,    4,    0,        0, 0x00000018},
 	{0x4f,    4,    2,        0, 0x00000000},
 	{0x4f,    4,    1,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000020},
-	{0x77,    3,    0,        0, 0x00000020},
 	{0x9f,    3,    4,        0, 0x00000000},
 	{0x57,    3,    0,        0, 0x0000000f},
-	{0x67,    3,    0,        0, 0x00000002},
-	{0x0f,    0,    3,        0, 0x00000000},
-	{0x71,    1,    0,      137, 0x00000000},
+	{0x65,    3,    0,        5, 0x00000007},
+	{0x65,    3,    0,        9, 0x00000003},
+	{0x65,    3,    0,       16, 0x00000001},
+	{0x15,    3,    0,       27, 0x00000000},
+	{0x07,    7,    0,        0, 0x0000008c},
+	{0x05,    0,    0,       40, 0x00000000},
+	{0x65,    3,    0,        8, 0x0000000b},
+	{0x65,    3,    0,       14, 0x00000009},
+	{0x15,    3,    0,       24, 0x00000008},
+	{0x07,    7,    0,        0, 0x000000ac},
+	{0x05,    0,    0,       35, 0x00000000},
+	{0x65,    3,    0,       13, 0x00000005},
+	{0x15,    3,    0,       22, 0x00000004},
+	{0x07,    7,    0,        0, 0x0000009c},
+	{0x05,    0,    0,       31, 0x00000000},
+	{0x65,    3,    0,       12, 0x0000000d},
+	{0x15,    3,    0,       20, 0x0000000c},
+	{0x07,    7,    0,        0, 0x000000bc},
+	{0x05,    0,    0,       27, 0x00000000},
+	{0x15,    3,    0,       19, 0x00000002},
+	{0x07,    7,    0,        0, 0x00000094},
+	{0x05,    0,    0,       24, 0x00000000},
+	{0x15,    3,    0,       18, 0x0000000a},
+	{0x07,    7,    0,        0, 0x000000b4},
+	{0x05,    0,    0,       21, 0x00000000},
+	{0x15,    3,    0,       17, 0x00000006},
+	{0x07,    7,    0,        0, 0x000000a4},
+	{0x05,    0,    0,       18, 0x00000000},
+	{0x15,    3,    0,       16, 0x0000000e},
+	{0x07,    7,    0,        0, 0x000000c4},
+	{0x05,    0,    0,       15, 0x00000000},
+	{0x07,    7,    0,        0, 0x00000088},
+	{0x05,    0,    0,       13, 0x00000000},
+	{0x07,    7,    0,        0, 0x000000a8},
+	{0x05,    0,    0,       11, 0x00000000},
+	{0x07,    7,    0,        0, 0x00000098},
+	{0x05,    0,    0,        9, 0x00000000},
+	{0x07,    7,    0,        0, 0x000000b8},
+	{0x05,    0,    0,        7, 0x00000000},
+	{0x07,    7,    0,        0, 0x00000090},
+	{0x05,    0,    0,        5, 0x00000000},
+	{0x07,    7,    0,        0, 0x000000b0},
+	{0x05,    0,    0,        3, 0x00000000},
+	{0x07,    7,    0,        0, 0x000000a0},
+	{0x05,    0,    0,        1, 0x00000000},
+	{0x07,    7,    0,        0, 0x000000c0},
+	{0x71,    1,    7,        1, 0x00000000},
 	{0x67,    1,    0,        0, 0x00000008},
-	{0x71,    2,    0,      136, 0x00000000},
+	{0x71,    2,    7,        0, 0x00000000},
 	{0x4f,    1,    2,        0, 0x00000000},
-	{0x71,    2,    0,      138, 0x00000000},
+	{0x71,    2,    7,        2, 0x00000000},
 	{0x67,    2,    0,        0, 0x00000010},
-	{0x71,    3,    0,      139, 0x00000000},
+	{0x71,    3,    7,        3, 0x00000000},
 	{0x67,    3,    0,        0, 0x00000018},
 	{0x4f,    3,    2,        0, 0x00000000},
 	{0x4f,    3,    1,        0, 0x00000000},
 	{0x07,    3,    0,        0, 0x7cafe800},
 	{0x63,    6,    3,       52, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000001},
-	{0xbf,    0,    7,        0, 0x00000000},
+	{0xb7,    8,    0,        0, 0x00000001},
+	{0xbf,    0,    8,        0, 0x00000000},
 	{0x95,    0,    0,        0, 0x00000000},
 };
-- 
2.39.1.windows.1


^ permalink raw reply	[relevance 1%]

* Re: [dpdk-dev] [v1] ethdev: support Tx queue used count
  @ 2024-01-12 12:11  3%     ` David Marchand
  2024-01-12 14:25  3%       ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: David Marchand @ 2024-01-12 12:11 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: jerinj, dev, Thomas Monjalon, Andrew Rybchenko, ferruh.yigit,
	ajit.khaparde, aboyer, beilei.xing, bruce.richardson, chas3,
	chenbo.xia, ciara.loftus, dsinghrawat, ed.czeck, evgenys, grive,
	g.singh, zhouguoyang, haiyue.wang, hkalra, heinrich.kuhn,
	hemant.agrawal, hyonkim, igorch, irusskikh, jgrajcia,
	jasvinder.singh, jianwang, jiawenwu, jingjing.wu, johndale,
	john.miller, linville, keith.wiles, kirankumark, oulijun, lironh,
	longli, mw, spinler, matan, matt.peters, maxime.coquelin, mk,
	humin29, pnalla, ndabilpuram, qiming.yang, qi.z.zhang, radhac,
	rahul.lakkireddy, rmody, rosen.xu, sachin.saxena, skoteshwar,
	shshaikh, shaibran, shepard.siegel, asomalap, somnath.kotur,
	sthemmin, steven.webster, skori, mtetsuyah, vburru, viacheslavo,
	xiao.w.wang, cloud.wangxiaoyun, yisen.zhuang, yongwang,
	xuanziyang2, cristian.dumitrescu

On Fri, Jan 12, 2024 at 12:34 PM Ferruh Yigit <ferruh.yigit@amd.com> wrote:
> > diff --git a/lib/ethdev/rte_ethdev_core.h b/lib/ethdev/rte_ethdev_core.h
> > index 4bfaf79c6c..d3f09f390d 100644
> > --- a/lib/ethdev/rte_ethdev_core.h
> > +++ b/lib/ethdev/rte_ethdev_core.h
> > @@ -60,6 +60,9 @@ typedef uint16_t (*eth_recycle_tx_mbufs_reuse_t)(void *txq,
> >  /** @internal Refill Rx descriptors with the recycling mbufs */
> >  typedef void (*eth_recycle_rx_descriptors_refill_t)(void *rxq, uint16_t nb);
> >
> > +/** @internal Get number of used descriptors on a transmit queue. */
> > +typedef int (*eth_tx_queue_count_t)(void *txq);
> > +
>
> Can you please move it above 'tx_descriptor_status', to keep same order
> kept in many other locations:
> rx_queue_count
> rx_descriptor_status
> tx_queue_count
> tx_descriptor_status
>
>
> >  /**
> >   * @internal
> >   * Structure used to hold opaque pointers to internal ethdev Rx/Tx
> > @@ -116,7 +119,9 @@ struct rte_eth_fp_ops {
> >       eth_tx_descriptor_status_t tx_descriptor_status;
> >       /** Copy used mbufs from Tx mbuf ring into Rx. */
> >       eth_recycle_tx_mbufs_reuse_t recycle_tx_mbufs_reuse;
> > -     uintptr_t reserved2[2];
> > +     /** Get the number of used Tx descriptors. */
> > +     eth_tx_queue_count_t tx_queue_count;
> >
>
> Similarly, can you please move it above 'tx_descriptor_status'?

Moving fields in rte_eth_fp_ops (where fast-path API ops are) breaks
the applications ABI.


-- 
David Marchand


^ permalink raw reply	[relevance 3%]

* Re: [dpdk-dev] [v1] ethdev: support Tx queue used count
  2024-01-12  8:02  4%   ` David Marchand
@ 2024-01-12  9:29  0%     ` Jerin Jacob
  0 siblings, 0 replies; 200+ results
From: Jerin Jacob @ 2024-01-12  9:29 UTC (permalink / raw)
  To: David Marchand
  Cc: jerinj, dev, Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko,
	ferruh.yigit, ajit.khaparde, aboyer, beilei.xing,
	bruce.richardson, chas3, chenbo.xia, ciara.loftus, dsinghrawat,
	ed.czeck, evgenys, grive, g.singh, zhouguoyang, haiyue.wang,
	hkalra, heinrich.kuhn, hemant.agrawal, hyonkim, igorch,
	irusskikh, jgrajcia, jasvinder.singh, jianwang, jiawenwu,
	jingjing.wu, johndale, john.miller, linville, keith.wiles,
	kirankumark, oulijun, lironh, longli, mw, spinler, matan,
	matt.peters, maxime.coquelin, mk, humin29, pnalla, ndabilpuram,
	qiming.yang, qi.z.zhang, radhac, rahul.lakkireddy, rmody,
	rosen.xu, sachin.saxena, skoteshwar, shshaikh, shaibran,
	shepard.siegel, asomalap, somnath.kotur, sthemmin,
	steven.webster, skori, mtetsuyah, vburru, viacheslavo,
	xiao.w.wang, cloud.wangxiaoyun, yisen.zhuang, yongwang,
	xuanziyang2, cristian.dumitrescu

On Fri, Jan 12, 2024 at 1:33 PM David Marchand
<david.marchand@redhat.com> wrote:
>
> Hi Jerin,
>
> On Thu, Jan 11, 2024 at 4:32 PM <jerinj@marvell.com> wrote:
> >
> > From: Jerin Jacob <jerinj@marvell.com>
> >
> > Introduce a new API to retrieve the number of used descriptors
> > in a Tx queue. Applications can leverage this API in the fast path to
> > inspect the Tx queue occupancy and take appropriate actions based on the
> > available free descriptors.
> >
> > A notable use case could be implementing Random Early Discard (RED)
> > in software based on Tx queue occupancy.
> >
> > Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> > ---
> >  doc/guides/nics/features.rst         | 10 ++++
> >  doc/guides/nics/features/default.ini |  1 +
> >  lib/ethdev/ethdev_driver.h           |  2 +
> >  lib/ethdev/ethdev_private.c          |  1 +
> >  lib/ethdev/ethdev_trace_points.c     |  3 ++
> >  lib/ethdev/rte_ethdev.h              | 74 ++++++++++++++++++++++++++++
> >  lib/ethdev/rte_ethdev_core.h         |  7 ++-
> >  lib/ethdev/rte_ethdev_trace_fp.h     |  8 +++
> >  lib/ethdev/version.map               |  3 ++
> >  9 files changed, 108 insertions(+), 1 deletion(-)
>
> We need some libabigail suppression rule for the reserved2 field update.
> Looking at some previous rules, something like below can do the trick.
>
> diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
> index 21b8cd6113..ba240f74d5 100644
> --- a/devtools/libabigail.abignore
> +++ b/devtools/libabigail.abignore
> @@ -33,3 +33,6 @@
>  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>  ; Temporary exceptions till next major ABI version ;
>  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> +[suppress_type]
> +        name = rte_eth_fp_ops
> +        has_data_member_inserted_between = {offset_of(reserved2), end}

Thanks David. will fix in v2.


>
> --
> David Marchand
>

^ permalink raw reply	[relevance 0%]

* Re: [dpdk-dev] [v1] ethdev: support Tx queue used count
  @ 2024-01-12  8:02  4%   ` David Marchand
  2024-01-12  9:29  0%     ` Jerin Jacob
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 200+ results
From: David Marchand @ 2024-01-12  8:02 UTC (permalink / raw)
  To: jerinj
  Cc: dev, Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko,
	ferruh.yigit, ajit.khaparde, aboyer, beilei.xing,
	bruce.richardson, chas3, chenbo.xia, ciara.loftus, dsinghrawat,
	ed.czeck, evgenys, grive, g.singh, zhouguoyang, haiyue.wang,
	hkalra, heinrich.kuhn, hemant.agrawal, hyonkim, igorch,
	irusskikh, jgrajcia, jasvinder.singh, jianwang, jiawenwu,
	jingjing.wu, johndale, john.miller, linville, keith.wiles,
	kirankumark, oulijun, lironh, longli, mw, spinler, matan,
	matt.peters, maxime.coquelin, mk, humin29, pnalla, ndabilpuram,
	qiming.yang, qi.z.zhang, radhac, rahul.lakkireddy, rmody,
	rosen.xu, sachin.saxena, skoteshwar, shshaikh, shaibran,
	shepard.siegel, asomalap, somnath.kotur, sthemmin,
	steven.webster, skori, mtetsuyah, vburru, viacheslavo,
	xiao.w.wang, cloud.wangxiaoyun, yisen.zhuang, yongwang,
	xuanziyang2, cristian.dumitrescu

Hi Jerin,

On Thu, Jan 11, 2024 at 4:32 PM <jerinj@marvell.com> wrote:
>
> From: Jerin Jacob <jerinj@marvell.com>
>
> Introduce a new API to retrieve the number of used descriptors
> in a Tx queue. Applications can leverage this API in the fast path to
> inspect the Tx queue occupancy and take appropriate actions based on the
> available free descriptors.
>
> A notable use case could be implementing Random Early Discard (RED)
> in software based on Tx queue occupancy.
>
> Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> ---
>  doc/guides/nics/features.rst         | 10 ++++
>  doc/guides/nics/features/default.ini |  1 +
>  lib/ethdev/ethdev_driver.h           |  2 +
>  lib/ethdev/ethdev_private.c          |  1 +
>  lib/ethdev/ethdev_trace_points.c     |  3 ++
>  lib/ethdev/rte_ethdev.h              | 74 ++++++++++++++++++++++++++++
>  lib/ethdev/rte_ethdev_core.h         |  7 ++-
>  lib/ethdev/rte_ethdev_trace_fp.h     |  8 +++
>  lib/ethdev/version.map               |  3 ++
>  9 files changed, 108 insertions(+), 1 deletion(-)

We need some libabigail suppression rule for the reserved2 field update.
Looking at some previous rules, something like below can do the trick.

diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index 21b8cd6113..ba240f74d5 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -33,3 +33,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Temporary exceptions till next major ABI version ;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+[suppress_type]
+        name = rte_eth_fp_ops
+        has_data_member_inserted_between = {offset_of(reserved2), end}


-- 
David Marchand


^ permalink raw reply	[relevance 4%]

* RE: [PATCH] doc: update minimum Linux kernel version
  2024-01-11 19:54  3%       ` Stephen Hemminger
@ 2024-01-11 22:38  0%         ` Morten Brørup
  2024-02-16  3:05  0%           ` Stephen Hemminger
  0 siblings, 1 reply; 200+ results
From: Morten Brørup @ 2024-01-11 22:38 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Patrick Robb, Aaron Conole, dev

> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Thursday, 11 January 2024 20.55
> 
> On Thu, 11 Jan 2024 20:26:56 +0100
> Morten Brørup <mb@smartsharesystems.com> wrote:
> 
> >
> >
> > When the documentation specifies a minimum required kernel version,
> it implicitly claims that DPDK works with that kernel version.
> >
> > So we should either test with the specified kernel version (which
> requires significant effort to set up, so I’m not going to ask for
> it!), or add a big fat disclaimer/warning that DPDK is not tested with
> the mentioned kernel version, and list the kernel versions actually
> tested.
> 
> It is much less of an issue than it used to be since there should be no
> need for
> DPDK specific kernel components. The kernel API/ABI is stable across
> releases
> (with the notable exception of BPF). Therefore the DPDK kernel version
> dependency
> is much less than it used to be.

That is my experience too.
Your BPF exception is a great example of the Devil being in the details!
Last time we upgraded the kernel version in our appliances (because we needed a feature not available in the old kernel we were using), we ran into two major problems; the first was so bad that we eventually gave up on debugging it and moved on to yet a newer kernel version; the second was a well documented API change, and thus relatively easy to fix (by using the new API instead of the old) once it started causing problems.

I think many hardware appliances (like ours) are using very old kernel versions, mainly for historical reasons.
Jumping ahead to a modern kernel version seems risky, so taking small steps still leaves us on old kernel versions.
There are also build environment issues, i.e. building a certain kernel version only works with certain GCC versions; you cannot build an old kernel version using a new GCC version or vice versa.
And similar dependencies between libc versions and kernel versions.
And root file system dependencies, mainly expectations to what is in /dev and /proc.
And it's not only DPDK itself and DPDK applications that may run into issues when upgrading the kernel version. Any application or library on the system might run into similar or other problems when upgrading to a newer kernel version.

So the easy solution is to simply stick with whatever kernel version was used for the system initially, and never upgrade it. Or only upgrade to a slightly newer version, to keep the knock-on effect at a minimum.
(The distro companies must be putting significant effort into keeping up with new versions of kernels, libraries and applications, to offer new features and ensure system-wide interoperability. The resulting value of this should be appreciated!)

> 
> Poking around the source, still see some leftovers.
> 
> Like quick assist documentation wanting kernel version for sources?
> Why does QAT depend on kernel source being present. Thats not right.
> 
> The other bad spot is the Intel GVE driver reading and passing
> the OS version in. Looks like some host side validation.
> 
> Putting OS version anywhere in DPDK is a mistake.

Interesting observations. Again, I agree very much - it is likely to become problematic to maintain and/or use with other OS versions than its developer had originally foreseen.


^ permalink raw reply	[relevance 0%]

* Re: [PATCH] doc: update minimum Linux kernel version
  @ 2024-01-11 19:54  3%       ` Stephen Hemminger
  2024-01-11 22:38  0%         ` Morten Brørup
  0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2024-01-11 19:54 UTC (permalink / raw)
  To: Morten Brørup; +Cc: Patrick Robb, Aaron Conole, dev

On Thu, 11 Jan 2024 20:26:56 +0100
Morten Brørup <mb@smartsharesystems.com> wrote:

>  
> 
> When the documentation specifies a minimum required kernel version, it implicitly claims that DPDK works with that kernel version.
> 
> So we should either test with the specified kernel version (which requires significant effort to set up, so I’m not going to ask for it!), or add a big fat disclaimer/warning that DPDK is not tested with the mentioned kernel version, and list the kernel versions actually tested.

It is much less of an issue than it used to be since there should be no need for
DPDK specific kernel components. The kernel API/ABI is stable across releases 
(with the notable exception of BPF). Therefore the DPDK kernel version dependency
is much less than it used to be.

Poking around the source, still see some leftovers.

Like quick assist documentation wanting kernel version for sources?
Why does QAT depend on kernel source being present. Thats not right.

The other bad spot is the Intel GVE driver reading and passing
the OS version in. Looks like some host side validation.

Putting OS version anywhere in DPDK is a mistake.

^ permalink raw reply	[relevance 3%]

* Re: [v7 1/1] net/af_xdp: fix multi interface support for K8s
  2024-01-11 12:21  0%         ` Maryam Tahhan
  2024-01-11 13:28  0%           ` Kevin Traynor
@ 2024-01-11 14:21  0%           ` Ferruh Yigit
  2024-02-07 23:24  0%             ` Ferruh Yigit
  1 sibling, 1 reply; 200+ results
From: Ferruh Yigit @ 2024-01-11 14:21 UTC (permalink / raw)
  To: Maryam Tahhan, stephen, lihuisong, fengchengwen, liuyonglong,
	david.marchand
  Cc: dev, Ciara Loftus, Shibin Koikkara Reeny, Kevin Traynor, Luca Boccassi

On 1/11/2024 12:21 PM, Maryam Tahhan wrote:
> On 11/01/2024 11:35, Ferruh Yigit wrote:
>> Devarg is user interface, changing it impacts the user.
>>
>> Assume that user of '22.11.3' using 'use_cni' dev_arg, it will be broken
>> when user upgrades DPDK to '22.11.4', which is not expected.
>>
>> dev_arg is not API/ABI but as it impacts the user, it is in the gray
>> area to backport to the LTS release.
> Fair enough
>> Current patch doesn't have Fixes tag or stable tag, so it doesn't
>> request to be backported to LTS release. I took this as an improvement,
>> more than a fix.
> 
> This was overlooked by me apologies. It's been a while since I've
> contributed to DPDK and I must've missed this detail in the contribution
> guide.
>> As far as I understand existing code (that use 'use_cni' dev_arg)
>> supports only single netdev, this patch adds support for multiple netdevs.
> 
> The use_cni implementation will no longer work with the AF_XDP DP as the
> use_cni was originally implemented as it has hard coded what's now an
> incorrect path for the UDS.
> 
>> So what do you think keep LTS with 'use_cni' dev_arg, is there a
>> requirement to update LTS release?
>> If so, can it be an option to keep 'use_cni' for backward compatibility
>> but add only add 'uds_path' and remove 'use_cni' in next LTS?
> 
> 
> Yeah we can go back to the version of the patch that had the 'use_cni'
> flag that was used in combination with the path argument. We can add
> better documentation re the "use_cni" misnomer... What we can then do is
> if no path argument is set by the user assume their intent and and
> generate the path internally in the AF_XDP PMD (which was suggested by
> Shibin at some stage). That way there should be no surprises to the End
> User.
> 

Ack, this keeps backward compatibility,

BUT if 'use_cni' is already broken in v23.11 (that is what I understand
from your above comment), means there is no user of it in LTS, and we
can be more pragmatic and replace the dev_args, by backporting this
patch, assuming LTS maintainer is also OK with it.


> Long term I would like to keep a (renamed) path argument (in case the
> path does ever change from the AF_XDP DP POV) and use it also in
> combination with another (maybe boolean) param for passing pinned bpf
> maps rather than another separate path.
> 
> WDYT? Would this work for the LTS release?
> 
> 


^ permalink raw reply	[relevance 0%]

* Re: [v7 1/1] net/af_xdp: fix multi interface support for K8s
  2024-01-11 12:21  0%         ` Maryam Tahhan
@ 2024-01-11 13:28  0%           ` Kevin Traynor
  2024-01-11 14:21  0%           ` Ferruh Yigit
  1 sibling, 0 replies; 200+ results
From: Kevin Traynor @ 2024-01-11 13:28 UTC (permalink / raw)
  To: Maryam Tahhan, Ferruh Yigit, stephen, lihuisong, fengchengwen,
	liuyonglong, david.marchand
  Cc: dev, Ciara Loftus, Shibin Koikkara Reeny, Luca Boccassi

On 11/01/2024 12:21, Maryam Tahhan wrote:
> On 11/01/2024 11:35, Ferruh Yigit wrote:
>> Devarg is user interface, changing it impacts the user.
>>
>> Assume that user of '22.11.3' using 'use_cni' dev_arg, it will be broken
>> when user upgrades DPDK to '22.11.4', which is not expected.
>>
>> dev_arg is not API/ABI but as it impacts the user, it is in the gray
>> area to backport to the LTS release.
> Fair enough
>>
>>
>> Current patch doesn't have Fixes tag or stable tag, so it doesn't
>> request to be backported to LTS release. I took this as an improvement,
>> more than a fix.
> 
> This was overlooked by me apologies. It's been a while since I've 
> contributed to DPDK and I must've missed this detail in the contribution 
> guide.
>> As far as I understand existing code (that use 'use_cni' dev_arg)
>> supports only single netdev, this patch adds support for multiple netdevs.
> 
> The use_cni implementation will no longer work with the AF_XDP DP as the 
> use_cni was originally implemented as it has hard coded what's now an 
> incorrect path for the UDS.
> 
>>
>> So what do you think keep LTS with 'use_cni' dev_arg, is there a
>> requirement to update LTS release?
>> If so, can it be an option to keep 'use_cni' for backward compatibility
>> but add only add 'uds_path' and remove 'use_cni' in next LTS?
> 
> 
> Yeah we can go back to the version of the patch that had the 'use_cni' 
> flag that was used in combination with the path argument. We can add 
> better documentation re the "use_cni" misnomer... What we can then do is 
> if no path argument is set by the user assume their intent and and 
> generate the path internally in the AF_XDP PMD (which was suggested by 
> Shibin at some stage). That way there should be no surprises to the End 
> User.
> 

That plan sounds like it wouldn't impact a user upgrading from 23.11.0
to 23.11.X which is always the main concern.

> Long term I would like to keep a (renamed) path argument (in case the 
> path does ever change from the AF_XDP DP POV) and use it also in 
> combination with another (maybe boolean) param for passing pinned bpf 
> maps rather than another separate path.
> 
> WDYT? Would this work for the LTS release?
> 
> 

Is it needed on LTS branch? If the current limitation was an oversight
or it's not really usable as intended, then I'd say yes. If not, then
please consider the questions in
http://doc.dpdk.org/guides/contributing/stable.html#what-changes-should-be-backported

Seems like it's for
Fixes: 7fc6ae50369d ("net/af_xdp: support CNI Integration")
so it would be only relevant for 23.11 only, so 23.11 maintainer (TBC)
should ack.

I suggest if you feel it should be backported, add the Fixes: and stable
tags, and 23.11 maintainer can review at some point before backport.

thanks,
Kevin.


^ permalink raw reply	[relevance 0%]

* Re: [v7 1/1] net/af_xdp: fix multi interface support for K8s
  2024-01-11 11:35  3%       ` Ferruh Yigit
@ 2024-01-11 12:21  0%         ` Maryam Tahhan
  2024-01-11 13:28  0%           ` Kevin Traynor
  2024-01-11 14:21  0%           ` Ferruh Yigit
  0 siblings, 2 replies; 200+ results
From: Maryam Tahhan @ 2024-01-11 12:21 UTC (permalink / raw)
  To: Ferruh Yigit, stephen, lihuisong, fengchengwen, liuyonglong,
	david.marchand
  Cc: dev, Ciara Loftus, Shibin Koikkara Reeny, Kevin Traynor, Luca Boccassi

[-- Attachment #1: Type: text/plain, Size: 1972 bytes --]

On 11/01/2024 11:35, Ferruh Yigit wrote:
> Devarg is user interface, changing it impacts the user.
>
> Assume that user of '22.11.3' using 'use_cni' dev_arg, it will be broken
> when user upgrades DPDK to '22.11.4', which is not expected.
>
> dev_arg is not API/ABI but as it impacts the user, it is in the gray
> area to backport to the LTS release.
Fair enough
>
>
> Current patch doesn't have Fixes tag or stable tag, so it doesn't
> request to be backported to LTS release. I took this as an improvement,
> more than a fix.

This was overlooked by me apologies. It's been a while since I've 
contributed to DPDK and I must've missed this detail in the contribution 
guide.
> As far as I understand existing code (that use 'use_cni' dev_arg)
> supports only single netdev, this patch adds support for multiple netdevs.

The use_cni implementation will no longer work with the AF_XDP DP as the 
use_cni was originally implemented as it has hard coded what's now an 
incorrect path for the UDS.

>
> So what do you think keep LTS with 'use_cni' dev_arg, is there a
> requirement to update LTS release?
> If so, can it be an option to keep 'use_cni' for backward compatibility
> but add only add 'uds_path' and remove 'use_cni' in next LTS?


Yeah we can go back to the version of the patch that had the 'use_cni' 
flag that was used in combination with the path argument. We can add 
better documentation re the "use_cni" misnomer... What we can then do is 
if no path argument is set by the user assume their intent and and 
generate the path internally in the AF_XDP PMD (which was suggested by 
Shibin at some stage). That way there should be no surprises to the End 
User.

Long term I would like to keep a (renamed) path argument (in case the 
path does ever change from the AF_XDP DP POV) and use it also in 
combination with another (maybe boolean) param for passing pinned bpf 
maps rather than another separate path.

WDYT? Would this work for the LTS release?


[-- Attachment #2: Type: text/html, Size: 2825 bytes --]

^ permalink raw reply	[relevance 0%]

* Re: [v7 1/1] net/af_xdp: fix multi interface support for K8s
  @ 2024-01-11 11:35  3%       ` Ferruh Yigit
  2024-01-11 12:21  0%         ` Maryam Tahhan
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2024-01-11 11:35 UTC (permalink / raw)
  To: Maryam Tahhan, stephen, lihuisong, fengchengwen, liuyonglong,
	david.marchand
  Cc: dev, Ciara Loftus, Shibin Koikkara Reeny, Kevin Traynor, Luca Boccassi

On 1/11/2024 9:01 AM, Maryam Tahhan wrote:
> On 10/01/2024 15:21, Ferruh Yigit wrote:
>> On 1/10/2024 2:58 PM, Maryam Tahhan wrote:
>>> Hi folks
>>>
>>> Just wondering if there's any other comments re this patch after all the
>>> review comments were addressed?
>>>
>> Hi Maryam,
>>
>> There was a request from David, to the previous version, that fixes
>> (either to code or document) should be separated into its own patch, so
>> that they can be merged to our LTS (say 21.11.x) releases, to make sure
>> LTS release has correct info/code. On top of it your changes can be
>> another patch.
>>
>> As document completely changed, it is not easy for me to say, can you
>> please confirm that there is no fix to the documentation unrelated with
>> your code change?
>>
> Hey Ferruh
> 
> Yes - I should've clarified. I took David's comments into consideration.
> The old use_cni implementation is broken (so if a DPDK pod wants
> multiple AF_XDP interfaces it will not work). So IMHO it doesn't make
> sense to patch documentation for something that is broken. The whole
> change would need to be back ported to LTS.
> 

Devarg is user interface, changing it impacts the user.

Assume that user of '22.11.3' using 'use_cni' dev_arg, it will be broken
when user upgrades DPDK to '22.11.4', which is not expected.

dev_arg is not API/ABI but as it impacts the user, it is in the gray
area to backport to the LTS release.


Current patch doesn't have Fixes tag or stable tag, so it doesn't
request to be backported to LTS release. I took this as an improvement,
more than a fix.

As far as I understand existing code (that use 'use_cni' dev_arg)
supports only single netdev, this patch adds support for multiple netdevs.

So what do you think keep LTS with 'use_cni' dev_arg, is there a
requirement to update LTS release?
If so, can it be an option to keep 'use_cni' for backward compatibility
but add only add 'uds_path' and remove 'use_cni' in next LTS?

> 
> However, I have a second change to apply on top of this - so I will send
> a series. So please hold off merging for now.
> 
> BR
> Maryam
> 


^ permalink raw reply	[relevance 3%]

* Re: [PATCH] build: fix linker warnings about undefined symbols
  @ 2024-01-11  9:48  4%     ` Bruce Richardson
  2024-01-12 20:11  0%       ` Tyler Retzlaff
  0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2024-01-11  9:48 UTC (permalink / raw)
  To: Morten Brørup; +Cc: Tyler Retzlaff, dev

On Thu, Jan 11, 2024 at 10:38:05AM +0100, Morten Brørup wrote:
> > From: Tyler Retzlaff [mailto:roretzla@linux.microsoft.com]
> > Sent: Wednesday, 10 January 2024 17.58
> > 
> > On Wed, Jan 10, 2024 at 03:01:03PM +0000, Bruce Richardson wrote:
> > > The default behaviour of "ld.lld" has changed, so it now prints out
> > > warnings about entries in the version.map file which don't exist in
> > > the current build. Since we use our version.map file simply to filter
> > > out the functions we don't want made public, we include in it all
> > > functions across all OS's and builds that we want public if present.
> > > This causes these ld warnings to be emitted, e.g. on BSD, which is
> > > missing functionality found on Linux. For example:
> > >
> > > * hpet functions in EAL
> > > * regexdev enqueue and dequeue burst
> > > * eventdev event_timer functions
> > >
> > > Easiest solution, without major rework of how we use our version.map
> > > files, and without dynamically generating them per-build, is to pass
> > > the --undefined-version flag to the linker, to restore the old
> > > behaviour.
> > >
> > > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > > ---
> > 
> > Acked-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
> > 
> > i don't know if has ever been discussed but a way to achieve a similar
> > outcome would be to introduce a visibility macro allowing the data and
> > function symbols to be explicitly made visible while making the build
> > default hidden.
> > 
> > https://gcc.gnu.org/wiki/Visibility
> 
> This looks interesting!
> Declaring a function "public" directly in its header seems much simpler to manage than having to add it to the version.map file too.
> 
> I wonder if function versioning is still supported if using this instead of version.map files?
> Of if there are other relevant reasons for continuing to use the version.map files instead of this?
> 

I don't see in that wiki page and details of how to mark symbols with
different ABI versions. For example, as well as listing what functions are
public, our version.map files also identify the ABI version (e.g. DPDK_24)
they belong to, or whether they are experimental or internal. Having them
all in the version file also makes it easy to see how many experimental
functions we have in each component.

/Bruce

^ permalink raw reply	[relevance 4%]

* Re: rte_eth_dev_data reorganization needed
  2024-01-08 17:14  3% rte_eth_dev_data reorganization needed Stephen Hemminger
@ 2024-01-09 16:58  3% ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2024-01-09 16:58 UTC (permalink / raw)
  To: Stephen Hemminger, dev
  Cc: Thomas Monjalon, Jerin Jacob Kollanukkaran, Qi Z Zhang

On 1/8/2024 5:14 PM, Stephen Hemminger wrote:
> While looking at ethdev (for pdump issues) noticed.
> The rte_eth_dev_data structure layout is unorganized.
> Lots of holes, fields not arranged in logical groups
> and usage could be localized for better cache access.
> 

For reference following is structure layout [1].

Agree that it can benefit from reorganization.

> Obviously, any reorg is ABI break. We should do this for 24.11
>

It may not be an ABI break, since structure moved to ethdev_driver.h
with recent changes, it is not exposed to user directly anymore.


eth_dev_data is device data and it is not directly involved in the
datapath, although I can see 'rx_mbuf_alloc_failed' stats is updated in
datapath, and some drivers access 'dev_private' in datapath, most of
other fields are configuration related.

So, although I expect changes in eth_dev_data doesn't impact the
performance it needs to be tested and verified.

As this release looks mostly quite, perhaps it can be good time to try
this kind of change, what do you think to start reorg in this release?





[1]
struct rte_eth_dev_data {
 char                       name[64];             /*     0    64 */
 /* --- cacheline 1 boundary (64 bytes) --- */
 void * *                   rx_queues;            /*    64     8 */
 void * *                   tx_queues;            /*    72     8 */
 uint16_t                   nb_rx_queues;         /*    80     2 */
 uint16_t                   nb_tx_queues;         /*    82     2 */
 struct rte_eth_dev_sriov   sriov;                /*    84     6 */

 /* XXX 6 bytes hole, try to pack */

 void *                     dev_private;          /*    96     8 */
 struct rte_eth_link        dev_link __attribute__((__aligned__(8))); /*
  104     8 */

 /* XXX last struct has 2 bytes of padding */

 struct rte_eth_conf        dev_conf;             /*   112  2280 */

 /* XXX last struct has 4 bytes of padding */

 /* --- cacheline 37 boundary (2368 bytes) was 24 bytes ago --- */
 uint16_t                   mtu;                  /*  2392     2 */

 /* XXX 2 bytes hole, try to pack */

 uint32_t                   min_rx_buf_size;      /*  2396     4 */
 uint64_t                   rx_mbuf_alloc_failed; /*  2400     8 */
 struct rte_ether_addr *    mac_addrs;            /*  2408     8 */
 uint64_t                   mac_pool_sel[128];    /*  2416  1024 */
 /* --- cacheline 53 boundary (3392 bytes) was 48 bytes ago --- */
 struct rte_ether_addr *    hash_mac_addrs;       /*  3440     8 */
 uint16_t                   port_id;              /*  3448     2 */
 uint8_t                    promiscuous:1;        /*  3450: 0  1 */
 uint8_t                    scattered_rx:1;       /*  3450: 1  1 */
 uint8_t                    all_multicast:1;      /*  3450: 2  1 */
 uint8_t                    dev_started:1;        /*  3450: 3  1 */
 uint8_t                    lro:1;                /*  3450: 4  1 */
 uint8_t                    dev_configured:1;     /*  3450: 5  1 */
 uint8_t                    flow_configured:1;    /*  3450: 6  1 */

 /* XXX 1 bit hole, try to pack */

 uint8_t                    rx_queue_state[1024]; /*  3451  1024 */
 /* --- cacheline 69 boundary (4416 bytes) was 59 bytes ago --- */
 uint8_t                    tx_queue_state[1024]; /*  4475  1024 */

 /* XXX 1 byte hole, try to pack */

 /* --- cacheline 85 boundary (5440 bytes) was 60 bytes ago --- */
 uint32_t                   dev_flags;            /*  5500     4 */
 /* --- cacheline 86 boundary (5504 bytes) --- */
 int                        numa_node;            /*  5504     4 */

 /* XXX 4 bytes hole, try to pack */

 struct rte_vlan_filter_conf vlan_filter_conf;    /*  5512   512 */
 /* --- cacheline 94 boundary (6016 bytes) was 8 bytes ago --- */
 struct rte_eth_dev_owner   owner;                /*  6024    72 */
 /* --- cacheline 95 boundary (6080 bytes) was 16 bytes ago --- */
 uint16_t                   representor_id;       /*  6096     2 */
 uint16_t                   backer_port_id;       /*  6098     2 */

 /* XXX 4 bytes hole, try to pack */

 pthread_mutex_t            flow_ops_mutex;       /*  6104    40 */

 /* size: 6144, cachelines: 96, members: 32 */
 /* sum members: 6126, holes: 5, sum holes: 17 */
 /* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
 /* paddings: 2, sum paddings: 6 */
 /* forced alignments: 1 */
} __attribute__((__aligned__(64)));


^ permalink raw reply	[relevance 3%]

* RE: Issues around packet capture when secondary process is doing rx/tx
  2024-01-08  1:59  3% Issues around packet capture when secondary process is doing rx/tx Stephen Hemminger
  2024-01-08 10:41  0% ` Morten Brørup
  2024-01-08 15:13  0% ` Konstantin Ananyev
@ 2024-01-09  1:30  0% ` Honnappa Nagarahalli
  2 siblings, 0 replies; 200+ results
From: Honnappa Nagarahalli @ 2024-01-09  1:30 UTC (permalink / raw)
  To: Stephen Hemminger, dev
  Cc: arshdeep.kaur, Gowda, Sandesh, Reshma Pattan, nd, nd



> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Sunday, January 7, 2024 7:59 PM
> To: dev@dpdk.org
> Cc: arshdeep.kaur@intel.com; Gowda, Sandesh <sandesh.gowda@intel.com>;
> Reshma Pattan <reshma.pattan@intel.com>
> Subject: Issues around packet capture when secondary process is doing rx/tx
> 
> I have been looking at a problem reported by Sandesh where packet capture
> does not work if rx/tx burst is done in secondary process.
> 
> The root cause is that existing rx/tx callback model just doesn't work unless the
> process doing the rx/tx burst calls is the same one that registered the callbacks.
This is not specific to packet capture. This is a generic problem and we should look to solve it generically.

> 
> An example sequence would be:
> 	1. dumpcap (or pdump) as secondary tells pdump in primary to register
> callback
> 	2. secondary process calls rx_burst.
> 	3. rx_burst sees the callback but it has pointer pdump_rx which is not
> necessarily
> 	   at same location in primary and secondary process.
> 	4. indirect function call in secondary to bad location likely causes crash.
> 
> Some possible workarounds.
> 	1. Keep callback list per-process: messy, but won't crash. Capture won't
> work
>            without other changes. In this primary would register callback, but
> secondaries
>            would not use them in rx/tx burst.
> 
> 	2. Replace use of rx/tx callback in pdump with change to rte_ethdev to
> have
>            a capture flag. (i.e. don't use indirection).  Likely ABI problems.
>            Basically, ignore the rx/tx callback mechanism. This is my preferred
> 	   solution.
> 
> 	3. Some fix up mechanism (in EAL mp support?) to have each process
> fixup
>            its callback mechanism.
Yes, would prefer this. Let the application call additional APIs to register the call backs in secondary process.

> 
> 	4. Do something in pdump_init to register the callback in same process
> context
> 	   (probably need callbacks to be per-process). Would mean callback is
> always
>            on independent of capture being enabled.
> 
>         5. Get rid of indirect function call pointer, and replace it by index into
>            a static table of callback functions. Every process would have same code
>            (in this case pdump_rx) but at different address.  Requires all callbacks
>            to be statically defined at build time.
> 
> The existing rx/tx callback is not safe id rx/tx burst is called from different
> process than where callback is registered.
> 


^ permalink raw reply	[relevance 0%]

* rte_eth_dev_data reorganization needed
@ 2024-01-08 17:14  3% Stephen Hemminger
  2024-01-09 16:58  3% ` Ferruh Yigit
  0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2024-01-08 17:14 UTC (permalink / raw)
  To: dev

While looking at ethdev (for pdump issues) noticed.
The rte_eth_dev_data structure layout is unorganized.
Lots of holes, fields not arranged in logical groups
and usage could be localized for better cache access.

Obviously, any reorg is ABI break. We should do this for 24.11

^ permalink raw reply	[relevance 3%]

* Re: Issues around packet capture when secondary process is doing rx/tx
  2024-01-08 15:13  0% ` Konstantin Ananyev
@ 2024-01-08 17:02  0%   ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2024-01-08 17:02 UTC (permalink / raw)
  To: Konstantin Ananyev; +Cc: dev, arshdeep.kaur, Gowda, Sandesh, Reshma Pattan

On Mon, 8 Jan 2024 15:13:25 +0000
Konstantin Ananyev <konstantin.ananyev@huawei.com> wrote:

> > 
> > 	2. Replace use of rx/tx callback in pdump with change to rte_ethdev to have
> >            a capture flag. (i.e. don't use indirection).  Likely ABI problems.
> >            Basically, ignore the rx/tx callback mechanism. This is my preferred
> > 	   solution.  
> 
> It is not only the capture flag, it is also what to do with the captured packets
> (copy? If yes, then where to? examine? drop?, do something else?).
> It is probably not the best choice to add all these things into ethdev API.

The part that pdump does is trivial, it just copies and puts in ring.
This will work from any process.

^ permalink raw reply	[relevance 0%]

* RE: Issues around packet capture when secondary process is doing rx/tx
  2024-01-08  1:59  3% Issues around packet capture when secondary process is doing rx/tx Stephen Hemminger
  2024-01-08 10:41  0% ` Morten Brørup
@ 2024-01-08 15:13  0% ` Konstantin Ananyev
  2024-01-08 17:02  0%   ` Stephen Hemminger
  2024-01-09  1:30  0% ` Honnappa Nagarahalli
  2 siblings, 1 reply; 200+ results
From: Konstantin Ananyev @ 2024-01-08 15:13 UTC (permalink / raw)
  To: Stephen Hemminger, dev; +Cc: arshdeep.kaur, Gowda, Sandesh, Reshma Pattan



> I have been looking at a problem reported by Sandesh
> where packet capture does not work if rx/tx burst is done in secondary process.
> 
> The root cause is that existing rx/tx callback model just doesn't work
> unless the process doing the rx/tx burst calls is the same one that
> registered the callbacks.
> 
> An example sequence would be:
> 	1. dumpcap (or pdump) as secondary tells pdump in primary to register callback
> 	2. secondary process calls rx_burst.
> 	3. rx_burst sees the callback but it has pointer pdump_rx which is not necessarily
> 	   at same location in primary and secondary process.
> 	4. indirect function call in secondary to bad location likely causes crash.

As I remember, RX/TX callbacks were never intended to work over multiple processes.
Right now RX/TX callbacks are private for the process, different process simply should not
see/execute them.
I.E. it callbacks list is part of 'struct rte_eth_dev' itself, not the rte_eth_dev.data that is shared
between processes.
It should be normal, wehn for the same port/queue you will end-up with different list of callbacks
for different processes.  
So, unless I am missing something, I don't see how we can end-up with 3) and 4) from above:
From my understanding secondary process will never see/call primary's callbacks.

About pdump itself, it was a while when I looked at it last time, but as I remember to start it to work,
server process has to call rte_pdump_init() which in terns register PDUMP_MP handler.
I suppose for the secondary process to act as a 'pdump server' it needs to call rte_pdump_init() itself,
though I am not sure such option is supported right now. 
 
> 
> Some possible workarounds.
> 	1. Keep callback list per-process: messy, but won't crash. Capture won't work
>            without other changes. In this primary would register callback, but secondaries
>            would not use them in rx/tx burst.
> 
> 	2. Replace use of rx/tx callback in pdump with change to rte_ethdev to have
>            a capture flag. (i.e. don't use indirection).  Likely ABI problems.
>            Basically, ignore the rx/tx callback mechanism. This is my preferred
> 	   solution.

It is not only the capture flag, it is also what to do with the captured packets
(copy? If yes, then where to? examine? drop?, do something else?).
It is probably not the best choice to add all these things into ethdev API.

> 	3. Some fix up mechanism (in EAL mp support?) to have each process fixup
>            its callback mechanism.
 
Probably the easiest way to fix that - pass to rte_pdump_enable() extra information
that  would allow it to distinguish on what exact process (local, remote)
we want to enable pdump functionality. Then it could act accordingly.

> 
> 	4. Do something in pdump_init to register the callback in same process context
> 	   (probably need callbacks to be per-process). Would mean callback is always
>            on independent of capture being enabled.
> 
>         5. Get rid of indirect function call pointer, and replace it by index into
>            a static table of callback functions. Every process would have same code
>            (in this case pdump_rx) but at different address.  Requires all callbacks
>            to be statically defined at build time.

Doesn't look like a good approach - it will break many things. 
 
> The existing rx/tx callback is not safe id rx/tx burst is called from different process
> than where callback is registered.
 


^ permalink raw reply	[relevance 0%]

* RE: Issues around packet capture when secondary process is doing rx/tx
  2024-01-08  1:59  3% Issues around packet capture when secondary process is doing rx/tx Stephen Hemminger
@ 2024-01-08 10:41  0% ` Morten Brørup
  2024-01-08 15:13  0% ` Konstantin Ananyev
  2024-01-09  1:30  0% ` Honnappa Nagarahalli
  2 siblings, 0 replies; 200+ results
From: Morten Brørup @ 2024-01-08 10:41 UTC (permalink / raw)
  To: Stephen Hemminger, dev; +Cc: arshdeep.kaur, Gowda, Sandesh, Reshma Pattan

> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Monday, 8 January 2024 02.59
> 
> I have been looking at a problem reported by Sandesh
> where packet capture does not work if rx/tx burst is done in secondary
> process.
> 
> The root cause is that existing rx/tx callback model just doesn't work
> unless the process doing the rx/tx burst calls is the same one that
> registered the callbacks.

So, callbacks don't work across processes, because code might differ across processes.

If process A is running, and RX'ing and TX'ing, and process B wants to install its own callbacks (e.g. packet capture) on RX and RX, we basically want process A to execute code residing in process B, which is impossible.

An alternative could be to pass the packets through a ring in shared memory. However, this method would add the ring processing latency of process B to the RX/TX latency of process A.

I think we can conclude that callbacks are one of the things that don't work with secondary processes.

With this decided, we can then consider how to best add packet capture. The concept of passing "data" (instead of calling functions) across processes obviously applies to this use case.

> 
> An example sequence would be:
> 	1. dumpcap (or pdump) as secondary tells pdump in primary to
> register callback
> 	2. secondary process calls rx_burst.
> 	3. rx_burst sees the callback but it has pointer pdump_rx which
> is not necessarily
> 	   at same location in primary and secondary process.
> 	4. indirect function call in secondary to bad location likely
> causes crash.
> 
> Some possible workarounds.
> 	1. Keep callback list per-process: messy, but won't crash.
> Capture won't work
>            without other changes. In this primary would register
> callback, but secondaries
>            would not use them in rx/tx burst.
> 
> 	2. Replace use of rx/tx callback in pdump with change to
> rte_ethdev to have
>            a capture flag. (i.e. don't use indirection).  Likely ABI
> problems.
>            Basically, ignore the rx/tx callback mechanism. This is my
> preferred
> 	   solution.
> 
> 	3. Some fix up mechanism (in EAL mp support?) to have each
> process fixup
>            its callback mechanism.
> 
> 	4. Do something in pdump_init to register the callback in same
> process context
> 	   (probably need callbacks to be per-process). Would mean
> callback is always
>            on independent of capture being enabled.
> 
>         5. Get rid of indirect function call pointer, and replace it by
> index into
>            a static table of callback functions. Every process would
> have same code
>            (in this case pdump_rx) but at different address.  Requires
> all callbacks
>            to be statically defined at build time.
> 
> The existing rx/tx callback is not safe id rx/tx burst is called from
> different process
> than where callback is registered.
> 


^ permalink raw reply	[relevance 0%]

* Issues around packet capture when secondary process is doing rx/tx
@ 2024-01-08  1:59  3% Stephen Hemminger
  2024-01-08 10:41  0% ` Morten Brørup
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Stephen Hemminger @ 2024-01-08  1:59 UTC (permalink / raw)
  To: dev; +Cc: arshdeep.kaur, Gowda, Sandesh, Reshma Pattan

I have been looking at a problem reported by Sandesh 
where packet capture does not work if rx/tx burst is done in secondary process.

The root cause is that existing rx/tx callback model just doesn't work
unless the process doing the rx/tx burst calls is the same one that
registered the callbacks.

An example sequence would be:
	1. dumpcap (or pdump) as secondary tells pdump in primary to register callback
	2. secondary process calls rx_burst.
	3. rx_burst sees the callback but it has pointer pdump_rx which is not necessarily
	   at same location in primary and secondary process. 
	4. indirect function call in secondary to bad location likely causes crash.

Some possible workarounds.
	1. Keep callback list per-process: messy, but won't crash. Capture won't work
           without other changes. In this primary would register callback, but secondaries
           would not use them in rx/tx burst.

	2. Replace use of rx/tx callback in pdump with change to rte_ethdev to have
           a capture flag. (i.e. don't use indirection).  Likely ABI problems.
           Basically, ignore the rx/tx callback mechanism. This is my preferred
	   solution.

	3. Some fix up mechanism (in EAL mp support?) to have each process fixup
           its callback mechanism.

	4. Do something in pdump_init to register the callback in same process context
	   (probably need callbacks to be per-process). Would mean callback is always
           on independent of capture being enabled.

        5. Get rid of indirect function call pointer, and replace it by index into
           a static table of callback functions. Every process would have same code
           (in this case pdump_rx) but at different address.  Requires all callbacks
           to be statically defined at build time.

The existing rx/tx callback is not safe id rx/tx burst is called from different process
than where callback is registered.



^ permalink raw reply	[relevance 3%]

* RE: [RFC] ethdev: fast path async flow API
  2023-12-28 13:53  3%   ` Dariusz Sosnowski
@ 2023-12-28 14:10  0%     ` Ivan Malov
  0 siblings, 0 replies; 200+ results
From: Ivan Malov @ 2023-12-28 14:10 UTC (permalink / raw)
  To: Dariusz Sosnowski
  Cc: Stephen Hemminger, NBU-Contact-Thomas Monjalon (EXTERNAL),
	Ferruh Yigit, Andrew Rybchenko, Ori Kam, dev

Hi Dariusz,

I appreciate the proposal. You say that a reference PMD implementation
will be made available for 24.03 release. What about the applications?
Is this supposed to go to upstream code of some applications?

Thank you.

On Thu, 28 Dec 2023, Dariusz Sosnowski wrote:

> Hi Stephen,
>
>>> +/**
>>> + * @internal
>>> + *
>>> + * Fast path async flow functions and related data are held in a flat array,
>> one entry per ethdev.
>>> + * It is assumed that each entry is read-only and cache aligned.
>>> + */
>>> +struct rte_flow_fp_ops {
>>> +     void *ctx;
>>> +     rte_flow_async_create_t async_create;
>>> +     rte_flow_async_create_by_index_t async_create_by_index;
>>> +     rte_flow_async_actions_update_t async_actions_update;
>>> +     rte_flow_async_destroy_t async_destroy;
>>> +     rte_flow_push_t push;
>>> +     rte_flow_pull_t pull;
>>> +     rte_flow_async_action_handle_create_t async_action_handle_create;
>>> +     rte_flow_async_action_handle_destroy_t async_action_handle_destroy;
>>> +     rte_flow_async_action_handle_update_t async_action_handle_update;
>>> +     rte_flow_async_action_handle_query_t async_action_handle_query;
>>> +     rte_flow_async_action_handle_query_update_t
>> async_action_handle_query_update;
>>> +     rte_flow_async_action_list_handle_create_t
>> async_action_list_handle_create;
>>> +     rte_flow_async_action_list_handle_destroy_t
>> async_action_list_handle_destroy;
>>> +     rte_flow_async_action_list_handle_query_update_t
>> async_action_list_handle_query_update;
>>> +} __rte_cache_aligned;
>>
>> If you go ahead with this then all usage should be const pointer.
>> Still think it is bad idea and creates even more technical debt.
> Could you please elaborate a bit more on why do you think it is a bad idea and why it creates technical debt?
>
>>> **Future considerations**
>>>
>>> A case can be made about converting some of the existing stable API
>>> functions to fast path versions in future LTS releases.
>>> I don't have any hard data on how such changes would affect
>>> performance of these APIs, but I assume that the improvement would be noticeable.
>>
>> The problem is that inline functions create future ABI problems.
> Agreed, this is why such a change can only be introduced when a new major ABI version is released.
> However, even though inlining could reduce function call overhead, I'm not sure if such a change is needed for synchronous flow API.
> I mentioned it here as a thing to consider.
>
>> Usually, there are other ways to get the same performance benefit.
>> Often batching updates to hardware will do the trick.
> This is true, but we still have some library-level overhead.
> To elaborate more, the current state of flow API is as follows:
> - With sync flow API:
>  - Applications cannot batch flow operations.
> - With async flow APIs:
>  - Applications can enqueue multiple flow operations and PMDs can issue batches to HW.
>  - But there is still one function call per enqueued flow operation.
>    The overall API overhead in datapath may be nonnegligible if we consider that applications may enqueue a flow rule creation operation for every packet received in SW.
> This proposal specifically aims at reducing API overhead for async flow API in a case mentioned above.
>
> As a side note, we plan to push changes to mlx5 PMD in 24.03 which will reduce PMD overhead in such scenarios.
> This proposal's goal is to reduce overhead of async flow API at library level.
>
> Best regards,
> Dariusz Sosnowski
>

^ permalink raw reply	[relevance 0%]

* RE: [RFC] ethdev: fast path async flow API
  @ 2023-12-28 13:53  3%   ` Dariusz Sosnowski
  2023-12-28 14:10  0%     ` Ivan Malov
  0 siblings, 1 reply; 200+ results
From: Dariusz Sosnowski @ 2023-12-28 13:53 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: NBU-Contact-Thomas Monjalon (EXTERNAL),
	Ferruh Yigit, Andrew Rybchenko, Ori Kam, dev

Hi Stephen,

> > +/**
> > + * @internal
> > + *
> > + * Fast path async flow functions and related data are held in a flat array,
> one entry per ethdev.
> > + * It is assumed that each entry is read-only and cache aligned.
> > + */
> > +struct rte_flow_fp_ops {
> > +     void *ctx;
> > +     rte_flow_async_create_t async_create;
> > +     rte_flow_async_create_by_index_t async_create_by_index;
> > +     rte_flow_async_actions_update_t async_actions_update;
> > +     rte_flow_async_destroy_t async_destroy;
> > +     rte_flow_push_t push;
> > +     rte_flow_pull_t pull;
> > +     rte_flow_async_action_handle_create_t async_action_handle_create;
> > +     rte_flow_async_action_handle_destroy_t async_action_handle_destroy;
> > +     rte_flow_async_action_handle_update_t async_action_handle_update;
> > +     rte_flow_async_action_handle_query_t async_action_handle_query;
> > +     rte_flow_async_action_handle_query_update_t
> async_action_handle_query_update;
> > +     rte_flow_async_action_list_handle_create_t
> async_action_list_handle_create;
> > +     rte_flow_async_action_list_handle_destroy_t
> async_action_list_handle_destroy;
> > +     rte_flow_async_action_list_handle_query_update_t
> async_action_list_handle_query_update;
> > +} __rte_cache_aligned;
> 
> If you go ahead with this then all usage should be const pointer.
> Still think it is bad idea and creates even more technical debt.
Could you please elaborate a bit more on why do you think it is a bad idea and why it creates technical debt? 

> > **Future considerations**
> >
> > A case can be made about converting some of the existing stable API 
> > functions to fast path versions in future LTS releases.
> > I don't have any hard data on how such changes would affect 
> > performance of these APIs, but I assume that the improvement would be noticeable.
> 
> The problem is that inline functions create future ABI problems.
Agreed, this is why such a change can only be introduced when a new major ABI version is released.
However, even though inlining could reduce function call overhead, I'm not sure if such a change is needed for synchronous flow API.
I mentioned it here as a thing to consider.

> Usually, there are other ways to get the same performance benefit.
> Often batching updates to hardware will do the trick.
This is true, but we still have some library-level overhead.
To elaborate more, the current state of flow API is as follows:
- With sync flow API:
  - Applications cannot batch flow operations.
- With async flow APIs:
  - Applications can enqueue multiple flow operations and PMDs can issue batches to HW.
  - But there is still one function call per enqueued flow operation.
    The overall API overhead in datapath may be nonnegligible if we consider that applications may enqueue a flow rule creation operation for every packet received in SW.
This proposal specifically aims at reducing API overhead for async flow API in a case mentioned above.

As a side note, we plan to push changes to mlx5 PMD in 24.03 which will reduce PMD overhead in such scenarios.
This proposal's goal is to reduce overhead of async flow API at library level.

Best regards,
Dariusz Sosnowski

^ permalink raw reply	[relevance 3%]

* Re: [RFC] ethdev: fast path async flow API
  @ 2023-12-27 17:39  3% ` Stephen Hemminger
      2 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2023-12-27 17:39 UTC (permalink / raw)
  To: Dariusz Sosnowski
  Cc: Thomas Monjalon, Ferruh Yigit, Andrew Rybchenko, Ori Kam, dev

On Wed, 27 Dec 2023 12:57:09 +0200
Dariusz Sosnowski <dsosnowski@nvidia.com> wrote:

> **Future considerations**
> 
> A case can be made about converting some of the existing
> stable API functions to fast path versions in future LTS releases.
> I don't have any hard data on how such changes would affect performance of
> these APIs, but I assume that the improvement would be noticeable.

The problem is that inline functions create future ABI problems.
Usually, there are other ways to get the same performance benefit.
Often batching updates to hardware will do the trick.

^ permalink raw reply	[relevance 3%]

* [RFC] net/tap: remove kernel side RSS via BPF
@ 2023-12-15 16:31  1% Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2023-12-15 16:31 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The support of BPF in TAP device was problematic since the
API to BPF in kernel is not stable and keeps changing.

Since the RTE_FLOW_ACTION_TYPE_RSS is the only part using this
remove support for kernel side flow remapping.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 doc/guides/nics/tap.rst               |   74 --
 drivers/net/tap/bpf/Makefile          |   19 -
 drivers/net/tap/bpf/bpf_api.h         |  276 ----
 drivers/net/tap/bpf/bpf_elf.h         |   53 -
 drivers/net/tap/bpf/bpf_extract.py    |   86 --
 drivers/net/tap/bpf/tap_bpf_program.c |  255 ----
 drivers/net/tap/meson.build           |    5 -
 drivers/net/tap/rte_eth_tap.h         |    5 +-
 drivers/net/tap/tap_bpf.h             |  121 --
 drivers/net/tap/tap_bpf_api.c         |  190 ---
 drivers/net/tap/tap_bpf_insns.h       | 1743 -------------------------
 drivers/net/tap/tap_flow.c            |  496 +------
 drivers/net/tap/tap_flow.h            |   12 -
 drivers/net/tap/tap_tcmsgs.h          |    3 -
 14 files changed, 4 insertions(+), 3334 deletions(-)
 delete mode 100644 drivers/net/tap/bpf/Makefile
 delete mode 100644 drivers/net/tap/bpf/bpf_api.h
 delete mode 100644 drivers/net/tap/bpf/bpf_elf.h
 delete mode 100644 drivers/net/tap/bpf/bpf_extract.py
 delete mode 100644 drivers/net/tap/bpf/tap_bpf_program.c
 delete mode 100644 drivers/net/tap/tap_bpf.h
 delete mode 100644 drivers/net/tap/tap_bpf_api.c
 delete mode 100644 drivers/net/tap/tap_bpf_insns.h

diff --git a/doc/guides/nics/tap.rst b/doc/guides/nics/tap.rst
index d4f45c02a1e5..5779f5d08e31 100644
--- a/doc/guides/nics/tap.rst
+++ b/doc/guides/nics/tap.rst
@@ -123,7 +123,6 @@ Supported actions:
 - DROP
 - QUEUE
 - PASSTHRU
-- RSS (requires kernel 4.9)
 
 It is generally not possible to provide a "last" item. However, if the "last"
 item, once masked, is identical to the masked spec, then it is supported.
@@ -153,10 +152,6 @@ Drop UDP packets in vlan 3::
    testpmd> flow create 0 priority 3 ingress pattern eth / vlan vid is 3 / \
             ipv4 proto is 17 / end actions drop / end
 
-Distribute IPv4 TCP packets using RSS to a given MAC address over queues 0-3::
-
-   testpmd> flow create 0 priority 4 ingress pattern eth dst is 0a:0b:0c:0d:0e:0f \
-            / ipv4 / tcp / end actions rss queues 0 1 2 3 end / end
 
 Multi-process sharing
 ---------------------
@@ -227,80 +222,11 @@ size of the packets after you stop the traffic. Use pktgen ``help``
 command to see a list of all commands. You can also use the ``-f`` option to
 load commands at startup in command line or Lua script in pktgen.
 
-RSS specifics
--------------
-Packet distribution in TAP is done by the kernel which has a default
-distribution. This feature is adding RSS distribution based on eBPF code.
-The default eBPF code calculates RSS hash based on Toeplitz algorithm for
-a fixed RSS key. It is calculated on fixed packet offsets. For IPv4 and IPv6 it
-is calculated over src/dst addresses (8 or 32 bytes for IPv4 or IPv6
-respectively) and src/dst TCP/UDP ports (4 bytes).
-
-The RSS algorithm is written in file ``tap_bpf_program.c`` which
-does not take part in TAP PMD compilation. Instead this file is compiled
-in advance to eBPF object file. The eBPF object file is then parsed and
-translated into eBPF byte code in the format of C arrays of eBPF
-instructions. The C array of eBPF instructions is part of TAP PMD tree and
-is taking part in TAP PMD compilation. At run time the C arrays are uploaded to
-the kernel via BPF system calls and the RSS hash is calculated by the
-kernel.
-
-It is possible to support different RSS hash algorithms by updating file
-``tap_bpf_program.c``  In order to add a new RSS hash algorithm follow these
-steps:
-
-#. Write the new RSS implementation in file ``tap_bpf_program.c``
-
-   BPF programs which are uploaded to the kernel correspond to
-   C functions under different ELF sections.
-
-#. Install ``LLVM`` library and ``clang`` compiler versions 3.7 and above
-
-#. Use make to compile  `tap_bpf_program.c`` via ``LLVM`` into an object file
-   and extract the resulting instructions into ``tap_bpf_insn.h``::
-
-    cd bpf; make
-
-#. Recompile the TAP PMD.
-
-The C arrays are uploaded to the kernel using BPF system calls.
-
-``tc`` (traffic control) is a well known user space utility program used to
-configure the Linux kernel packet scheduler. It is usually packaged as
-part of the ``iproute2`` package.
-Since commit 11c39b5e9 ("tc: add eBPF support to f_bpf") ``tc`` can be used
-to uploads eBPF code to the kernel and can be patched in order to print the
-C arrays of eBPF instructions just before calling the BPF system call.
-Please refer to ``iproute2`` package file ``lib/bpf.c`` function
-``bpf_prog_load()``.
-
-An example utility for eBPF instruction generation in the format of C arrays will
-be added in next releases
-
-TAP reports on supported RSS functions as part of dev_infos_get callback:
-``RTE_ETH_RSS_IP``, ``RTE_ETH_RSS_UDP`` and ``RTE_ETH_RSS_TCP``.
-**Known limitation:** TAP supports all of the above hash functions together
-and not in partial combinations.
 
 Systems supporting flow API
 ---------------------------
 
 - "tc flower" classifier requires linux kernel above 4.2
-- eBPF/RSS requires linux kernel above 4.9
-
-+--------------------+-----------------------+
-| RH7.3              | No flow rule support  |
-+--------------------+-----------------------+
-| RH7.4              | No RSS action support |
-+--------------------+-----------------------+
-| RH7.5              | No RSS action support |
-+--------------------+-----------------------+
-| SLES 15,           | No limitation         |
-| kernel 4.12        |                       |
-+--------------------+-----------------------+
-| Azure Ubuntu 16.04,| No limitation         |
-| kernel 4.13        |                       |
-+--------------------+-----------------------+
 
 Limitations
 -----------
diff --git a/drivers/net/tap/bpf/Makefile b/drivers/net/tap/bpf/Makefile
deleted file mode 100644
index 9efeeb1bc704..000000000000
--- a/drivers/net/tap/bpf/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# This file is not built as part of normal DPDK build.
-# It is used to generate the eBPF code for TAP RSS.
-
-CLANG=clang
-CLANG_OPTS=-O2
-TARGET=../tap_bpf_insns.h
-
-all: $(TARGET)
-
-clean:
-	rm tap_bpf_program.o $(TARGET)
-
-tap_bpf_program.o: tap_bpf_program.c
-	$(CLANG) $(CLANG_OPTS) -emit-llvm -c $< -o - | \
-	llc -march=bpf -filetype=obj -o $@
-
-$(TARGET): tap_bpf_program.o
-	python3 bpf_extract.py -stap_bpf_program.c -o $@ $<
diff --git a/drivers/net/tap/bpf/bpf_api.h b/drivers/net/tap/bpf/bpf_api.h
deleted file mode 100644
index 2638a8a4ac9a..000000000000
--- a/drivers/net/tap/bpf/bpf_api.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-
-#ifndef __BPF_API__
-#define __BPF_API__
-
-/* Note:
- *
- * This file can be included into eBPF kernel programs. It contains
- * a couple of useful helper functions, map/section ABI (bpf_elf.h),
- * misc macros and some eBPF specific LLVM built-ins.
- */
-
-#include <stdint.h>
-
-#include <linux/pkt_cls.h>
-#include <linux/bpf.h>
-#include <linux/filter.h>
-
-#include <asm/byteorder.h>
-
-#include "bpf_elf.h"
-
-/** libbpf pin type. */
-enum libbpf_pin_type {
-	LIBBPF_PIN_NONE,
-	/* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */
-	LIBBPF_PIN_BY_NAME,
-};
-
-/** Type helper macros. */
-
-#define __uint(name, val) int (*name)[val]
-#define __type(name, val) typeof(val) *name
-#define __array(name, val) typeof(val) *name[]
-
-/** Misc macros. */
-
-#ifndef __stringify
-# define __stringify(X)		#X
-#endif
-
-#ifndef __maybe_unused
-# define __maybe_unused		__attribute__((__unused__))
-#endif
-
-#ifndef offsetof
-# define offsetof(TYPE, MEMBER)	__builtin_offsetof(TYPE, MEMBER)
-#endif
-
-#ifndef likely
-# define likely(X)		__builtin_expect(!!(X), 1)
-#endif
-
-#ifndef unlikely
-# define unlikely(X)		__builtin_expect(!!(X), 0)
-#endif
-
-#ifndef htons
-# define htons(X)		__constant_htons((X))
-#endif
-
-#ifndef ntohs
-# define ntohs(X)		__constant_ntohs((X))
-#endif
-
-#ifndef htonl
-# define htonl(X)		__constant_htonl((X))
-#endif
-
-#ifndef ntohl
-# define ntohl(X)		__constant_ntohl((X))
-#endif
-
-#ifndef __inline__
-# define __inline__		__attribute__((always_inline))
-#endif
-
-/** Section helper macros. */
-
-#ifndef __section
-# define __section(NAME)						\
-	__attribute__((section(NAME), used))
-#endif
-
-#ifndef __section_tail
-# define __section_tail(ID, KEY)					\
-	__section(__stringify(ID) "/" __stringify(KEY))
-#endif
-
-#ifndef __section_xdp_entry
-# define __section_xdp_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_cls_entry
-# define __section_cls_entry						\
-	__section(ELF_SECTION_CLASSIFIER)
-#endif
-
-#ifndef __section_act_entry
-# define __section_act_entry						\
-	__section(ELF_SECTION_ACTION)
-#endif
-
-#ifndef __section_lwt_entry
-# define __section_lwt_entry						\
-	__section(ELF_SECTION_PROG)
-#endif
-
-#ifndef __section_license
-# define __section_license						\
-	__section(ELF_SECTION_LICENSE)
-#endif
-
-#ifndef __section_maps
-# define __section_maps							\
-	__section(ELF_SECTION_MAPS)
-#endif
-
-/** Declaration helper macros. */
-
-#ifndef BPF_LICENSE
-# define BPF_LICENSE(NAME)						\
-	char ____license[] __section_license = NAME
-#endif
-
-/** Classifier helper */
-
-#ifndef BPF_H_DEFAULT
-# define BPF_H_DEFAULT	-1
-#endif
-
-/** BPF helper functions for tc. Individual flags are in linux/bpf.h */
-
-#ifndef __BPF_FUNC
-# define __BPF_FUNC(NAME, ...)						\
-	(* NAME)(__VA_ARGS__) __maybe_unused
-#endif
-
-#ifndef BPF_FUNC
-# define BPF_FUNC(NAME, ...)						\
-	__BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME
-#endif
-
-/* Map access/manipulation */
-static void *BPF_FUNC(map_lookup_elem, void *map, const void *key);
-static int BPF_FUNC(map_update_elem, void *map, const void *key,
-		    const void *value, uint32_t flags);
-static int BPF_FUNC(map_delete_elem, void *map, const void *key);
-
-/* Time access */
-static uint64_t BPF_FUNC(ktime_get_ns);
-
-/* Debugging */
-
-/* FIXME: __attribute__ ((format(printf, 1, 3))) not possible unless
- * llvm bug https://llvm.org/bugs/show_bug.cgi?id=26243 gets resolved.
- * It would require ____fmt to be made const, which generates a reloc
- * entry (non-map).
- */
-static void BPF_FUNC(trace_printk, const char *fmt, int fmt_size, ...);
-
-#ifndef printt
-# define printt(fmt, ...)						\
-	({								\
-		char ____fmt[] = fmt;					\
-		trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__);	\
-	})
-#endif
-
-/* Random numbers */
-static uint32_t BPF_FUNC(get_prandom_u32);
-
-/* Tail calls */
-static void BPF_FUNC(tail_call, struct __sk_buff *skb, void *map,
-		     uint32_t index);
-
-/* System helpers */
-static uint32_t BPF_FUNC(get_smp_processor_id);
-static uint32_t BPF_FUNC(get_numa_node_id);
-
-/* Packet misc meta data */
-static uint32_t BPF_FUNC(get_cgroup_classid, struct __sk_buff *skb);
-static int BPF_FUNC(skb_under_cgroup, void *map, uint32_t index);
-
-static uint32_t BPF_FUNC(get_route_realm, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(get_hash_recalc, struct __sk_buff *skb);
-static uint32_t BPF_FUNC(set_hash_invalid, struct __sk_buff *skb);
-
-/* Packet redirection */
-static int BPF_FUNC(redirect, int ifindex, uint32_t flags);
-static int BPF_FUNC(clone_redirect, struct __sk_buff *skb, int ifindex,
-		    uint32_t flags);
-
-/* Packet manipulation */
-static int BPF_FUNC(skb_load_bytes, struct __sk_buff *skb, uint32_t off,
-		    void *to, uint32_t len);
-static int BPF_FUNC(skb_store_bytes, struct __sk_buff *skb, uint32_t off,
-		    const void *from, uint32_t len, uint32_t flags);
-
-static int BPF_FUNC(l3_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(l4_csum_replace, struct __sk_buff *skb, uint32_t off,
-		    uint32_t from, uint32_t to, uint32_t flags);
-static int BPF_FUNC(csum_diff, const void *from, uint32_t from_size,
-		    const void *to, uint32_t to_size, uint32_t seed);
-static int BPF_FUNC(csum_update, struct __sk_buff *skb, uint32_t wsum);
-
-static int BPF_FUNC(skb_change_type, struct __sk_buff *skb, uint32_t type);
-static int BPF_FUNC(skb_change_proto, struct __sk_buff *skb, uint32_t proto,
-		    uint32_t flags);
-static int BPF_FUNC(skb_change_tail, struct __sk_buff *skb, uint32_t nlen,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_pull_data, struct __sk_buff *skb, uint32_t len);
-
-/* Event notification */
-static int __BPF_FUNC(skb_event_output, struct __sk_buff *skb, void *map,
-		      uint64_t index, const void *data, uint32_t size) =
-		      (void *) BPF_FUNC_perf_event_output;
-
-/* Packet vlan encap/decap */
-static int BPF_FUNC(skb_vlan_push, struct __sk_buff *skb, uint16_t proto,
-		    uint16_t vlan_tci);
-static int BPF_FUNC(skb_vlan_pop, struct __sk_buff *skb);
-
-/* Packet tunnel encap/decap */
-static int BPF_FUNC(skb_get_tunnel_key, struct __sk_buff *skb,
-		    struct bpf_tunnel_key *to, uint32_t size, uint32_t flags);
-static int BPF_FUNC(skb_set_tunnel_key, struct __sk_buff *skb,
-		    const struct bpf_tunnel_key *from, uint32_t size,
-		    uint32_t flags);
-
-static int BPF_FUNC(skb_get_tunnel_opt, struct __sk_buff *skb,
-		    void *to, uint32_t size);
-static int BPF_FUNC(skb_set_tunnel_opt, struct __sk_buff *skb,
-		    const void *from, uint32_t size);
-
-/** LLVM built-ins, mem*() routines work for constant size */
-
-#ifndef lock_xadd
-# define lock_xadd(ptr, val)	((void) __sync_fetch_and_add(ptr, val))
-#endif
-
-#ifndef memset
-# define memset(s, c, n)	__builtin_memset((s), (c), (n))
-#endif
-
-#ifndef memcpy
-# define memcpy(d, s, n)	__builtin_memcpy((d), (s), (n))
-#endif
-
-#ifndef memmove
-# define memmove(d, s, n)	__builtin_memmove((d), (s), (n))
-#endif
-
-/* FIXME: __builtin_memcmp() is not yet fully usable unless llvm bug
- * https://llvm.org/bugs/show_bug.cgi?id=26218 gets resolved. Also
- * this one would generate a reloc entry (non-map), otherwise.
- */
-#if 0
-#ifndef memcmp
-# define memcmp(a, b, n)	__builtin_memcmp((a), (b), (n))
-#endif
-#endif
-
-unsigned long long load_byte(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.byte");
-
-unsigned long long load_half(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.half");
-
-unsigned long long load_word(void *skb, unsigned long long off)
-	asm ("llvm.bpf.load.word");
-
-#endif /* __BPF_API__ */
diff --git a/drivers/net/tap/bpf/bpf_elf.h b/drivers/net/tap/bpf/bpf_elf.h
deleted file mode 100644
index ea8a11c95c0f..000000000000
--- a/drivers/net/tap/bpf/bpf_elf.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
-#ifndef __BPF_ELF__
-#define __BPF_ELF__
-
-#include <asm/types.h>
-
-/* Note:
- *
- * Below ELF section names and bpf_elf_map structure definition
- * are not (!) kernel ABI. It's rather a "contract" between the
- * application and the BPF loader in tc. For compatibility, the
- * section names should stay as-is. Introduction of aliases, if
- * needed, are a possibility, though.
- */
-
-/* ELF section names, etc */
-#define ELF_SECTION_LICENSE	"license"
-#define ELF_SECTION_MAPS	"maps"
-#define ELF_SECTION_PROG	"prog"
-#define ELF_SECTION_CLASSIFIER	"classifier"
-#define ELF_SECTION_ACTION	"action"
-
-#define ELF_MAX_MAPS		64
-#define ELF_MAX_LICENSE_LEN	128
-
-/* Object pinning settings */
-#define PIN_NONE		0
-#define PIN_OBJECT_NS		1
-#define PIN_GLOBAL_NS		2
-
-/* ELF map definition */
-struct bpf_elf_map {
-	__u32 type;
-	__u32 size_key;
-	__u32 size_value;
-	__u32 max_elem;
-	__u32 flags;
-	__u32 id;
-	__u32 pinning;
-	__u32 inner_id;
-	__u32 inner_idx;
-};
-
-#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val)		\
-	struct ____btf_map_##name {				\
-		type_key key;					\
-		type_val value;					\
-	};							\
-	struct ____btf_map_##name				\
-	    __attribute__ ((section(".maps." #name), used))	\
-	    ____btf_map_##name = { }
-
-#endif /* __BPF_ELF__ */
diff --git a/drivers/net/tap/bpf/bpf_extract.py b/drivers/net/tap/bpf/bpf_extract.py
deleted file mode 100644
index b630c42b809f..000000000000
--- a/drivers/net/tap/bpf/bpf_extract.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright (c) 2023 Stephen Hemminger <stephen@networkplumber.org>
-
-import argparse
-import sys
-import struct
-from tempfile import TemporaryFile
-from elftools.elf.elffile import ELFFile
-
-
-def load_sections(elffile):
-    """Get sections of interest from ELF"""
-    result = []
-    parts = [("cls_q", "cls_q_insns"), ("l3_l4", "l3_l4_hash_insns")]
-    for name, tag in parts:
-        section = elffile.get_section_by_name(name)
-        if section:
-            insns = struct.iter_unpack('<BBhL', section.data())
-            result.append([tag, insns])
-    return result
-
-
-def dump_section(name, insns, out):
-    """Dump the array of BPF instructions"""
-    print(f'\nstatic struct bpf_insn {name}[] = {{', file=out)
-    for bpf in insns:
-        code = bpf[0]
-        src = bpf[1] >> 4
-        dst = bpf[1] & 0xf
-        off = bpf[2]
-        imm = bpf[3]
-        print(f'\t{{{code:#04x}, {dst:4d}, {src:4d}, {off:8d}, {imm:#010x}}},',
-              file=out)
-    print('};', file=out)
-
-
-def parse_args():
-    """Parse command line arguments"""
-    parser = argparse.ArgumentParser()
-    parser.add_argument('-s',
-                        '--source',
-                        type=str,
-                        help="original source file")
-    parser.add_argument('-o', '--out', type=str, help="output C file path")
-    parser.add_argument("file",
-                        nargs='+',
-                        help="object file path or '-' for stdin")
-    return parser.parse_args()
-
-
-def open_input(path):
-    """Open the file or stdin"""
-    if path == "-":
-        temp = TemporaryFile()
-        temp.write(sys.stdin.buffer.read())
-        return temp
-    return open(path, 'rb')
-
-
-def write_header(out, source):
-    """Write file intro header"""
-    print("/* SPDX-License-Identifier: BSD-3-Clause", file=out)
-    if source:
-        print(f' * Auto-generated from {source}', file=out)
-    print(" * This not the original source file. Do NOT edit it.", file=out)
-    print(" */\n", file=out)
-    print("#include <tap_bpf.h>", file=out)
-
-
-def main():
-    '''program main function'''
-    args = parse_args()
-
-    with open(args.out, 'w',
-              encoding="utf-8") if args.out else sys.stdout as out:
-        write_header(out, args.source)
-        for path in args.file:
-            elffile = ELFFile(open_input(path))
-            sections = load_sections(elffile)
-            for name, insns in sections:
-                dump_section(name, insns, out)
-
-
-if __name__ == "__main__":
-    main()
diff --git a/drivers/net/tap/bpf/tap_bpf_program.c b/drivers/net/tap/bpf/tap_bpf_program.c
deleted file mode 100644
index f05aed021c30..000000000000
--- a/drivers/net/tap/bpf/tap_bpf_program.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
- * Copyright 2017 Mellanox Technologies, Ltd
- */
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <asm/types.h>
-#include <linux/in.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/if_tunnel.h>
-#include <linux/filter.h>
-
-#include "bpf_api.h"
-#include "bpf_elf.h"
-#include "../tap_rss.h"
-
-/** Create IPv4 address */
-#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \
-		(((b) & 0xff) << 16) | \
-		(((c) & 0xff) << 8)  | \
-		((d) & 0xff))
-
-#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \
-		((b) & 0xff))
-
-/*
- * The queue number is offset by a unique QUEUE_OFFSET, to distinguish
- * packets that have gone through this rule (skb->cb[1] != 0) from others.
- */
-#define QUEUE_OFFSET		0x7cafe800
-#define PIN_GLOBAL_NS		2
-
-#define KEY_IDX			0
-#define BPF_MAP_ID_KEY	1
-
-struct vlan_hdr {
-	__be16 proto;
-	__be16 tci;
-};
-
-struct bpf_elf_map __attribute__((section("maps"), used))
-map_keys = {
-	.type           =       BPF_MAP_TYPE_HASH,
-	.id             =       BPF_MAP_ID_KEY,
-	.size_key       =       sizeof(__u32),
-	.size_value     =       sizeof(struct rss_key),
-	.max_elem       =       256,
-	.pinning        =       PIN_GLOBAL_NS,
-};
-
-__section("cls_q") int
-match_q(struct __sk_buff *skb)
-{
-	__u32 queue = skb->cb[1];
-	/* queue is set by tap_flow_bpf_cls_q() before load */
-	volatile __u32 q = 0xdeadbeef;
-	__u32 match_queue = QUEUE_OFFSET + q;
-
-	/* printt("match_q$i() queue = %d\n", queue); */
-
-	if (queue != match_queue)
-		return TC_ACT_OK;
-
-	/* queue match */
-	skb->cb[1] = 0;
-	return TC_ACT_UNSPEC;
-}
-
-
-struct ipv4_l3_l4_tuple {
-	__u32    src_addr;
-	__u32    dst_addr;
-	__u16    dport;
-	__u16    sport;
-} __attribute__((packed));
-
-struct ipv6_l3_l4_tuple {
-	__u8        src_addr[16];
-	__u8        dst_addr[16];
-	__u16       dport;
-	__u16       sport;
-} __attribute__((packed));
-
-static const __u8 def_rss_key[TAP_RSS_HASH_KEY_SIZE] = {
-	0xd1, 0x81, 0xc6, 0x2c,
-	0xf7, 0xf4, 0xdb, 0x5b,
-	0x19, 0x83, 0xa2, 0xfc,
-	0x94, 0x3e, 0x1a, 0xdb,
-	0xd9, 0x38, 0x9e, 0x6b,
-	0xd1, 0x03, 0x9c, 0x2c,
-	0xa7, 0x44, 0x99, 0xad,
-	0x59, 0x3d, 0x56, 0xd9,
-	0xf3, 0x25, 0x3c, 0x06,
-	0x2a, 0xdc, 0x1f, 0xfc,
-};
-
-static __u32  __attribute__((always_inline))
-rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key,
-		__u8 input_len)
-{
-	__u32 i, j, hash = 0;
-#pragma unroll
-	for (j = 0; j < input_len; j++) {
-#pragma unroll
-		for (i = 0; i < 32; i++) {
-			if (input_tuple[j] & (1U << (31 - i))) {
-				hash ^= ((const __u32 *)def_rss_key)[j] << i |
-				(__u32)((uint64_t)
-				(((const __u32 *)def_rss_key)[j + 1])
-					>> (32 - i));
-			}
-		}
-	}
-	return hash;
-}
-
-static int __attribute__((always_inline))
-rss_l3_l4(struct __sk_buff *skb)
-{
-	void *data_end = (void *)(long)skb->data_end;
-	void *data = (void *)(long)skb->data;
-	__u16 proto = (__u16)skb->protocol;
-	__u32 key_idx = 0xdeadbeef;
-	__u32 hash;
-	struct rss_key *rsskey;
-	__u64 off = ETH_HLEN;
-	int j;
-	__u8 *key = 0;
-	__u32 len;
-	__u32 queue = 0;
-	bool mf = 0;
-	__u16 frag_off = 0;
-
-	rsskey = map_lookup_elem(&map_keys, &key_idx);
-	if (!rsskey) {
-		printt("hash(): rss key is not configured\n");
-		return TC_ACT_OK;
-	}
-	key = (__u8 *)rsskey->key;
-
-	/* Get correct proto for 802.1ad */
-	if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
-		if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
-		    sizeof(proto) > data_end)
-			return TC_ACT_OK;
-		proto = *(__u16 *)(data + ETH_ALEN * 2 +
-				   sizeof(struct vlan_hdr));
-		off += sizeof(struct vlan_hdr);
-	}
-
-	if (proto == htons(ETH_P_IP)) {
-		if (data + off + sizeof(struct iphdr) + sizeof(__u32)
-			> data_end)
-			return TC_ACT_OK;
-
-		__u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr);
-		__u8 *frag_off_addr = data + off + offsetof(struct iphdr, frag_off);
-		__u8 *prot_addr = data + off + offsetof(struct iphdr, protocol);
-		__u8 *src_dst_port = data + off + sizeof(struct iphdr);
-		struct ipv4_l3_l4_tuple v4_tuple = {
-			.src_addr = IPv4(*(src_dst_addr + 0),
-					*(src_dst_addr + 1),
-					*(src_dst_addr + 2),
-					*(src_dst_addr + 3)),
-			.dst_addr = IPv4(*(src_dst_addr + 4),
-					*(src_dst_addr + 5),
-					*(src_dst_addr + 6),
-					*(src_dst_addr + 7)),
-			.sport = 0,
-			.dport = 0,
-		};
-		/** Fetch the L4-payer port numbers only in-case of TCP/UDP
-		 ** and also if the packet is not fragmented. Since fragmented
-		 ** chunks do not have L4 TCP/UDP header.
-		 **/
-		if (*prot_addr == IPPROTO_UDP || *prot_addr == IPPROTO_TCP) {
-			frag_off = PORT(*(frag_off_addr + 0),
-					*(frag_off_addr + 1));
-			mf = frag_off & 0x2000;
-			frag_off = frag_off & 0x1fff;
-			if (mf == 0 && frag_off == 0) {
-				v4_tuple.sport = PORT(*(src_dst_port + 0),
-						*(src_dst_port + 1));
-				v4_tuple.dport = PORT(*(src_dst_port + 2),
-						*(src_dst_port + 3));
-			}
-		}
-		__u8 input_len = sizeof(v4_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3);
-	} else if (proto == htons(ETH_P_IPV6)) {
-		if (data + off + sizeof(struct ipv6hdr) +
-					sizeof(__u32) > data_end)
-			return TC_ACT_OK;
-		__u8 *src_dst_addr = data + off +
-					offsetof(struct ipv6hdr, saddr);
-		__u8 *src_dst_port = data + off +
-					sizeof(struct ipv6hdr);
-		__u8 *next_hdr = data + off +
-					offsetof(struct ipv6hdr, nexthdr);
-
-		struct ipv6_l3_l4_tuple v6_tuple;
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.src_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + j));
-		for (j = 0; j < 4; j++)
-			*((uint32_t *)&v6_tuple.dst_addr + j) =
-				__builtin_bswap32(*((uint32_t *)
-						src_dst_addr + 4 + j));
-
-		/** Fetch the L4 header port-numbers only if next-header
-		 * is TCP/UDP **/
-		if (*next_hdr == IPPROTO_UDP || *next_hdr == IPPROTO_TCP) {
-			v6_tuple.sport = PORT(*(src_dst_port + 0),
-				      *(src_dst_port + 1));
-			v6_tuple.dport = PORT(*(src_dst_port + 2),
-				      *(src_dst_port + 3));
-		} else {
-			v6_tuple.sport = 0;
-			v6_tuple.dport = 0;
-		}
-
-		__u8 input_len = sizeof(v6_tuple) / sizeof(__u32);
-		if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3))
-			input_len--;
-		hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9);
-	} else {
-		return TC_ACT_PIPE;
-	}
-
-	queue = rsskey->queues[(hash % rsskey->nb_queues) &
-				       (TAP_MAX_QUEUES - 1)];
-	skb->cb[1] = QUEUE_OFFSET + queue;
-	/* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */
-
-	return TC_ACT_RECLASSIFY;
-}
-
-#define RSS(L)						\
-	__section(#L) int				\
-		L ## _hash(struct __sk_buff *skb)	\
-	{						\
-		return rss_ ## L (skb);			\
-	}
-
-RSS(l3_l4)
-
-BPF_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/tap/meson.build b/drivers/net/tap/meson.build
index 5099ccdff11b..f83f460a7808 100644
--- a/drivers/net/tap/meson.build
+++ b/drivers/net/tap/meson.build
@@ -7,7 +7,6 @@ if not is_linux
 endif
 sources = files(
         'rte_eth_tap.c',
-        'tap_bpf_api.c',
         'tap_flow.c',
         'tap_intr.c',
         'tap_netlink.c',
@@ -25,10 +24,6 @@ cflags += '-DTAP_MAX_QUEUES=16'
 args = [
         [ 'HAVE_TC_FLOWER', 'linux/pkt_cls.h', 'TCA_FLOWER_UNSPEC' ],
         [ 'HAVE_TC_VLAN_ID', 'linux/pkt_cls.h', 'TCA_FLOWER_KEY_VLAN_PRIO' ],
-        [ 'HAVE_TC_BPF', 'linux/pkt_cls.h', 'TCA_BPF_UNSPEC' ],
-        [ 'HAVE_TC_BPF_FD', 'linux/pkt_cls.h', 'TCA_BPF_FD' ],
-        [ 'HAVE_TC_ACT_BPF', 'linux/tc_act/tc_bpf.h', 'TCA_ACT_BPF_UNSPEC' ],
-        [ 'HAVE_TC_ACT_BPF_FD', 'linux/tc_act/tc_bpf.h', 'TCA_ACT_BPF_FD' ],
 ]
 config = configuration_data()
 foreach arg:args
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 5ac93f93e961..e19824583651 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -79,11 +79,8 @@ struct pmd_internals {
 	int flow_isolate;                 /* 1 if flow isolation is enabled */
 	int flower_support;               /* 1 if kernel supports, else 0 */
 	int flower_vlan_support;          /* 1 if kernel supports, else 0 */
-	int rss_enabled;                  /* 1 if RSS is enabled, else 0 */
 	int persist;			  /* 1 if keep link up, else 0 */
-	/* implicit rules set when RSS is enabled */
-	int map_fd;                       /* BPF RSS map fd */
-	int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */
+
 	LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
 	LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
 	/* implicit rte_flow rules set when a remote device is active */
diff --git a/drivers/net/tap/tap_bpf.h b/drivers/net/tap/tap_bpf.h
deleted file mode 100644
index 0d38bc111fe0..000000000000
--- a/drivers/net/tap/tap_bpf.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
- * Copyright 2017 Mellanox Technologies, Ltd
- */
-
-#ifndef __TAP_BPF_H__
-#define __TAP_BPF_H__
-
-#include <tap_autoconf.h>
-
-/* Do not #include <linux/bpf.h> since eBPF must compile on different
- * distros which may include partial definitions for eBPF (while the
- * kernel itself may support eBPF). Instead define here all that is needed
- */
-
-/* BPF_MAP_UPDATE_ELEM command flags */
-#define	BPF_ANY	0 /* create a new element or update an existing */
-
-/* BPF architecture instruction struct */
-struct bpf_insn {
-	__u8	code;
-	__u8	dst_reg:4;
-	__u8	src_reg:4;
-	__s16	off;
-	__s32	imm; /* immediate value */
-};
-
-/* BPF program types */
-enum bpf_prog_type {
-	BPF_PROG_TYPE_UNSPEC,
-	BPF_PROG_TYPE_SOCKET_FILTER,
-	BPF_PROG_TYPE_KPROBE,
-	BPF_PROG_TYPE_SCHED_CLS,
-	BPF_PROG_TYPE_SCHED_ACT,
-};
-
-/* BPF commands types */
-enum bpf_cmd {
-	BPF_MAP_CREATE,
-	BPF_MAP_LOOKUP_ELEM,
-	BPF_MAP_UPDATE_ELEM,
-	BPF_MAP_DELETE_ELEM,
-	BPF_MAP_GET_NEXT_KEY,
-	BPF_PROG_LOAD,
-};
-
-/* BPF maps types */
-enum bpf_map_type {
-	BPF_MAP_TYPE_UNSPEC,
-	BPF_MAP_TYPE_HASH,
-};
-
-/* union of anonymous structs used with TAP BPF commands */
-union bpf_attr {
-	/* BPF_MAP_CREATE command */
-	struct {
-		__u32	map_type;
-		__u32	key_size;
-		__u32	value_size;
-		__u32	max_entries;
-		__u32	map_flags;
-		__u32	inner_map_fd;
-	};
-
-	/* BPF_MAP_UPDATE_ELEM, BPF_MAP_DELETE_ELEM commands */
-	struct {
-		__u32		map_fd;
-		__aligned_u64	key;
-		union {
-			__aligned_u64 value;
-			__aligned_u64 next_key;
-		};
-		__u64		flags;
-	};
-
-	/* BPF_PROG_LOAD command */
-	struct {
-		__u32		prog_type;
-		__u32		insn_cnt;
-		__aligned_u64	insns;
-		__aligned_u64	license;
-		__u32		log_level;
-		__u32		log_size;
-		__aligned_u64	log_buf;
-		__u32		kern_version;
-		__u32		prog_flags;
-	};
-} __rte_aligned(8);
-
-#ifndef __NR_bpf
-# if defined(__i386__)
-#  define __NR_bpf 357
-# elif defined(__x86_64__)
-#  define __NR_bpf 321
-# elif defined(__arm__)
-#  define __NR_bpf 386
-# elif defined(__aarch64__)
-#  define __NR_bpf 280
-# elif defined(__sparc__)
-#  define __NR_bpf 349
-# elif defined(__s390__)
-#  define __NR_bpf 351
-# elif defined(__powerpc__)
-#  define __NR_bpf 361
-# elif defined(__riscv)
-#  define __NR_bpf 280
-# elif defined(__loongarch__)
-#  define __NR_bpf 280
-# else
-#  error __NR_bpf not defined
-# endif
-#endif
-
-enum {
-	BPF_MAP_ID_KEY,
-	BPF_MAP_ID_SIMPLE,
-};
-
-static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
-		size_t insns_cnt, const char *license);
-
-#endif /* __TAP_BPF_H__ */
diff --git a/drivers/net/tap/tap_bpf_api.c b/drivers/net/tap/tap_bpf_api.c
deleted file mode 100644
index 15283f8917ed..000000000000
--- a/drivers/net/tap/tap_bpf_api.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2017 Mellanox Technologies, Ltd
- */
-
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/queue.h>
-
-#include <rte_malloc.h>
-#include <rte_eth_tap.h>
-#include <tap_flow.h>
-#include <tap_autoconf.h>
-#include <tap_tcmsgs.h>
-#include <tap_bpf.h>
-#include <tap_bpf_insns.h>
-
-/**
- * Load BPF program (section cls_q) into the kernel and return a bpf fd
- *
- * @param queue_idx
- *   Queue index matching packet cb
- *
- * @return
- *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
- */
-int tap_flow_bpf_cls_q(__u32 queue_idx)
-{
-	cls_q_insns[1].imm = queue_idx;
-
-	return bpf_load(BPF_PROG_TYPE_SCHED_CLS,
-		(struct bpf_insn *)cls_q_insns,
-		RTE_DIM(cls_q_insns),
-		"Dual BSD/GPL");
-}
-
-/**
- * Load BPF program (section l3_l4) into the kernel and return a bpf fd.
- *
- * @param[in] key_idx
- *   RSS MAP key index
- *
- * @param[in] map_fd
- *   BPF RSS map file descriptor
- *
- * @return
- *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
- */
-int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
-{
-	l3_l4_hash_insns[4].imm = key_idx;
-	l3_l4_hash_insns[9].imm = map_fd;
-
-	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
-		(struct bpf_insn *)l3_l4_hash_insns,
-		RTE_DIM(l3_l4_hash_insns),
-		"Dual BSD/GPL");
-}
-
-/**
- * Helper function to convert a pointer to unsigned 64 bits
- *
- * @param[in] ptr
- *   pointer to address
- *
- * @return
- *   64 bit unsigned long type of pointer address
- */
-static inline __u64 ptr_to_u64(const void *ptr)
-{
-	return (__u64)(unsigned long)ptr;
-}
-
-/**
- * Call BPF system call
- *
- * @param[in] cmd
- *   BPF command for program loading, map creation, map entry update, etc
- *
- * @param[in] attr
- *   System call attributes relevant to system call command
- *
- * @param[in] size
- *   size of attr parameter
- *
- * @return
- *   -1 if BPF system call failed, 0 otherwise
- */
-static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
-			unsigned int size)
-{
-	return syscall(__NR_bpf, cmd, attr, size);
-}
-
-/**
- * Load BPF instructions to kernel
- *
- * @param[in] type
- *   BPF program type: classifier or action
- *
- * @param[in] insns
- *   Array of BPF instructions (equivalent to BPF instructions)
- *
- * @param[in] insns_cnt
- *   Number of BPF instructions (size of array)
- *
- * @param[in] license
- *   License string that must be acknowledged by the kernel
- *
- * @return
- *   -1 if the BPF program couldn't be loaded, fd (file descriptor) otherwise
- */
-static int bpf_load(enum bpf_prog_type type,
-		  const struct bpf_insn *insns,
-		  size_t insns_cnt,
-		  const char *license)
-{
-	union bpf_attr attr = {};
-
-	bzero(&attr, sizeof(attr));
-	attr.prog_type = type;
-	attr.insn_cnt = (__u32)insns_cnt;
-	attr.insns = ptr_to_u64(insns);
-	attr.license = ptr_to_u64(license);
-	attr.log_buf = ptr_to_u64(NULL);
-	attr.log_level = 0;
-	attr.kern_version = 0;
-
-	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
-}
-
-/**
- * Create BPF map for RSS rules
- *
- * @param[in] key_size
- *   map RSS key size
- *
- * @param[in] value_size
- *   Map RSS value size
- *
- * @param[in] max_entries
- *   Map max number of RSS entries (limit on max RSS rules)
- *
- * @return
- *   -1 if BPF map couldn't be created, map fd otherwise
- */
-int tap_flow_bpf_rss_map_create(unsigned int key_size,
-		unsigned int value_size,
-		unsigned int max_entries)
-{
-	union bpf_attr attr = {};
-
-	bzero(&attr, sizeof(attr));
-	attr.map_type    = BPF_MAP_TYPE_HASH;
-	attr.key_size    = key_size;
-	attr.value_size  = value_size;
-	attr.max_entries = max_entries;
-
-	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
-}
-
-/**
- * Update RSS entry in BPF map
- *
- * @param[in] fd
- *   RSS map fd
- *
- * @param[in] key
- *   Pointer to RSS key whose entry is updated
- *
- * @param[in] value
- *   Pointer to RSS new updated value
- *
- * @return
- *   -1 if RSS entry failed to be updated, 0 otherwise
- */
-int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value)
-{
-	union bpf_attr attr = {};
-
-	bzero(&attr, sizeof(attr));
-
-	attr.map_type = BPF_MAP_TYPE_HASH;
-	attr.map_fd = fd;
-	attr.key = ptr_to_u64(key);
-	attr.value = ptr_to_u64(value);
-	attr.flags = BPF_ANY;
-
-	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
-}
diff --git a/drivers/net/tap/tap_bpf_insns.h b/drivers/net/tap/tap_bpf_insns.h
deleted file mode 100644
index 53fa76c4e6b0..000000000000
--- a/drivers/net/tap/tap_bpf_insns.h
+++ /dev/null
@@ -1,1743 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Auto-generated from tap_bpf_program.c
- * This not the original source file. Do NOT edit it.
- */
-
-#include <tap_bpf.h>
-
-static struct bpf_insn cls_q_insns[] = {
-	{0x61,    2,    1,       52, 0x00000000},
-	{0x18,    3,    0,        0, 0xdeadbeef},
-	{0x00,    0,    0,        0, 0x00000000},
-	{0x63,   10,    3,       -4, 0x00000000},
-	{0xb7,    0,    0,        0, 0x00000000},
-	{0x61,    3,   10,       -4, 0x00000000},
-	{0x07,    3,    0,        0, 0x7cafe800},
-	{0x67,    3,    0,        0, 0x00000020},
-	{0x77,    3,    0,        0, 0x00000020},
-	{0x5d,    2,    3,        4, 0x00000000},
-	{0xb7,    2,    0,        0, 0x00000000},
-	{0x63,    1,    2,       52, 0x00000000},
-	{0x18,    0,    0,        0, 0xffffffff},
-	{0x00,    0,    0,        0, 0x00000000},
-	{0x95,    0,    0,        0, 0x00000000},
-};
-
-static struct bpf_insn l3_l4_hash_insns[] = {
-	{0xbf,    7,    1,        0, 0x00000000},
-	{0x61,    6,    7,       16, 0x00000000},
-	{0x61,    8,    7,       76, 0x00000000},
-	{0x61,    9,    7,       80, 0x00000000},
-	{0x18,    1,    0,        0, 0xdeadbeef},
-	{0x00,    0,    0,        0, 0x00000000},
-	{0x63,   10,    1,       -4, 0x00000000},
-	{0xbf,    2,   10,        0, 0x00000000},
-	{0x07,    2,    0,        0, 0xfffffffc},
-	{0x18,    1,    0,        0, 0x00000000},
-	{0x00,    0,    0,        0, 0x00000000},
-	{0x85,    0,    0,        0, 0x00000001},
-	{0x55,    0,    0,       21, 0x00000000},
-	{0xb7,    1,    0,        0, 0x00000a64},
-	{0x6b,   10,    1,      -16, 0x00000000},
-	{0x18,    1,    0,        0, 0x69666e6f},
-	{0x00,    0,    0,        0, 0x65727567},
-	{0x7b,   10,    1,      -24, 0x00000000},
-	{0x18,    1,    0,        0, 0x6e207369},
-	{0x00,    0,    0,        0, 0x6320746f},
-	{0x7b,   10,    1,      -32, 0x00000000},
-	{0x18,    1,    0,        0, 0x20737372},
-	{0x00,    0,    0,        0, 0x2079656b},
-	{0x7b,   10,    1,      -40, 0x00000000},
-	{0x18,    1,    0,        0, 0x68736168},
-	{0x00,    0,    0,        0, 0x203a2928},
-	{0x7b,   10,    1,      -48, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0x73,   10,    7,      -14, 0x00000000},
-	{0xbf,    1,   10,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0xffffffd0},
-	{0xb7,    2,    0,        0, 0x00000023},
-	{0x85,    0,    0,        0, 0x00000006},
-	{0x05,    0,    0,     1680, 0x00000000},
-	{0xb7,    1,    0,        0, 0x0000000e},
-	{0x61,    2,    7,       20, 0x00000000},
-	{0x15,    2,    0,       10, 0x00000000},
-	{0x61,    2,    7,       28, 0x00000000},
-	{0x55,    2,    0,        8, 0x0000a888},
-	{0xbf,    2,    7,        0, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0xbf,    1,    8,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0x00000012},
-	{0x2d,    1,    9,     1670, 0x00000000},
-	{0xb7,    1,    0,        0, 0x00000012},
-	{0x69,    6,    8,       16, 0x00000000},
-	{0xbf,    7,    2,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x0000ffff},
-	{0x7b,   10,    7,      -56, 0x00000000},
-	{0x15,    6,    0,      443, 0x0000dd86},
-	{0xb7,    7,    0,        0, 0x00000003},
-	{0x55,    6,    0,     1662, 0x00000008},
-	{0x0f,    8,    1,        0, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0xbf,    1,    8,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0x00000018},
-	{0x2d,    1,    9,     1657, 0x00000000},
-	{0xb7,    1,    0,        0, 0x00000000},
-	{0x71,    3,    8,       12, 0x00000000},
-	{0x71,    2,    8,        9, 0x00000000},
-	{0x15,    2,    0,        1, 0x00000011},
-	{0x55,    2,    0,       21, 0x00000006},
-	{0x71,    2,    8,        7, 0x00000000},
-	{0x71,    4,    8,        6, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x67,    5,    0,        0, 0x00000008},
-	{0x57,    5,    0,        0, 0x00001f00},
-	{0x4f,    5,    2,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x4f,    4,    5,        0, 0x00000000},
-	{0x55,    4,    0,       12, 0x00000000},
-	{0xbf,    2,    8,        0, 0x00000000},
-	{0x07,    2,    0,        0, 0x00000014},
-	{0x71,    4,    2,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000018},
-	{0x71,    1,    2,        1, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000010},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    4,    2,        3, 0x00000000},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    2,    2,        2, 0x00000000},
-	{0x67,    2,    0,        0, 0x00000008},
-	{0x4f,    1,    2,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000038},
-	{0xc7,    4,    0,        0, 0x00000038},
-	{0xb7,    2,    0,        0, 0x00000000},
-	{0x65,    4,    0,        1, 0xffffffff},
-	{0xb7,    7,    0,        0, 0x2cc681d1},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x598d03a2},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb31a0745},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x66340e8a},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xcc681d15},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000004},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x98d03a2b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000002},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x31a07456},
-	{0x71,    4,    8,       13, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6340e8ad},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc681d15b},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d03a2b7},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1a07456f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x340e8ade},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x681d15bd},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd03a2b7b},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa07456f6},
-	{0x71,    3,    8,       14, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x40e8aded},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000038},
-	{0xc7,    4,    0,        0, 0x00000038},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0x81d15bdb},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x03a2b7b7},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x07456f6f},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x0e8adedf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1d15bdbf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000004},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3a2b7b7e},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000002},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7456f6fd},
-	{0x71,    4,    8,       15, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe8adedfa},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd15bdbf4},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa2b7b7e9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x456f6fd3},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8adedfa7},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x15bdbf4f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x2b7b7e9e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x56f6fd3d},
-	{0x71,    3,    8,       16, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xadedfa7b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000038},
-	{0xc7,    4,    0,        0, 0x00000038},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5bdbf4f7},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb7b7e9ef},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6f6fd3df},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xdedfa7bf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xbdbf4f7f},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000004},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7b7e9eff},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000002},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf6fd3dff},
-	{0x71,    4,    8,       17, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xedfa7bfe},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdbf4f7fc},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb7e9eff9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6fd3dff2},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdfa7bfe5},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbf4f7fca},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7e9eff94},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfd3dff28},
-	{0x71,    3,    8,       18, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfa7bfe51},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x67,    6,    0,        0, 0x00000038},
-	{0xc7,    6,    0,        0, 0x00000038},
-	{0xbf,    4,    5,        0, 0x00000000},
-	{0xa7,    4,    0,        0, 0xf4f7fca2},
-	{0x6d,    2,    6,        1, 0x00000000},
-	{0xbf,    4,    5,        0, 0x00000000},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000040},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xe9eff945},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000020},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd3dff28a},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000010},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xa7bfe514},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000008},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x4f7fca28},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x9eff9450},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x3dff28a0},
-	{0x71,    5,    8,       19, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x7bfe5141},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000038},
-	{0xc7,    3,    0,        0, 0x00000038},
-	{0xbf,    7,    4,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf7fca283},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    7,    4,        0, 0x00000000},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xeff94506},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xdff28a0c},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xbfe51418},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7fca2831},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000004},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xff945063},
-	{0xbf,    3,    5,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000002},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xff28a0c6},
-	{0x57,    5,    0,        0, 0x00000001},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xfe51418c},
-	{0xbf,    4,    1,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000020},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0xbf,    3,    7,        0, 0x00000000},
-	{0xa7,    3,    0,        0, 0xfca28319},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    3,    7,        0, 0x00000000},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x40000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf9450633},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x20000000},
-	{0x79,    6,   10,      -56, 0x00000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf28a0c67},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x10000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xe51418ce},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x08000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xca28319d},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x04000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x9450633b},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x02000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x28a0c676},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x01000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x51418ced},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00800000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xa28319db},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00400000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x450633b6},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00200000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8a0c676c},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00100000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x1418ced8},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00080000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x28319db1},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00040000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x50633b63},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00020000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xa0c676c6},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00010000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x418ced8d},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00008000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8319db1a},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00004000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x0633b634},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00002000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x0c676c68},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00001000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x18ced8d1},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000800},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x319db1a3},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000400},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x633b6347},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000200},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xc676c68f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000100},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8ced8d1f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000080},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x19db1a3e},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000040},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x33b6347d},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000020},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x676c68fa},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000010},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xced8d1f4},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000008},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x9db1a3e9},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000004},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x3b6347d2},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000002},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x76c68fa5},
-	{0x57,    1,    0,        0, 0x00000001},
-	{0x15,    1,    0,     1194, 0x00000000},
-	{0xa7,    3,    0,        0, 0xed8d1f4a},
-	{0x05,    0,    0,     1192, 0x00000000},
-	{0x0f,    8,    1,        0, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000000},
-	{0xbf,    1,    8,        0, 0x00000000},
-	{0x07,    1,    0,        0, 0x0000002c},
-	{0x2d,    1,    9,     1216, 0x00000000},
-	{0x61,    2,    8,        8, 0x00000000},
-	{0xdc,    2,    0,        0, 0x00000040},
-	{0xc7,    2,    0,        0, 0x00000020},
-	{0x71,    3,    8,        6, 0x00000000},
-	{0x15,    3,    0,        2, 0x00000011},
-	{0xb7,    1,    0,        0, 0x00000000},
-	{0x55,    3,    0,       12, 0x00000006},
-	{0xbf,    3,    8,        0, 0x00000000},
-	{0x07,    3,    0,        0, 0x00000028},
-	{0x71,    4,    3,        0, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000018},
-	{0x71,    1,    3,        1, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000010},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    4,    3,        3, 0x00000000},
-	{0x4f,    1,    4,        0, 0x00000000},
-	{0x71,    3,    3,        2, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000008},
-	{0x4f,    1,    3,        0, 0x00000000},
-	{0xbf,    4,    2,        0, 0x00000000},
-	{0x77,    4,    0,        0, 0x0000001f},
-	{0x57,    4,    0,        0, 0x2cc681d1},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x598d03a2},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb31a0745},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x66340e8a},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xcc681d15},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x98d03a2b},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x31a07456},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x6340e8ad},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xc681d15b},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x8d03a2b7},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00200000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x1a07456f},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x340e8ade},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x681d15bd},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd03a2b7b},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xa07456f6},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00010000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x40e8aded},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x81d15bdb},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00004000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x03a2b7b7},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x07456f6f},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x0e8adedf},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x1d15bdbf},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x3a2b7b7e},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x7456f6fd},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xe8adedfa},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd15bdbf4},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xa2b7b7e9},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x456f6fd3},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x8adedfa7},
-	{0xbf,    3,    2,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x15bdbf4f},
-	{0x61,    3,    8,       12, 0x00000000},
-	{0xbf,    5,    2,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x2b7b7e9e},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    2,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x56f6fd3d},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    2,    0,        0, 0x00000001},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xadedfa7b},
-	{0xb7,    2,    0,        0, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0x5bdbf4f7},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x40000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb7b7e9ef},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x20000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6f6fd3df},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x10000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdedfa7bf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x08000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbdbf4f7f},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x04000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7b7e9eff},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x02000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf6fd3dff},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x01000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xedfa7bfe},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00800000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdbf4f7fc},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00400000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb7e9eff9},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00200000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6fd3dff2},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00100000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdfa7bfe5},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00080000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbf4f7fca},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00040000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7e9eff94},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00020000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfd3dff28},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00010000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfa7bfe51},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00008000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf4f7fca2},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00004000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe9eff945},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00002000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd3dff28a},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00001000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa7bfe514},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000800},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x4f7fca28},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000400},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x9eff9450},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000200},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3dff28a0},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000100},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7bfe5141},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000080},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf7fca283},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xeff94506},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdff28a0c},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xbfe51418},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7fca2831},
-	{0x61,    4,    8,       16, 0x00000000},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000004},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xff945063},
-	{0xdc,    4,    0,        0, 0x00000040},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000002},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xff28a0c6},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfe51418c},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0xfca28319},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf9450633},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf28a0c67},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe51418ce},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xca28319d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9450633b},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x28a0c676},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x51418ced},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa28319db},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x450633b6},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00200000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8a0c676c},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1418ced8},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x28319db1},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x50633b63},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa0c676c6},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00010000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x418ced8d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8319db1a},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00004000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x0633b634},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x0c676c68},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x18ced8d1},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x319db1a3},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x633b6347},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc676c68f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8ced8d1f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x19db1a3e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x33b6347d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x676c68fa},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xced8d1f4},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9db1a3e9},
-	{0x61,    3,    8,       20, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3b6347d2},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x76c68fa5},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xed8d1f4a},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0xdb1a3e94},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x40000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb6347d28},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x20000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6c68fa51},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x10000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd8d1f4a3},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x08000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb1a3e946},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x04000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6347d28d},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x02000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc68fa51a},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x01000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d1f4a35},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00800000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1a3e946b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00400000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x347d28d7},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00200000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x68fa51ae},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00100000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd1f4a35c},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00080000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa3e946b9},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00040000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x47d28d73},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00020000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8fa51ae7},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00010000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1f4a35cf},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00008000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3e946b9e},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00004000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7d28d73c},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00002000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xfa51ae78},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00001000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf4a35cf1},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000800},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe946b9e3},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000400},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd28d73c7},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000200},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa51ae78e},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000100},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x4a35cf1c},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000080},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x946b9e38},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x28d73c71},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x51ae78e3},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa35cf1c6},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x46b9e38d},
-	{0x61,    4,    8,       24, 0x00000000},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000004},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d73c71b},
-	{0xdc,    4,    0,        0, 0x00000040},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000002},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1ae78e36},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x35cf1c6c},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6b9e38d9},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xd73c71b2},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xae78e364},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5cf1c6c9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb9e38d92},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x73c71b25},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe78e364b},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xcf1c6c96},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9e38d92c},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3c71b259},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00200000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x78e364b2},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf1c6c964},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe38d92c9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc71b2593},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8e364b27},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00010000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1c6c964e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x38d92c9c},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00004000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x71b25938},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xe364b270},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc6c964e0},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x8d92c9c0},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x1b259380},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x364b2700},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6c964e01},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xd92c9c03},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb2593807},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x64b2700f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xc964e01e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x92c9c03d},
-	{0x61,    3,    8,       28, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x2593807a},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x4b2700f4},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x964e01e8},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xa7,    5,    0,        0, 0x2c9c03d1},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    5,    7,        0, 0x00000000},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x40000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x593807a3},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x20000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xb2700f46},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x10000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x64e01e8d},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x08000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc9c03d1a},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x04000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x93807a35},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x02000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x2700f46b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x01000000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x4e01e8d6},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00800000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x9c03d1ad},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00400000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3807a35b},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00200000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x700f46b6},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00100000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe01e8d6c},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00080000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xc03d1ad9},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00040000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x807a35b3},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00020000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x00f46b66},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00010000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x01e8d6cc},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00008000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x03d1ad99},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00004000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x07a35b32},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00002000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x0f46b665},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00001000},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1e8d6cca},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000800},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x3d1ad994},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000400},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x7a35b328},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000200},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xf46b6651},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000100},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xe8d6cca2},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000080},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd1ad9944},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000040},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xa35b3289},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000020},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x46b66512},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000010},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x8d6cca25},
-	{0xbf,    4,    3,        0, 0x00000000},
-	{0x57,    4,    0,        0, 0x00000008},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x1ad9944a},
-	{0x61,    4,    8,       32, 0x00000000},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000004},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x35b32894},
-	{0xdc,    4,    0,        0, 0x00000040},
-	{0xbf,    6,    3,        0, 0x00000000},
-	{0x57,    6,    0,        0, 0x00000002},
-	{0x15,    6,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0x6b665129},
-	{0xc7,    4,    0,        0, 0x00000020},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    5,    0,        0, 0xd6cca253},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xa7,    7,    0,        0, 0xad9944a7},
-	{0x6d,    2,    4,        1, 0x00000000},
-	{0xbf,    7,    5,        0, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x40000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5b32894f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x20000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb665129f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x10000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x6cca253e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x08000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xd9944a7d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x04000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xb32894fb},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x02000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x665129f6},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x01000000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xcca253ec},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00800000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9944a7d9},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00400000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x32894fb2},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00200000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x65129f65},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00100000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xca253eca},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00080000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x944a7d95},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00040000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x2894fb2a},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00020000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x5129f655},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00010000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa253ecab},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00008000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x44a7d956},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00004000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x894fb2ac},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00002000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x129f6558},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00001000},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x253ecab1},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000800},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x4a7d9563},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000400},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x94fb2ac7},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000200},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x29f6558f},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000100},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x53ecab1e},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000080},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xa7d9563d},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000040},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x4fb2ac7a},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000020},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x9f6558f5},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000010},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x3ecab1ea},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x00000008},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0x7d9563d5},
-	{0x61,    3,    8,       36, 0x00000000},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xfb2ac7ab},
-	{0xdc,    3,    0,        0, 0x00000040},
-	{0xbf,    5,    4,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xf6558f56},
-	{0xc7,    3,    0,        0, 0x00000020},
-	{0x57,    4,    0,        0, 0x00000001},
-	{0x15,    4,    0,        1, 0x00000000},
-	{0xa7,    7,    0,        0, 0xecab1eac},
-	{0xbf,    4,    7,        0, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd9563d59},
-	{0x6d,    2,    3,        1, 0x00000000},
-	{0xbf,    4,    7,        0, 0x00000000},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x40000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb2ac7ab2},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x20000000},
-	{0x79,    6,   10,      -56, 0x00000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x6558f564},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x10000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xcab1eac8},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x08000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x9563d590},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x04000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x2ac7ab20},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x02000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x558f5641},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x01000000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xab1eac83},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00800000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x563d5906},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00400000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xac7ab20c},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00200000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x58f56418},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00100000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb1eac831},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00080000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x63d59063},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00040000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xc7ab20c7},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00020000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x8f56418f},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00010000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x1eac831e},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00008000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x3d59063c},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00004000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x7ab20c78},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00002000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xf56418f0},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00001000},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xeac831e1},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000800},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xd59063c2},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000400},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xab20c784},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000200},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x56418f09},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000100},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xac831e12},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000080},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x59063c25},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000040},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xb20c784b},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000020},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x6418f097},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000010},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0xc831e12f},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000008},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x9063c25f},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000004},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x20c784be},
-	{0xbf,    5,    3,        0, 0x00000000},
-	{0x57,    5,    0,        0, 0x00000002},
-	{0x15,    5,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x418f097c},
-	{0x57,    3,    0,        0, 0x00000001},
-	{0x15,    3,    0,        1, 0x00000000},
-	{0xa7,    4,    0,        0, 0x831e12f9},
-	{0xbf,    5,    1,        0, 0x00000000},
-	{0x67,    5,    0,        0, 0x00000020},
-	{0xc7,    5,    0,        0, 0x00000020},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0xa7,    3,    0,        0, 0x063c25f3},
-	{0x6d,    2,    5,        1, 0x00000000},
-	{0xbf,    3,    4,        0, 0x00000000},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x40000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x0c784be7},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x20000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x18f097cf},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x10000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x31e12f9f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x08000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x63c25f3f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x04000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xc784be7f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x02000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x8f097cff},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x01000000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x1e12f9fe},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00800000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x3c25f3fc},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00400000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x784be7f8},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00200000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf097cff0},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00100000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xe12f9fe0},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00080000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xc25f3fc1},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00040000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x84be7f83},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00020000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x097cff07},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00010000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x12f9fe0f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00008000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x25f3fc1f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00004000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x4be7f83f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00002000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x97cff07f},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00001000},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x2f9fe0fe},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000800},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x5f3fc1fd},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000400},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xbe7f83fb},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000200},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x7cff07f7},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000100},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf9fe0fee},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000080},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xf3fc1fdc},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000040},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xe7f83fb8},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000020},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xcff07f70},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000010},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x9fe0fee1},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000008},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x3fc1fdc2},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000004},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0x7f83fb85},
-	{0xbf,    2,    1,        0, 0x00000000},
-	{0x57,    2,    0,        0, 0x00000002},
-	{0x15,    2,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xff07f70a},
-	{0x57,    1,    0,        0, 0x00000001},
-	{0x15,    1,    0,        1, 0x00000000},
-	{0xa7,    3,    0,        0, 0xfe0fee15},
-	{0x71,    1,    0,      201, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000008},
-	{0x71,    2,    0,      200, 0x00000000},
-	{0x4f,    1,    2,        0, 0x00000000},
-	{0x71,    2,    0,      202, 0x00000000},
-	{0x67,    2,    0,        0, 0x00000010},
-	{0x71,    4,    0,      203, 0x00000000},
-	{0x67,    4,    0,        0, 0x00000018},
-	{0x4f,    4,    2,        0, 0x00000000},
-	{0x4f,    4,    1,        0, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000020},
-	{0x77,    3,    0,        0, 0x00000020},
-	{0x9f,    3,    4,        0, 0x00000000},
-	{0x57,    3,    0,        0, 0x0000000f},
-	{0x67,    3,    0,        0, 0x00000002},
-	{0x0f,    0,    3,        0, 0x00000000},
-	{0x71,    1,    0,      137, 0x00000000},
-	{0x67,    1,    0,        0, 0x00000008},
-	{0x71,    2,    0,      136, 0x00000000},
-	{0x4f,    1,    2,        0, 0x00000000},
-	{0x71,    2,    0,      138, 0x00000000},
-	{0x67,    2,    0,        0, 0x00000010},
-	{0x71,    3,    0,      139, 0x00000000},
-	{0x67,    3,    0,        0, 0x00000018},
-	{0x4f,    3,    2,        0, 0x00000000},
-	{0x4f,    3,    1,        0, 0x00000000},
-	{0x07,    3,    0,        0, 0x7cafe800},
-	{0x63,    6,    3,       52, 0x00000000},
-	{0xb7,    7,    0,        0, 0x00000001},
-	{0xbf,    0,    7,        0, 0x00000000},
-	{0x95,    0,    0,        0, 0x00000000},
-};
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index ed4d42f92f9f..84e816d80043 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -56,71 +56,6 @@ enum {
 	TCA_FLOWER_KEY_VLAN_ETH_TYPE,   /* be16 */
 };
 #endif
-/*
- * For kernels < 4.2 BPF related enums may not be defined.
- * Runtime checks will be carried out to gracefully report on TC messages that
- * are rejected by the kernel. Rejection reasons may be due to:
- * 1. enum is not defined
- * 2. enum is defined but kernel is not configured to support BPF system calls,
- *    BPF classifications or BPF actions.
- */
-#ifndef HAVE_TC_BPF
-enum {
-	TCA_BPF_UNSPEC,
-	TCA_BPF_ACT,
-	TCA_BPF_POLICE,
-	TCA_BPF_CLASSID,
-	TCA_BPF_OPS_LEN,
-	TCA_BPF_OPS,
-};
-#endif
-#ifndef HAVE_TC_BPF_FD
-enum {
-	TCA_BPF_FD = TCA_BPF_OPS + 1,
-	TCA_BPF_NAME,
-};
-#endif
-#ifndef HAVE_TC_ACT_BPF
-#define tc_gen \
-	__u32                 index; \
-	__u32                 capab; \
-	int                   action; \
-	int                   refcnt; \
-	int                   bindcnt
-
-struct tc_act_bpf {
-	tc_gen;
-};
-
-enum {
-	TCA_ACT_BPF_UNSPEC,
-	TCA_ACT_BPF_TM,
-	TCA_ACT_BPF_PARMS,
-	TCA_ACT_BPF_OPS_LEN,
-	TCA_ACT_BPF_OPS,
-};
-
-#endif
-#ifndef HAVE_TC_ACT_BPF_FD
-enum {
-	TCA_ACT_BPF_FD = TCA_ACT_BPF_OPS + 1,
-	TCA_ACT_BPF_NAME,
-};
-#endif
-
-/* RSS key management */
-enum bpf_rss_key_e {
-	KEY_CMD_GET = 1,
-	KEY_CMD_RELEASE,
-	KEY_CMD_INIT,
-	KEY_CMD_DEINIT,
-};
-
-enum key_status_e {
-	KEY_STAT_UNSPEC,
-	KEY_STAT_USED,
-	KEY_STAT_AVAILABLE,
-};
 
 #define ISOLATE_HANDLE 1
 #define REMOTE_PROMISCUOUS_HANDLE 2
@@ -128,8 +63,6 @@ enum key_status_e {
 struct rte_flow {
 	LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure */
 	struct rte_flow *remote_flow; /* associated remote flow */
-	int bpf_fd[SEC_MAX]; /* list of bfs fds per ELF section */
-	uint32_t key_idx; /* RSS rule key index into BPF map */
 	struct nlmsg msg;
 };
 
@@ -157,11 +90,6 @@ struct action_data {
 			struct tc_skbedit skbedit;
 			uint16_t queue;
 		} skbedit;
-		struct bpf {
-			struct tc_act_bpf bpf;
-			int bpf_fd;
-			const char *annotation;
-		} bpf;
 	};
 };
 
@@ -185,10 +113,6 @@ tap_flow_create(struct rte_eth_dev *dev,
 		const struct rte_flow_action actions[],
 		struct rte_flow_error *error);
 
-static void
-tap_flow_free(struct pmd_internals *pmd,
-	struct rte_flow *flow);
-
 static int
 tap_flow_destroy(struct rte_eth_dev *dev,
 		 struct rte_flow *flow,
@@ -199,14 +123,6 @@ tap_flow_isolate(struct rte_eth_dev *dev,
 		 int set,
 		 struct rte_flow_error *error);
 
-static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx);
-static int rss_enable(struct pmd_internals *pmd,
-			const struct rte_flow_attr *attr,
-			struct rte_flow_error *error);
-static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
-			const struct rte_flow_action_rss *rss,
-			struct rte_flow_error *error);
-
 static const struct rte_flow_ops tap_flow_ops = {
 	.validate = tap_flow_validate,
 	.create = tap_flow_create,
@@ -901,7 +817,7 @@ tap_flow_item_validate(const struct rte_flow_item *item,
 
 /**
  * Configure the kernel with a TC action and its configured parameters
- * Handled actions: "gact", "mirred", "skbedit", "bpf"
+ * Handled actions: "gact", "mirred", "skbedit"
  *
  * @param[in] flow
  *   Pointer to rte flow containing the netlink message
@@ -944,14 +860,6 @@ add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
 			   &adata->skbedit.skbedit);
 		tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
 			     adata->skbedit.queue);
-	} else if (strcmp("bpf", adata->id) == 0) {
-		tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
-		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
-			   strlen(adata->bpf.annotation) + 1,
-			   adata->bpf.annotation);
-		tap_nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS,
-			   sizeof(adata->bpf.bpf),
-			   &adata->bpf.bpf);
 	} else {
 		return -1;
 	}
@@ -1216,21 +1124,6 @@ priv_flow_process(struct pmd_internals *pmd,
 				err = add_actions(flow, 1, &adata,
 					TCA_FLOWER_ACT);
 			}
-		} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
-			const struct rte_flow_action_rss *rss =
-				(const struct rte_flow_action_rss *)
-				actions->conf;
-
-			if (action++)
-				goto exit_action_not_supported;
-
-			if (!pmd->rss_enabled) {
-				err = rss_enable(pmd, attr, error);
-				if (err)
-					goto exit_action_not_supported;
-			}
-			if (flow)
-				err = rss_add_actions(flow, pmd, rss, error);
 		} else {
 			goto exit_action_not_supported;
 		}
@@ -1318,38 +1211,6 @@ tap_flow_set_handle(struct rte_flow *flow)
 	flow->msg.t.tcm_handle = handle;
 }
 
-/**
- * Free the flow opened file descriptors and allocated memory
- *
- * @param[in] flow
- *   Pointer to the flow to free
- *
- */
-static void
-tap_flow_free(struct pmd_internals *pmd, struct rte_flow *flow)
-{
-	int i;
-
-	if (!flow)
-		return;
-
-	if (pmd->rss_enabled) {
-		/* Close flow BPF file descriptors */
-		for (i = 0; i < SEC_MAX; i++)
-			if (flow->bpf_fd[i] != 0) {
-				close(flow->bpf_fd[i]);
-				flow->bpf_fd[i] = 0;
-			}
-
-		/* Release the map key for this RSS rule */
-		bpf_rss_key(KEY_CMD_RELEASE, &flow->key_idx);
-		flow->key_idx = 0;
-	}
-
-	/* Free flow allocated memory */
-	rte_free(flow);
-}
-
 /**
  * Create a flow.
  *
@@ -1466,8 +1327,7 @@ tap_flow_create(struct rte_eth_dev *dev,
 	return flow;
 fail:
 	rte_free(remote_flow);
-	if (flow)
-		tap_flow_free(pmd, flow);
+	rte_free(flow);
 	return NULL;
 }
 
@@ -1541,7 +1401,7 @@ tap_flow_destroy_pmd(struct pmd_internals *pmd,
 	}
 end:
 	rte_free(remote_flow);
-	tap_flow_free(pmd, flow);
+	rte_free(flow);
 	return ret;
 }
 
@@ -1812,356 +1672,6 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error)
 	return 0;
 }
 
-#define MAX_RSS_KEYS 256
-#define KEY_IDX_OFFSET (3 * MAX_RSS_KEYS)
-#define SEC_NAME_CLS_Q "cls_q"
-
-static const char *sec_name[SEC_MAX] = {
-	[SEC_L3_L4] = "l3_l4",
-};
-
-/**
- * Enable RSS on tap: create TC rules for queuing.
- *
- * @param[in, out] pmd
- *   Pointer to private structure.
- *
- * @param[in] attr
- *   Pointer to rte_flow to get flow group
- *
- * @param[out] error
- *   Pointer to error reporting if not NULL.
- *
- * @return 0 on success, negative value on failure.
- */
-static int rss_enable(struct pmd_internals *pmd,
-			const struct rte_flow_attr *attr,
-			struct rte_flow_error *error)
-{
-	struct rte_flow *rss_flow = NULL;
-	struct nlmsg *msg = NULL;
-	/* 4096 is the maximum number of instructions for a BPF program */
-	char annotation[64];
-	int i;
-	int err = 0;
-
-	/* unlimit locked memory */
-	struct rlimit memlock_limit = {
-		.rlim_cur = RLIM_INFINITY,
-		.rlim_max = RLIM_INFINITY,
-	};
-	setrlimit(RLIMIT_MEMLOCK, &memlock_limit);
-
-	 /* Get a new map key for a new RSS rule */
-	err = bpf_rss_key(KEY_CMD_INIT, NULL);
-	if (err < 0) {
-		rte_flow_error_set(
-			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
-			"Failed to initialize BPF RSS keys");
-
-		return -1;
-	}
-
-	/*
-	 *  Create BPF RSS MAP
-	 */
-	pmd->map_fd = tap_flow_bpf_rss_map_create(sizeof(__u32), /* key size */
-				sizeof(struct rss_key),
-				MAX_RSS_KEYS);
-	if (pmd->map_fd < 0) {
-		TAP_LOG(ERR,
-			"Failed to create BPF map (%d): %s",
-				errno, strerror(errno));
-		rte_flow_error_set(
-			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
-			"Kernel too old or not configured "
-			"to support BPF maps");
-
-		return -ENOTSUP;
-	}
-
-	/*
-	 * Add a rule per queue to match reclassified packets and direct them to
-	 * the correct queue.
-	 */
-	for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
-		pmd->bpf_fd[i] = tap_flow_bpf_cls_q(i);
-		if (pmd->bpf_fd[i] < 0) {
-			TAP_LOG(ERR,
-				"Failed to load BPF section %s for queue %d",
-				SEC_NAME_CLS_Q, i);
-			rte_flow_error_set(
-				error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
-				NULL,
-				"Kernel too old or not configured "
-				"to support BPF programs loading");
-
-			return -ENOTSUP;
-		}
-
-		rss_flow = rte_zmalloc(__func__, sizeof(struct rte_flow), 0);
-		if (!rss_flow) {
-			TAP_LOG(ERR,
-				"Cannot allocate memory for rte_flow");
-			return -1;
-		}
-		msg = &rss_flow->msg;
-		tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, NLM_F_REQUEST |
-			    NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
-		msg->t.tcm_info = TC_H_MAKE(0, htons(ETH_P_ALL));
-		tap_flow_set_handle(rss_flow);
-		uint16_t group = attr->group << GROUP_SHIFT;
-		uint16_t prio = group | (i + PRIORITY_OFFSET);
-		msg->t.tcm_info = TC_H_MAKE(prio << 16, msg->t.tcm_info);
-		msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
-
-		tap_nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
-		if (tap_nlattr_nested_start(msg, TCA_OPTIONS) < 0)
-			return -1;
-		tap_nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]);
-		snprintf(annotation, sizeof(annotation), "[%s%d]",
-			SEC_NAME_CLS_Q, i);
-		tap_nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation) + 1,
-			   annotation);
-		/* Actions */
-		{
-			struct action_data adata = {
-				.id = "skbedit",
-				.skbedit = {
-					.skbedit = {
-						.action = TC_ACT_PIPE,
-					},
-					.queue = i,
-				},
-			};
-			if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
-				return -1;
-		}
-		tap_nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
-
-		/* Netlink message is now ready to be sent */
-		if (tap_nl_send(pmd->nlsk_fd, &msg->nh) < 0)
-			return -1;
-		err = tap_nl_recv_ack(pmd->nlsk_fd);
-		if (err < 0) {
-			TAP_LOG(ERR,
-				"Kernel refused TC filter rule creation (%d): %s",
-				errno, strerror(errno));
-			return err;
-		}
-		LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
-	}
-
-	pmd->rss_enabled = 1;
-	return err;
-}
-
-/**
- * Manage bpf RSS keys repository with operations: init, get, release
- *
- * @param[in] cmd
- *   Command on RSS keys: init, get, release
- *
- * @param[in, out] key_idx
- *   Pointer to RSS Key index (out for get command, in for release command)
- *
- * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise.
- */
-static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
-{
-	__u32 i;
-	int err = 0;
-	static __u32 num_used_keys;
-	static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC};
-	static __u32 rss_keys_initialized;
-	__u32 key;
-
-	switch (cmd) {
-	case KEY_CMD_GET:
-		if (!rss_keys_initialized) {
-			err = -1;
-			break;
-		}
-
-		if (num_used_keys == RTE_DIM(rss_keys)) {
-			err = -1;
-			break;
-		}
-
-		*key_idx = num_used_keys % RTE_DIM(rss_keys);
-		while (rss_keys[*key_idx] == KEY_STAT_USED)
-			*key_idx = (*key_idx + 1) % RTE_DIM(rss_keys);
-
-		rss_keys[*key_idx] = KEY_STAT_USED;
-
-		/*
-		 * Add an offset to key_idx in order to handle a case of
-		 * RSS and non RSS flows mixture.
-		 * If a non RSS flow is destroyed it has an eBPF map
-		 * index 0 (initialized on flow creation) and might
-		 * unintentionally remove RSS entry 0 from eBPF map.
-		 * To avoid this issue, add an offset to the real index
-		 * during a KEY_CMD_GET operation and subtract this offset
-		 * during a KEY_CMD_RELEASE operation in order to restore
-		 * the real index.
-		 */
-		*key_idx += KEY_IDX_OFFSET;
-		num_used_keys++;
-	break;
-
-	case KEY_CMD_RELEASE:
-		if (!rss_keys_initialized)
-			break;
-
-		/*
-		 * Subtract offset to restore real key index
-		 * If a non RSS flow is falsely trying to release map
-		 * entry 0 - the offset subtraction will calculate the real
-		 * map index as an out-of-range value and the release operation
-		 * will be silently ignored.
-		 */
-		key = *key_idx - KEY_IDX_OFFSET;
-		if (key >= RTE_DIM(rss_keys))
-			break;
-
-		if (rss_keys[key] == KEY_STAT_USED) {
-			rss_keys[key] = KEY_STAT_AVAILABLE;
-			num_used_keys--;
-		}
-	break;
-
-	case KEY_CMD_INIT:
-		for (i = 0; i < RTE_DIM(rss_keys); i++)
-			rss_keys[i] = KEY_STAT_AVAILABLE;
-
-		rss_keys_initialized = 1;
-		num_used_keys = 0;
-	break;
-
-	case KEY_CMD_DEINIT:
-		for (i = 0; i < RTE_DIM(rss_keys); i++)
-			rss_keys[i] = KEY_STAT_UNSPEC;
-
-		rss_keys_initialized = 0;
-		num_used_keys = 0;
-	break;
-
-	default:
-		break;
-	}
-
-	return err;
-}
-
-/**
- * Add RSS hash calculations and queue selection
- *
- * @param[in, out] pmd
- *   Pointer to internal structure. Used to set/get RSS map fd
- *
- * @param[in] rss
- *   Pointer to RSS flow actions
- *
- * @param[out] error
- *   Pointer to error reporting if not NULL.
- *
- * @return 0 on success, negative value on failure
- */
-static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd,
-			   const struct rte_flow_action_rss *rss,
-			   struct rte_flow_error *error)
-{
-	/* 4096 is the maximum number of instructions for a BPF program */
-	unsigned int i;
-	int err;
-	struct rss_key rss_entry = { .hash_fields = 0,
-				     .key_size = 0 };
-
-	/* Check supported RSS features */
-	if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT)
-		return rte_flow_error_set
-			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-			 "non-default RSS hash functions are not supported");
-	if (rss->level)
-		return rte_flow_error_set
-			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-			 "a nonzero RSS encapsulation level is not supported");
-
-	/* Get a new map key for a new RSS rule */
-	err = bpf_rss_key(KEY_CMD_GET, &flow->key_idx);
-	if (err < 0) {
-		rte_flow_error_set(
-			error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
-			"Failed to get BPF RSS key");
-
-		return -1;
-	}
-
-	/* Update RSS map entry with queues */
-	rss_entry.nb_queues = rss->queue_num;
-	for (i = 0; i < rss->queue_num; i++)
-		rss_entry.queues[i] = rss->queue[i];
-	rss_entry.hash_fields =
-		(1 << HASH_FIELD_IPV4_L3_L4) | (1 << HASH_FIELD_IPV6_L3_L4);
-
-	/* Add this RSS entry to map */
-	err = tap_flow_bpf_update_rss_elem(pmd->map_fd,
-				&flow->key_idx, &rss_entry);
-
-	if (err) {
-		TAP_LOG(ERR,
-			"Failed to update BPF map entry #%u (%d): %s",
-			flow->key_idx, errno, strerror(errno));
-		rte_flow_error_set(
-			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
-			"Kernel too old or not configured "
-			"to support BPF maps updates");
-
-		return -ENOTSUP;
-	}
-
-
-	/*
-	 * Load bpf rules to calculate hash for this key_idx
-	 */
-
-	flow->bpf_fd[SEC_L3_L4] =
-		tap_flow_bpf_calc_l3_l4_hash(flow->key_idx, pmd->map_fd);
-	if (flow->bpf_fd[SEC_L3_L4] < 0) {
-		TAP_LOG(ERR,
-			"Failed to load BPF section %s (%d): %s",
-				sec_name[SEC_L3_L4], errno, strerror(errno));
-		rte_flow_error_set(
-			error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
-			"Kernel too old or not configured "
-			"to support BPF program loading");
-
-		return -ENOTSUP;
-	}
-
-	/* Actions */
-	{
-		struct action_data adata[] = {
-			{
-				.id = "bpf",
-				.bpf = {
-					.bpf_fd = flow->bpf_fd[SEC_L3_L4],
-					.annotation = sec_name[SEC_L3_L4],
-					.bpf = {
-						.action = TC_ACT_PIPE,
-					},
-				},
-			},
-		};
-
-		if (add_actions(flow, RTE_DIM(adata), adata,
-			TCA_FLOWER_ACT) < 0)
-			return -1;
-	}
-
-	return 0;
-}
-
 /**
  * Get rte_flow operations.
  *
diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
index 240fbc3dfaef..099704437b2f 100644
--- a/drivers/net/tap/tap_flow.h
+++ b/drivers/net/tap/tap_flow.h
@@ -41,11 +41,6 @@ enum implicit_rule_index {
 	TAP_REMOTE_MAX_IDX,
 };
 
-enum bpf_fd_idx {
-	SEC_L3_L4,
-	SEC_MAX,
-};
-
 int tap_dev_flow_ops_get(struct rte_eth_dev *dev,
 			 const struct rte_flow_ops **ops);
 int tap_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error);
@@ -56,11 +51,4 @@ int tap_flow_implicit_destroy(struct pmd_internals *pmd,
 			      enum implicit_rule_index idx);
 int tap_flow_implicit_flush(struct pmd_internals *pmd,
 			    struct rte_flow_error *error);
-
-int tap_flow_bpf_cls_q(__u32 queue_idx);
-int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
-int tap_flow_bpf_rss_map_create(unsigned int key_size, unsigned int value_size,
-			unsigned int max_entries);
-int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value);
-
 #endif /* _TAP_FLOW_H_ */
diff --git a/drivers/net/tap/tap_tcmsgs.h b/drivers/net/tap/tap_tcmsgs.h
index a64cb29d6fa8..4b0413579749 100644
--- a/drivers/net/tap/tap_tcmsgs.h
+++ b/drivers/net/tap/tap_tcmsgs.h
@@ -14,9 +14,6 @@
 #include <linux/tc_act/tc_mirred.h>
 #include <linux/tc_act/tc_gact.h>
 #include <linux/tc_act/tc_skbedit.h>
-#ifdef HAVE_TC_ACT_BPF
-#include <linux/tc_act/tc_bpf.h>
-#endif
 #include <inttypes.h>
 
 #include <rte_ether.h>
-- 
2.43.0


^ permalink raw reply	[relevance 1%]

* Re: [PATCH 1/2] eal: fix constraints on stdatomic API
  @ 2023-12-15  7:17  3%       ` Tyler Retzlaff
  0 siblings, 0 replies; 200+ results
From: Tyler Retzlaff @ 2023-12-15  7:17 UTC (permalink / raw)
  To: Jie Hai
  Cc: dev, Morten Brørup, Konstantin Ananyev, lihuisong,
	fengchengwen, liudongdong3

On Fri, Dec 15, 2023 at 10:47:36AM +0800, Jie Hai wrote:
> On 2023/12/12 2:53, Tyler Retzlaff wrote:
> >On Mon, Dec 11, 2023 at 03:39:03PM +0800, Jie Hai wrote:
> >>The first parameter of rte_atomic_exchange_explicit() must be a
> >>pointer to _Atomic type. If run command "meson setup --werror
> >>-Denable_stdatomic=true build && ninja -C build", error will occur.
> >>Thia patch fixes it.
> >>
> >>Fixes: 1ec6a845b5cb ("eal: use stdatomic API in public headers")
> >>Cc: stable@dpdk.org
> >>
> >>Signed-off-by: Jie Hai <haijie1@huawei.com>
> >>---
> >>  app/test/test_atomic.c               |  6 +++---
> >>  lib/eal/include/generic/rte_atomic.h | 12 ++++++------
> >>  2 files changed, 9 insertions(+), 9 deletions(-)
> >>
> >>diff --git a/app/test/test_atomic.c b/app/test/test_atomic.c
> >>index db07159e81ab..c3cb3ae0ea57 100644
> >>--- a/app/test/test_atomic.c
> >>+++ b/app/test/test_atomic.c
> >>@@ -347,9 +347,9 @@ typedef union {
> >>  const uint8_t CRC8_POLY = 0x91;
> >>  uint8_t crc8_table[256];
> >>-volatile uint16_t token16;
> >>-volatile uint32_t token32;
> >>-volatile uint64_t token64;
> >>+volatile RTE_ATOMIC(uint16_t) token16;
> >>+volatile RTE_ATOMIC(uint32_t) token32;
> >>+volatile RTE_ATOMIC(uint64_t) token64;
> >
> >subject to my comment below, volatile qualification can be removed.
> >
> >>  static void
> >>  build_crc8_table(void)
> >>diff --git a/lib/eal/include/generic/rte_atomic.h b/lib/eal/include/generic/rte_atomic.h
> >>index 0e639dad76a4..38c3b41f9c68 100644
> >>--- a/lib/eal/include/generic/rte_atomic.h
> >>+++ b/lib/eal/include/generic/rte_atomic.h
> >>@@ -207,11 +207,11 @@ rte_atomic16_cmpset(volatile uint16_t *dst, uint16_t exp, uint16_t src)
> >>   *   The original value at that location
> >>   */
> >>  static inline uint16_t
> >>-rte_atomic16_exchange(volatile uint16_t *dst, uint16_t val);
> >>+rte_atomic16_exchange(volatile RTE_ATOMIC(uint16_t) *dst, uint16_t val);
> >
> >the existing rte_atomicNN (the old non-standard ones) are deprecated and will
> >be eventually removed so there isn't a lot of value in churning their
> >signatures to wrap the rte_stdatomic macros.
> >
> >the right thing to do here to just change the calling code to use the generic
> >rte_stdatomic macros directly so we can eventually remove
> >rte_atomicNN_xxx.
> >
> >ty
> >
> Hi, Tyler Retzlaff,
> 
> Thank you for your review.
> 
> As I understand it, this code is used to test the API
> rte_atomXXX_change, and the call here should not be modified.
> 
> Since the current problem affects compilation, I think it can be
> solved first.

okay, i understand the motivation now and see what you mean.

first, sorry for the trouble i did not expect anyone to start using this
option until i had completed full conversion of the tree.  drivers and
tests are still on my todo list.

for now would it be reasonable to just stop building this test when
enable_stdatomic=true? the api are still going to be tested by the ci
and builds that do not enable the option.

as for changing the signatures of the existing api i don't strictly
object since the RTE_ATOMIC() macro expands empty for the non stdatomic
builds so isn't technically an api or abi change. but there may still be
some resistance to merging regardless.

wonder if anyone else has any suggestions here?

ty

> 
> What do you think?
> 
> Thanks,
> Jie Hai
> >.

^ permalink raw reply	[relevance 3%]

* [PATCH v5 1/3] net/octeon_ep: optimize Rx and Tx routines
  2023-12-07  6:49  3%   ` [PATCH v4 " pbhagavatula
@ 2023-12-11 13:43  3%     ` pbhagavatula
  0 siblings, 0 replies; 200+ results
From: pbhagavatula @ 2023-12-11 13:43 UTC (permalink / raw)
  To: jerinj, Vamsi Attunuru; +Cc: dev, Pavan Nikhilesh

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Preset rearm data to avoid writing multiple fields in fastpath,
Increase maximum outstanding Tx instructions from 128 to 256.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
v5 Changes:
- Make release notes more verbose.
v4 Changes:
- Fix checkpatch.
- Update release notes.
v3 Chnages:
- Add more comments to the code.
- Re-enable 32b build to prevent ABI break.
v2 Changes:
- Skip compiling for 32b x86 targets.

 doc/guides/rel_notes/release_24_03.rst |  5 +++++
 drivers/net/octeon_ep/cnxk_ep_rx.c     | 12 ++++++++----
 drivers/net/octeon_ep/otx_ep_common.h  |  3 +++
 drivers/net/octeon_ep/otx_ep_rxtx.c    | 27 ++++++++++++++++++++++++++
 drivers/net/octeon_ep/otx_ep_rxtx.h    |  2 +-
 5 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index 6f8ad27808..2265814c55 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -55,6 +55,11 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================

+* **Updated Marvell Octeon ep driver.**
+
+  * Optimize mbuf rearm sequence.
+  * Updated Tx queue mbuf free thresholds from 128 to 256 for better performance.
+

 Removed Items
 -------------
diff --git a/drivers/net/octeon_ep/cnxk_ep_rx.c b/drivers/net/octeon_ep/cnxk_ep_rx.c
index 74f0011283..75bb7225d2 100644
--- a/drivers/net/octeon_ep/cnxk_ep_rx.c
+++ b/drivers/net/octeon_ep/cnxk_ep_rx.c
@@ -93,7 +93,7 @@ cnxk_ep_check_rx_pkts(struct otx_ep_droq *droq)
 	new_pkts = val - droq->pkts_sent_ism_prev;
 	droq->pkts_sent_ism_prev = val;

-	if (val > (uint32_t)(1 << 31)) {
+	if (val > RTE_BIT32(31)) {
 		/* Only subtract the packet count in the HW counter
 		 * when count above halfway to saturation.
 		 */
@@ -128,7 +128,6 @@ cnxk_ep_process_pkts_scalar(struct rte_mbuf **rx_pkts, struct otx_ep_droq *droq,
 {
 	struct rte_mbuf **recv_buf_list = droq->recv_buf_list;
 	uint32_t bytes_rsvd = 0, read_idx = droq->read_idx;
-	uint16_t port_id = droq->otx_ep_dev->port_id;
 	uint16_t nb_desc = droq->nb_desc;
 	uint16_t pkts;

@@ -137,14 +136,19 @@ cnxk_ep_process_pkts_scalar(struct rte_mbuf **rx_pkts, struct otx_ep_droq *droq,
 		struct rte_mbuf *mbuf;
 		uint16_t pkt_len;

+		rte_prefetch0(recv_buf_list[otx_ep_incr_index(read_idx, 2, nb_desc)]);
+		rte_prefetch0(rte_pktmbuf_mtod(recv_buf_list[otx_ep_incr_index(read_idx,
+									       2, nb_desc)],
+			      void *));
+
 		mbuf = recv_buf_list[read_idx];
 		info = rte_pktmbuf_mtod(mbuf, struct otx_ep_droq_info *);
 		read_idx = otx_ep_incr_index(read_idx, 1, nb_desc);
 		pkt_len = rte_bswap16(info->length >> 48);
-		mbuf->data_off += OTX_EP_INFO_SIZE;
 		mbuf->pkt_len = pkt_len;
 		mbuf->data_len = pkt_len;
-		mbuf->port = port_id;
+
+		*(uint64_t *)&mbuf->rearm_data = droq->rearm_data;
 		rx_pkts[pkts] = mbuf;
 		bytes_rsvd += pkt_len;
 	}
diff --git a/drivers/net/octeon_ep/otx_ep_common.h b/drivers/net/octeon_ep/otx_ep_common.h
index 82e57520d3..299b5122d8 100644
--- a/drivers/net/octeon_ep/otx_ep_common.h
+++ b/drivers/net/octeon_ep/otx_ep_common.h
@@ -365,6 +365,9 @@ struct otx_ep_droq {
 	/* receive buffer list contains mbuf ptr list */
 	struct rte_mbuf **recv_buf_list;

+	/* Packet re-arm data. */
+	uint64_t rearm_data;
+
 	/* Packets pending to be processed */
 	uint64_t pkts_pending;

diff --git a/drivers/net/octeon_ep/otx_ep_rxtx.c b/drivers/net/octeon_ep/otx_ep_rxtx.c
index c421ef0a1c..40c4a16a38 100644
--- a/drivers/net/octeon_ep/otx_ep_rxtx.c
+++ b/drivers/net/octeon_ep/otx_ep_rxtx.c
@@ -284,6 +284,32 @@ otx_ep_droq_setup_ring_buffers(struct otx_ep_droq *droq)
 	return 0;
 }

+static inline uint64_t
+otx_ep_set_rearm_data(struct otx_ep_device *otx_ep)
+{
+	uint16_t port_id = otx_ep->port_id;
+	struct rte_mbuf mb_def;
+	uint64_t *tmp;
+
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_off) % 8 != 0);
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, refcnt) - offsetof(struct rte_mbuf, data_off) !=
+			 2);
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, nb_segs) - offsetof(struct rte_mbuf, data_off) !=
+			 4);
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, port) - offsetof(struct rte_mbuf, data_off) !=
+			 6);
+	mb_def.nb_segs = 1;
+	mb_def.data_off = RTE_PKTMBUF_HEADROOM + OTX_EP_INFO_SIZE;
+	mb_def.port = port_id;
+	rte_mbuf_refcnt_set(&mb_def, 1);
+
+	/* Prevent compiler reordering: rearm_data covers previous fields */
+	rte_compiler_barrier();
+	tmp = (uint64_t *)&mb_def.rearm_data;
+
+	return *tmp;
+}
+
 /* OQ initialization */
 static int
 otx_ep_init_droq(struct otx_ep_device *otx_ep, uint32_t q_no,
@@ -340,6 +366,7 @@ otx_ep_init_droq(struct otx_ep_device *otx_ep, uint32_t q_no,
 		goto init_droq_fail;

 	droq->refill_threshold = c_refill_threshold;
+	droq->rearm_data = otx_ep_set_rearm_data(otx_ep);

 	/* Set up OQ registers */
 	ret = otx_ep->fn_list.setup_oq_regs(otx_ep, q_no);
diff --git a/drivers/net/octeon_ep/otx_ep_rxtx.h b/drivers/net/octeon_ep/otx_ep_rxtx.h
index cb68ef3b41..b159c32cae 100644
--- a/drivers/net/octeon_ep/otx_ep_rxtx.h
+++ b/drivers/net/octeon_ep/otx_ep_rxtx.h
@@ -17,7 +17,7 @@

 #define OTX_EP_FSZ 28
 #define OTX2_EP_FSZ 24
-#define OTX_EP_MAX_INSTR 128
+#define OTX_EP_MAX_INSTR 256

 /* SDP_LENGTH_S specifies packet length and is of 8-byte size */
 #define OTX_EP_INFO_SIZE 8
--
2.25.1


^ permalink raw reply	[relevance 3%]

* [PATCH] bus/uacce: introduce UACCE bus
@ 2023-12-08  6:18  2% Chengwen Feng
  2024-01-15  8:14  0% ` lihuisong (C)
  2024-01-16  3:35  2% ` [PATCH v2] " Chengwen Feng
  0 siblings, 2 replies; 200+ results
From: Chengwen Feng @ 2023-12-08  6:18 UTC (permalink / raw)
  To: thomas, dev; +Cc: tangkunshan, fanghao11, wangzhou1

UACCE (Unified/User-space-access-intended Accelerator Framework) was
upstream to Linux kernel version 5.7, and it targets to provide Shared
Virtual Addressing (SVA) between accelerators and processes. So
accelerator can access any data structure of the main cpu. [1] for more
information.

This commit introduces UACCE bus, so that the accelerator devices could
seen at DPDK and could be further registered as a compress, crypto, dma
and ethdev device.

[1] https://docs.kernel.org/misc-devices/uacce.html

Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 MAINTAINERS                          |   4 +
 drivers/bus/meson.build              |   1 +
 drivers/bus/uacce/bus_uacce_driver.h | 254 ++++++++++
 drivers/bus/uacce/meson.build        |  12 +
 drivers/bus/uacce/uacce.c            | 702 +++++++++++++++++++++++++++
 drivers/bus/uacce/version.map        |  15 +
 6 files changed, 988 insertions(+)
 create mode 100644 drivers/bus/uacce/bus_uacce_driver.h
 create mode 100644 drivers/bus/uacce/meson.build
 create mode 100644 drivers/bus/uacce/uacce.c
 create mode 100644 drivers/bus/uacce/version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index 0d1c8126e3..89711029d5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -604,6 +604,10 @@ Platform bus driver
 M: Tomasz Duszynski <tduszynski@marvell.com>
 F: drivers/bus/platform/
 
+UACCE bus driver
+M: Chengwen Feng <fengchengwen@huawei.com>
+F: drivers/bus/uacce/
+
 VDEV bus driver
 F: drivers/bus/vdev/
 F: app/test/test_vdev.c
diff --git a/drivers/bus/meson.build b/drivers/bus/meson.build
index a78b4283bf..d67db8576b 100644
--- a/drivers/bus/meson.build
+++ b/drivers/bus/meson.build
@@ -9,6 +9,7 @@ drivers = [
         'ifpga',
         'pci',
         'platform',
+        'uacce',
         'vdev',
         'vmbus',
 ]
diff --git a/drivers/bus/uacce/bus_uacce_driver.h b/drivers/bus/uacce/bus_uacce_driver.h
new file mode 100644
index 0000000000..0276154658
--- /dev/null
+++ b/drivers/bus/uacce/bus_uacce_driver.h
@@ -0,0 +1,254 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 HiSilicon Limited
+ */
+
+#ifndef BUS_UACCE_DRIVER_H
+#define BUS_UACCE_DRIVER_H
+
+/**
+ * @file
+ *
+ * HiSilicon UACCE bus interface.
+ */
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <linux/types.h>
+
+#include <rte_compat.h>
+#include <rte_devargs.h>
+#include <dev_driver.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define RTE_UACCE_DEV_PATH_SIZE		256
+#define RTE_UACCE_API_NAME_SIZE		64
+#define RTE_UACCE_ALGS_NAME_SIZE	384
+#define RTE_UACCE_ATTR_MAX_SIZE		384
+
+/*
+ * Definition for queue file region type.
+ */
+enum rte_uacce_qfrt {
+	RTE_UACCE_QFRT_MMIO = 0, /**< Device mmio region. */
+	RTE_UACCE_QFRT_DUS,      /**< Device user share region. */
+	RTE_UACCE_QFRT_BUTT
+};
+
+struct rte_uacce_driver;
+
+/**
+ * A structure describing a UACCE device.
+ */
+struct rte_uacce_device {
+	RTE_TAILQ_ENTRY(rte_uacce_device) next;  /**< Next in device list. */
+	struct rte_device device;                /**< Inherit core device. */
+	struct rte_uacce_driver *driver;         /**< Driver used in probing. */
+	char name[RTE_DEV_NAME_MAX_LEN];         /**< Device name. */
+	char dev_root[RTE_UACCE_DEV_PATH_SIZE];  /**< Sysfs path with device name. */
+	char cdev_path[RTE_UACCE_DEV_PATH_SIZE]; /**< Device path in devfs. */
+	char api[RTE_UACCE_API_NAME_SIZE];       /**< Device context type. */
+	char algs[RTE_UACCE_ALGS_NAME_SIZE];     /**< Device supported algorithms. */
+	uint32_t flags;                          /**< Device flags. */
+	int numa_node;                           /**< NUMA node connection, -1 if unknown. */
+	uint32_t qfrt_sz[RTE_UACCE_QFRT_BUTT];   /**< Queue file region type's size. */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_uacce_device.
+ */
+#define RTE_DEV_TO_UACCE_DEV(ptr) \
+	container_of(ptr, struct rte_uacce_device, device)
+
+#define RTE_DEV_TO_UACCE_DEV_CONST(ptr) \
+	container_of(ptr, const struct rte_uacce_device, device)
+
+/**
+ * A structure describing an ID for a UACCE driver. Each driver provides a
+ * table of these IDs for each device that it supports.
+ */
+struct rte_uacce_id {
+	const char *dev_api;   /**< Device context type. */
+	/** Device algorithm.
+	 * If this field is NULL, only dev_api is matched. Otherwise, in
+	 * addition to match dev_api, dev_alg must be a subset of device's
+	 * algs.
+	 */
+	const char *dev_alg;
+};
+
+/**
+ * Initialization function for the driver called during probing.
+ */
+typedef int (rte_uacce_probe_t)(struct rte_uacce_driver *, struct rte_uacce_device *);
+
+/**
+ * Uninitialization function for the driver called during hotplugging.
+ */
+typedef int (rte_uacce_remove_t)(struct rte_uacce_device *);
+
+/**
+ * A structure describing a UACCE driver.
+ */
+struct rte_uacce_driver {
+	RTE_TAILQ_ENTRY(rte_uacce_driver) next;	/**< Next in list. */
+	struct rte_driver driver;               /**< Inherit core driver. */
+	struct rte_uacce_bus *bus;              /**< UACCE bus reference. */
+	rte_uacce_probe_t *probe;               /**< Device probe function. */
+	rte_uacce_remove_t *remove;             /**< Device remove function. */
+	const struct rte_uacce_id *id_table;    /**< ID table, NULL terminated. */
+};
+
+/**
+ * Get available queue number.
+ *
+ * @param dev
+ *   A pointer to a rte_uacce_device structure describing the device
+ *   to use.
+ *
+ * @note The available queues on the device may changes dynamically,
+ * for examples, other process may alloc or free queues.
+ *
+ * @return
+ *   0 on success. Otherwise negative value is returned.
+ */
+__rte_internal
+int rte_uacce_avail_queues(struct rte_uacce_device *dev);
+
+/*
+ * The queue context for a UACCE queue.
+ */
+struct rte_uacce_qcontex {
+	int fd;                       /**< The file descriptor associated to the queue. */
+	struct rte_uacce_device *dev; /**< The device associated to the queue. */
+	void *qfrt_base[RTE_UACCE_QFRT_BUTT]; /**< The qfrt mmap's memory base. */
+};
+
+/**
+ * Alloc one queue.
+ *
+ * @param dev
+ *   A pointer to a rte_uacce_device structure describing the device to use.
+ * @param qctx
+ *   Pointer to queue context, which is used to store the queue information
+ *   that is successfully applied for.
+ *
+ * @return
+ *   0 on success. Otherwise negative value is returned.
+ */
+__rte_internal
+int rte_uacce_queue_alloc(struct rte_uacce_device *dev, struct rte_uacce_qcontex *qctx);
+
+/**
+ * Free one queue.
+ *
+ * @param qctx
+ *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
+ *
+ * @note Once the queue is freed, any operations on the queue (including
+ * control-plane and data-plane, and also read & write mmap region) are not
+ * allowed.
+ */
+__rte_internal
+void rte_uacce_queue_free(struct rte_uacce_qcontex *qctx);
+
+/**
+ * Start one queue.
+ *
+ * @param qctx
+ *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
+ *
+ * @return
+ *   0 on success. Otherwise negative value is returned.
+ */
+__rte_internal
+int rte_uacce_queue_start(struct rte_uacce_qcontex *qctx);
+
+/**
+ * Send ioctl command to one queue.
+ *
+ * @param qctx
+ *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
+ * @param cmd
+ *   ioctl command.
+ *   @note The nr must not conflict with the definition in Linux kerel:
+ *   include/uapi/misc/uacce/uacce.h. It is recommended that the driver
+ *   custom nr start from 64.
+ * @param arg
+ *   Command input & output buffer.
+ *
+ * @return
+ *   0 on success. Otherwise negative value is returned.
+ */
+__rte_internal
+int rte_uacce_queue_ioctl(struct rte_uacce_qcontex *qctx, unsigned long cmd, void *arg);
+
+/**
+ * Mmap queue file region.
+ *
+ * @param qctx
+ *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
+ * @param qfrt
+ *   The queue file region type. Must be RTE_UACCE_QFRT_MMIO or
+ *   RTE_UACCE_QFRT_DUS.
+ *
+ * @return
+ *   Non-NULL on success. Otherwise NULL is returned.
+ */
+__rte_internal
+void *rte_uacce_queue_mmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt);
+
+/**
+ * Unmap queue file region.
+ *
+ * @param qctx
+ *   Pointer to queue context, which allocated by @see rte_uacce_alloc_queue.
+ * @param qfrt
+ *   The queue file region type. Must be RTE_UACCE_QFRT_MMIO or
+ *   RTE_UACCE_QFRT_DUS.
+ *
+ * @return
+ *   Non-NULL on success. Otherwise NULL is returned.
+ */
+__rte_internal
+void rte_uacce_queue_unmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt);
+
+/**
+ * Register a UACCE driver.
+ *
+ * @param driver
+ *   A pointer to a rte_uacce_driver structure describing the driver to be
+ *   registered.
+ */
+__rte_internal
+void rte_uacce_register(struct rte_uacce_driver *driver);
+
+/**
+ * Unregister a UACCE driver.
+ *
+ * @param driver
+ *   A pointer to a rte_uacce_driver structure describing the driver to be
+ *   unregistered.
+ */
+__rte_internal
+void rte_uacce_unregister(struct rte_uacce_driver *driver);
+
+/**
+ * Helper for UACCE device registration from driver instance.
+ */
+#define RTE_PMD_REGISTER_UACCE(nm, uacce_drv) \
+		RTE_INIT(uacceinitfn_ ##nm) \
+		{\
+			(uacce_drv).driver.name = RTE_STR(nm);\
+			rte_uacce_register(&uacce_drv); \
+		} \
+		RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* BUS_UACCE_DRIVER_H */
diff --git a/drivers/bus/uacce/meson.build b/drivers/bus/uacce/meson.build
new file mode 100644
index 0000000000..b48d6db11a
--- /dev/null
+++ b/drivers/bus/uacce/meson.build
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2023 HiSilicon Limited.
+
+if not is_linux
+    build = false
+    reason = 'only supported on Linux'
+endif
+
+sources = files('uacce.c')
+driver_sdk_headers += files('bus_uacce_driver.h')
+
+deps += ['kvargs']
diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
new file mode 100644
index 0000000000..8e824c44df
--- /dev/null
+++ b/drivers/bus/uacce/uacce.c
@@ -0,0 +1,702 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 HiSilicon Limited
+ */
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <rte_bitops.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_errno.h>
+#include <rte_log.h>
+#include <rte_kvargs.h>
+#include <bus_driver.h>
+
+#include "bus_uacce_driver.h"
+
+#define UACCE_BUS_CLASS_PATH	"/sys/class/uacce"
+
+/* UACCE device flag of SVA. */
+#define UACCE_DEV_FLGA_SVA	RTE_BIT32(0)
+
+/* Support -a uacce:device-name when start DPDK application. */
+#define UACCE_DEV_PREFIX	"uacce:"
+
+/*
+ * Structure describing the UACCE bus.
+ */
+struct rte_uacce_bus {
+	struct rte_bus bus;		            /* Inherit the generic class. */
+	TAILQ_HEAD(, rte_uacce_device) device_list; /* List of devices. */
+	TAILQ_HEAD(, rte_uacce_driver) driver_list; /* List of drivers. */
+};
+
+/* Forward declaration of UACCE bus. */
+static struct rte_uacce_bus uacce_bus;
+
+enum uacce_params {
+	RTE_UACCE_PARAM_NAME,
+};
+
+static const char *const uacce_params_keys[] = {
+	[RTE_UACCE_PARAM_NAME] = "name",
+	NULL,
+};
+
+#define FOREACH_DEVICE_ON_UACCEBUS(p)	\
+		RTE_TAILQ_FOREACH(p, &uacce_bus.device_list, next)
+#define FOREACH_DRIVER_ON_UACCEBUS(p)	\
+		RTE_TAILQ_FOREACH(p, &uacce_bus.driver_list, next)
+
+extern int uacce_bus_logtype;
+#define UACCE_BUS_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, uacce_bus_logtype, "uacce: " fmt "\n", \
+		##args)
+#define UACCE_BUS_ERR(fmt, args...) UACCE_BUS_LOG(ERR, fmt, ##args)
+#define UACCE_BUS_WARN(fmt, args...) UACCE_BUS_LOG(WARNING, fmt, ##args)
+#define UACCE_BUS_INFO(fmt, args...) UACCE_BUS_LOG(INFO, fmt, ##args)
+#define UACCE_BUS_DEBUG(fmt, args...) UACCE_BUS_LOG(DEBUG, fmt, ##args)
+
+
+static struct rte_devargs *
+uacce_devargs_lookup(const char *dev_name)
+{
+	char name[RTE_UACCE_DEV_PATH_SIZE] = {0};
+	struct rte_devargs *devargs;
+
+	snprintf(name, sizeof(name), "%s%s", UACCE_DEV_PREFIX, dev_name);
+	RTE_EAL_DEVARGS_FOREACH("uacce", devargs) {
+		if (strcmp(devargs->name, name) == 0)
+			return devargs;
+	}
+
+	return NULL;
+}
+
+static bool
+uacce_ignore_device(const char *dev_name)
+{
+	struct rte_devargs *devargs = uacce_devargs_lookup(dev_name);
+
+	switch (uacce_bus.bus.conf.scan_mode) {
+	case RTE_BUS_SCAN_ALLOWLIST:
+		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
+			return false;
+		break;
+	case RTE_BUS_SCAN_UNDEFINED:
+	case RTE_BUS_SCAN_BLOCKLIST:
+		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
+			return false;
+		break;
+	}
+
+	return true;
+}
+
+/*
+ * Returns the number of bytes read (removed last newline) on success.
+ * Otherwise negative value is returned.
+ */
+static int
+uacce_read_attr(const char *dev_root, const char *attr, char *buf, uint32_t sz)
+{
+	char filename[PATH_MAX] = {0};
+	int ret;
+	int fd;
+	int i;
+
+	snprintf(filename, sizeof(filename), "%s/%s", dev_root, attr);
+	fd = open(filename, O_RDONLY, 0);
+	if (fd < 0) {
+		UACCE_BUS_ERR("failed to open %s", filename);
+		return -EIO;
+	}
+
+	ret = read(fd, buf, sz);
+	if (ret > 0) {
+		/* Remove the last new line character. */
+		for (i = ret - 1; i >= 0; i--) {
+			if (buf[i] == '\n') {
+				buf[i] = '\0';
+				ret--;
+				break;
+			}
+		}
+	}
+	if (ret <= 0) {
+		UACCE_BUS_ERR("failed to read %s", filename);
+		return -EIO;
+	}
+
+	close(fd);
+
+	return ret;
+}
+
+/* 0 on success. Otherwise negative value is returned. */
+static int
+uacce_read_attr_int(const char *dev_root, const char *attr, int *val)
+{
+	char buf[RTE_UACCE_ATTR_MAX_SIZE] = {0};
+	char *s = NULL;
+	int ret;
+
+	ret = uacce_read_attr(dev_root, attr, buf, sizeof(buf) - 1);
+	if (ret < 0)
+		return ret;
+
+	*val = strtol(buf, &s, 0);
+	if (s[0] != '\0') {
+		UACCE_BUS_ERR("read attr %s/%s expect an integer value", dev_root, attr);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* 0 on success. Otherwise negative value is returned. */
+static int
+uacce_read_attr_u32(const char *dev_root, const char *attr, uint32_t *val)
+{
+	char buf[RTE_UACCE_ATTR_MAX_SIZE] = {0};
+	char *s = NULL;
+	int ret;
+
+	ret = uacce_read_attr(dev_root, attr, buf, sizeof(buf) - 1);
+	if (ret < 0)
+		return ret;
+
+	*val = strtoul(buf, &s, 0);
+	if (s[0] != '\0') {
+		UACCE_BUS_ERR("read attr %s/%s expect an uint32 value", dev_root, attr);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+uacce_read_api(struct rte_uacce_device *dev)
+{
+	int ret = uacce_read_attr(dev->dev_root, "api", dev->api, sizeof(dev->api) - 1);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int
+uacce_read_algs(struct rte_uacce_device *dev)
+{
+	int ret = uacce_read_attr(dev->dev_root, "algorithms", dev->algs, sizeof(dev->algs) - 1);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int
+uacce_read_flags(struct rte_uacce_device *dev)
+{
+	return uacce_read_attr_u32(dev->dev_root, "flags", &dev->flags);
+}
+
+static void
+uacce_read_numa_node(struct rte_uacce_device *dev)
+{
+	int ret = uacce_read_attr_int(dev->dev_root, "device/numa_node", &dev->numa_node);
+	if (ret != 0) {
+		UACCE_BUS_WARN("read attr numa_node failed! set to default");
+		dev->numa_node = -1;
+	}
+}
+
+static int
+uacce_read_qfrt_sz(struct rte_uacce_device *dev)
+{
+	int ret = uacce_read_attr_u32(dev->dev_root, "region_mmio_size",
+				      &dev->qfrt_sz[RTE_UACCE_QFRT_MMIO]);
+	if (ret != 0)
+		return ret;
+	return uacce_read_attr_u32(dev->dev_root, "region_dus_size",
+				   &dev->qfrt_sz[RTE_UACCE_QFRT_DUS]);
+}
+
+static int
+uacce_verify(struct rte_uacce_device *dev)
+{
+	if (!(dev->flags & UACCE_DEV_FLGA_SVA)) {
+		UACCE_BUS_WARN("device %s don't support SVA, skip it!", dev->name);
+		return 1; /* >0 will skip this device. */
+	}
+
+	return 0;
+}
+
+/*
+ * Scan one UACCE sysfs entry, and fill the devices list from it.
+ * It reads api/algs/flags/numa_node/region-size (please refer Linux kernel:
+ * Documentation/ABI/testing/sysfs-driver-uacce) and stores them for later
+ * device-driver matching, driver init...
+ */
+static int
+uacce_scan_one(const char *dev_name)
+{
+	struct rte_uacce_device *dev = NULL;
+	int ret;
+
+	dev = calloc(1, sizeof(*dev));
+	if (!dev)
+		return -ENOMEM;
+
+	dev->device.bus = &uacce_bus.bus;
+	dev->device.name = dev->name;
+	dev->device.devargs = uacce_devargs_lookup(dev_name);
+	snprintf(dev->name, sizeof(dev->name), "%s", dev_name);
+	snprintf(dev->dev_root, sizeof(dev->dev_root), "%s/%s",
+		 UACCE_BUS_CLASS_PATH, dev_name);
+	snprintf(dev->cdev_path, sizeof(dev->cdev_path), "/dev/%s", dev_name);
+
+	ret = uacce_read_api(dev);
+	if (ret != 0)
+		goto err;
+	ret = uacce_read_algs(dev);
+	if (ret != 0)
+		goto err;
+	ret = uacce_read_flags(dev);
+	if (ret != 0)
+		goto err;
+	uacce_read_numa_node(dev);
+	ret = uacce_read_qfrt_sz(dev);
+	if (ret != 0)
+		goto err;
+
+	ret = uacce_verify(dev);
+	if (ret != 0)
+		goto err;
+
+	TAILQ_INSERT_TAIL(&uacce_bus.device_list, dev, next);
+	return 0;
+
+err:
+	free(dev);
+	return ret;
+}
+
+static int
+uacce_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+
+	dir = opendir(UACCE_BUS_CLASS_PATH);
+	if (dir == NULL) {
+		UACCE_BUS_LOG(INFO, "open %s failed!", UACCE_BUS_CLASS_PATH);
+		return 0;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		if (strlen(e->d_name) >= RTE_DEV_NAME_MAX_LEN) {
+			UACCE_BUS_LOG(WARNING, "uacce device name %s too long, skip it!",
+				      e->d_name);
+			continue;
+		}
+
+		if (uacce_ignore_device(e->d_name))
+			continue;
+
+		if (uacce_scan_one(e->d_name) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
+static bool
+uacce_match(const struct rte_uacce_driver *dr, const struct rte_uacce_device *dev)
+{
+	const struct rte_uacce_id *id_table;
+	uint32_t len;
+	char *map;
+
+	for (id_table = dr->id_table; id_table->dev_api != NULL; id_table++) {
+		if (strcmp(id_table->dev_api, dev->api) != 0)
+			continue;
+
+		if (id_table->dev_alg == NULL)
+			return 1;
+
+		/* The dev->algs's algrothims is separated by new line, for
+		 * example: dev->algs could be: aaa\nbbbb\ncc, which has three
+		 * algorithms: aaa, bbbb and cc.
+		 * The id_table->dev_alg should be a single algrithm, e.g. bbbb.
+		 */
+		map = strstr(dev->algs, id_table->dev_alg);
+		if (map == NULL)
+			continue;
+		if (map != dev->algs && map[-1] != '\n')
+			continue;
+		len = strlen(id_table->dev_alg);
+		if (map[len] != '\0' && map[len] != '\n')
+			continue;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+static int
+uacce_probe_one_driver(struct rte_uacce_driver *dr, struct rte_uacce_device *dev)
+{
+	const char *dev_name = dev->name;
+	bool already_probed;
+	int ret;
+
+	if (!uacce_match(dr, dev))
+		/* Match of device and driver failed */
+		return 1;
+
+	already_probed = rte_dev_is_probed(&dev->device);
+	if (already_probed) {
+		UACCE_BUS_INFO("device %s is already probed", dev_name);
+		return -EEXIST;
+	}
+
+	UACCE_BUS_DEBUG("probe device %s using driver %s", dev_name, dr->driver.name);
+
+	ret = dr->probe(dr, dev);
+	if (ret != 0) {
+		UACCE_BUS_ERR("probe device %s with driver %s failed %d",
+			      dev_name, dr->driver.name, ret);
+	} else {
+		dev->device.driver = &dr->driver;
+		dev->driver = dr;
+		UACCE_BUS_DEBUG("probe device %s with driver %s success",
+				dev_name, dr->driver.name);
+	}
+
+	return ret;
+}
+
+static int
+uacce_probe_all_drivers(struct rte_uacce_device *dev)
+{
+	struct rte_uacce_driver *dr = NULL;
+	int rc = 0;
+
+	FOREACH_DRIVER_ON_UACCEBUS(dr) {
+		rc = uacce_probe_one_driver(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return rc;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+static int
+uacce_probe(void)
+{
+	struct rte_uacce_device *dev = NULL;
+	size_t probed = 0, failed = 0;
+	int ret = 0;
+
+	FOREACH_DEVICE_ON_UACCEBUS(dev) {
+		probed++;
+
+		ret = uacce_probe_all_drivers(dev);
+		if (ret < 0) {
+			UACCE_BUS_LOG(ERR, "Requested device %s cannot be used",
+				dev->name);
+			rte_errno = errno;
+			failed++;
+		}
+	}
+
+	return (probed && probed == failed) ? -1 : 0;
+}
+
+static int
+uacce_cleanup(void)
+{
+	struct rte_uacce_device *dev, *tmp_dev;
+	int error = 0;
+
+	RTE_TAILQ_FOREACH_SAFE(dev, &uacce_bus.device_list, next, tmp_dev) {
+		struct rte_uacce_driver *dr = dev->driver;
+		int ret = 0;
+
+		if (dr == NULL || dr->remove == NULL)
+			goto free;
+
+		ret = dr->remove(dev);
+		if (ret < 0) {
+			rte_errno = errno;
+			error = -1;
+		}
+		dev->driver = NULL;
+		dev->device.driver = NULL;
+
+free:
+		memset(dev, 0, sizeof(*dev));
+		free(dev);
+	}
+
+	return error;
+}
+
+static int
+uacce_plug(struct rte_device *dev)
+{
+	return uacce_probe_all_drivers(RTE_DEV_TO_UACCE_DEV(dev));
+}
+
+static int
+uacce_detach_dev(struct rte_uacce_device *dev)
+{
+	struct rte_uacce_driver *dr;
+	int ret = 0;
+
+	dr = dev->driver;
+
+	UACCE_BUS_DEBUG("detach device %s using driver: %s", dev->device.name, dr->driver.name);
+
+	if (dr->remove) {
+		ret = dr->remove(dev);
+		if (ret < 0)
+			return ret;
+	}
+
+	dev->driver = NULL;
+	dev->device.driver = NULL;
+
+	return 0;
+}
+
+static int
+uacce_unplug(struct rte_device *dev)
+{
+	struct rte_uacce_device *uacce_dev;
+	int ret;
+
+	uacce_dev = RTE_DEV_TO_UACCE_DEV(dev);
+	ret = uacce_detach_dev(uacce_dev);
+	if (ret == 0) {
+		TAILQ_REMOVE(&uacce_bus.device_list, uacce_dev, next);
+		rte_devargs_remove(dev->devargs);
+		free(uacce_dev);
+	}
+
+	return ret;
+}
+
+static struct rte_device *
+uacce_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,  const void *data)
+{
+	const struct rte_uacce_device *uacce_start;
+	struct rte_uacce_device *uacce_dev;
+
+	if (start != NULL) {
+		uacce_start = RTE_DEV_TO_UACCE_DEV_CONST(start);
+		uacce_dev = TAILQ_NEXT(uacce_start, next);
+	} else {
+		uacce_dev = TAILQ_FIRST(&uacce_bus.device_list);
+	}
+
+	while (uacce_dev != NULL) {
+		if (cmp(&uacce_dev->device, data) == 0)
+			return &uacce_dev->device;
+		uacce_dev = TAILQ_NEXT(uacce_dev, next);
+	}
+
+	return NULL;
+}
+
+static int
+uacce_parse(const char *name, void *addr)
+{
+	const char **out = addr;
+	int ret;
+
+	ret = strncmp(name, UACCE_DEV_PREFIX, strlen(UACCE_DEV_PREFIX));
+
+	if (ret == 0 && addr)
+		*out = name;
+
+	return ret;
+}
+
+static int
+uacce_dev_match(const struct rte_device *dev, const void *_kvlist)
+{
+	const char *key = uacce_params_keys[RTE_UACCE_PARAM_NAME];
+	const struct rte_kvargs *kvlist = _kvlist;
+	const char *name;
+
+	/* no kvlist arg, all devices match. */
+	if (kvlist == NULL)
+		return 0;
+
+	/* if key is present in kvlist and does not match, filter device. */
+	name = rte_kvargs_get(kvlist, key);
+	if (name != NULL && strcmp(name, dev->name))
+		return -1;
+
+	return 0;
+}
+
+static void *
+uacce_dev_iterate(const void *start, const char *str,
+		  const struct rte_dev_iterator *it __rte_unused)
+{
+	rte_bus_find_device_t find_device;
+	struct rte_kvargs *kvargs = NULL;
+	struct rte_device *dev;
+
+	if (str != NULL) {
+		kvargs = rte_kvargs_parse(str, uacce_params_keys);
+		if (kvargs == NULL) {
+			UACCE_BUS_ERR("cannot parse argument list %s", str);
+			return NULL;
+		}
+	}
+	find_device = uacce_bus.bus.find_device;
+	dev = find_device(start, uacce_dev_match, kvargs);
+	rte_kvargs_free(kvargs);
+	return dev;
+}
+
+int
+rte_uacce_avail_queues(struct rte_uacce_device *dev)
+{
+	int avails = 0;
+	int ret;
+
+	ret = uacce_read_attr_int(dev->dev_root, "available_instances", &avails);
+	if (ret == 0)
+		ret = avails;
+
+	return ret;
+}
+
+int
+rte_uacce_queue_alloc(struct rte_uacce_device *dev, struct rte_uacce_qcontex *qctx)
+{
+	memset(qctx, 0, sizeof(*qctx));
+
+	qctx->fd = open(dev->cdev_path, O_RDWR | O_CLOEXEC);
+	if (qctx->fd >= 0) {
+		qctx->dev = dev;
+		return 0;
+	}
+
+	return -EIO;
+}
+
+void
+rte_uacce_queue_free(struct rte_uacce_qcontex *qctx)
+{
+	if (qctx->fd >= 0)
+		close(qctx->fd);
+	memset(qctx, 0, sizeof(*qctx));
+	qctx->fd = -1;
+}
+
+int
+rte_uacce_queue_start(struct rte_uacce_qcontex *qctx)
+{
+#define UACCE_CMD_START_Q	_IO('W', 0)
+	return ioctl(qctx->fd, UACCE_CMD_START_Q);
+}
+
+int
+rte_uacce_queue_ioctl(struct rte_uacce_qcontex *qctx, unsigned long cmd, void *arg)
+{
+	if (arg == NULL)
+		return ioctl(qctx->fd, cmd);
+
+	return ioctl(qctx->fd, cmd, arg);
+}
+
+void *
+rte_uacce_queue_mmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt)
+{
+	size_t size = qctx->dev->qfrt_sz[qfrt];
+	off_t off = qfrt * getpagesize();
+	void *addr;
+
+	if (size == 0 || qctx->qfrt_base[qfrt] != NULL) {
+		UACCE_BUS_ERR("failed to mmap for %s, size is zero or already mmapped!",
+			      qctx->dev->name);
+		return NULL;
+	}
+
+	addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, qctx->fd, off);
+	if (addr == MAP_FAILED) {
+		UACCE_BUS_ERR("failed to mmap for %s, qfrt %d err %d!",
+			      qctx->dev->name, qfrt, -errno);
+		return NULL;
+	}
+	qctx->qfrt_base[qfrt] = addr;
+
+	return addr;
+}
+
+void
+rte_uacce_queue_unmap(struct rte_uacce_qcontex *qctx, enum rte_uacce_qfrt qfrt)
+{
+	if (qctx->qfrt_base[qfrt] != NULL) {
+		munmap(qctx->qfrt_base[qfrt], qctx->dev->qfrt_sz[qfrt]);
+		qctx->qfrt_base[qfrt] = NULL;
+	}
+}
+
+void
+rte_uacce_register(struct rte_uacce_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&uacce_bus.driver_list, driver, next);
+	driver->bus = &uacce_bus;
+}
+
+void
+rte_uacce_unregister(struct rte_uacce_driver *driver)
+{
+	TAILQ_REMOVE(&uacce_bus.driver_list, driver, next);
+	driver->bus = NULL;
+}
+
+static struct rte_uacce_bus uacce_bus = {
+	.bus = {
+		.scan = uacce_scan,
+		.probe = uacce_probe,
+		.cleanup = uacce_cleanup,
+		.plug = uacce_plug,
+		.unplug = uacce_unplug,
+		.find_device = uacce_find_device,
+		.parse = uacce_parse,
+		.dev_iterate = uacce_dev_iterate,
+	},
+	.device_list = TAILQ_HEAD_INITIALIZER(uacce_bus.device_list),
+	.driver_list = TAILQ_HEAD_INITIALIZER(uacce_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(uacce, uacce_bus.bus);
+RTE_LOG_REGISTER_DEFAULT(uacce_bus_logtype, NOTICE);
diff --git a/drivers/bus/uacce/version.map b/drivers/bus/uacce/version.map
new file mode 100644
index 0000000000..533b2ea0d8
--- /dev/null
+++ b/drivers/bus/uacce/version.map
@@ -0,0 +1,15 @@
+INTERNAL {
+	global:
+
+	rte_uacce_avail_queues;
+	rte_uacce_queue_alloc;
+	rte_uacce_queue_free;
+	rte_uacce_queue_ioctl;
+	rte_uacce_queue_mmap;
+	rte_uacce_queue_start;
+	rte_uacce_queue_unmap;
+	rte_uacce_register;
+	rte_uacce_unregister;
+
+	local: *;
+};
-- 
2.17.1


^ permalink raw reply	[relevance 2%]

* Re: [PATCH RESEND v6 0/5] app/testpmd: support multiple process attach and detach port
  @ 2023-12-08  2:25  0%       ` lihuisong (C)
  0 siblings, 0 replies; 200+ results
From: lihuisong (C) @ 2023-12-08  2:25 UTC (permalink / raw)
  To: thomas, ferruh.yigit
  Cc: andrew.rybchenko, fengchengwen, liudongdong3, liuyonglong, dev

Hi Ferruh and Thomas,

This series have been discussing for over a year and a half.
Looking back on previous discussions, we have also made some progress 
and consensus.
I am sticking to track it. Because they resolve a real exist issue.
Can you take a look at it again?

BR,
/Huisong


在 2023/10/30 20:17, lihuisong (C) 写道:
> Hi Ferruh and Thomas,
>
> This series have been discussing more than one year.
> Kindly ping for reivew.
>
>
> 在 2023/10/9 18:34, lihuisong (C) 写道:
>> Hi Ferruh and Thomas,
>>
>> Can you take a look at this series? They've been over a year on 
>> disscussion.
>>
>>
>> 在 2023/8/2 11:15, Huisong Li 写道:
>>> This patchset fix some bugs and support attaching and detaching port
>>> in primary and secondary.
>>>
>>> ---
>>>   -v6: adjust rte_eth_dev_is_used position based on alphabetical order
>>>        in version.map
>>>   -v5: move 'ALLOCATED' state to the back of 'REMOVED' to avoid abi 
>>> break.
>>>   -v4: fix a misspelling.
>>>   -v3:
>>>     #1 merge patch 1/6 and patch 2/6 into patch 1/5, and add 
>>> modification
>>>        for other bus type.
>>>     #2 add a RTE_ETH_DEV_ALLOCATED state in rte_eth_dev_state to 
>>> resolve
>>>        the probelm in patch 2/5.
>>>   -v2: resend due to CI unexplained failure.
>>>
>>> Huisong Li (5):
>>>    drivers/bus: restore driver assignment at front of probing
>>>    ethdev: fix skip valid port in probing callback
>>>    app/testpmd: check the validity of the port
>>>    app/testpmd: add attach and detach port for multiple process
>>>    app/testpmd: stop forwarding in new or destroy event
>>>
>>>   app/test-pmd/testpmd.c                   | 47 
>>> +++++++++++++++---------
>>>   app/test-pmd/testpmd.h                   |  1 -
>>>   drivers/bus/auxiliary/auxiliary_common.c |  9 ++++-
>>>   drivers/bus/dpaa/dpaa_bus.c              |  9 ++++-
>>>   drivers/bus/fslmc/fslmc_bus.c            |  8 +++-
>>>   drivers/bus/ifpga/ifpga_bus.c            | 12 ++++--
>>>   drivers/bus/pci/pci_common.c             |  9 ++++-
>>>   drivers/bus/vdev/vdev.c                  | 10 ++++-
>>>   drivers/bus/vmbus/vmbus_common.c         |  9 ++++-
>>>   drivers/net/bnxt/bnxt_ethdev.c           |  3 +-
>>>   drivers/net/bonding/bonding_testpmd.c    |  1 -
>>>   drivers/net/mlx5/mlx5.c                  |  2 +-
>>>   lib/ethdev/ethdev_driver.c               | 13 +++++--
>>>   lib/ethdev/ethdev_driver.h               | 12 ++++++
>>>   lib/ethdev/ethdev_pci.h                  |  2 +-
>>>   lib/ethdev/rte_class_eth.c               |  2 +-
>>>   lib/ethdev/rte_ethdev.c                  |  4 +-
>>>   lib/ethdev/rte_ethdev.h                  |  4 +-
>>>   lib/ethdev/version.map                   |  1 +
>>>   19 files changed, 114 insertions(+), 44 deletions(-)
>>>
>>
>> .
>
> .

^ permalink raw reply	[relevance 0%]

* [PATCH v4 1/3] net/octeon_ep: optimize Rx and Tx routines
  2023-12-06 17:24  3% ` [PATCH v3 " pbhagavatula
@ 2023-12-07  6:49  3%   ` pbhagavatula
  2023-12-11 13:43  3%     ` [PATCH v5 " pbhagavatula
  0 siblings, 1 reply; 200+ results
From: pbhagavatula @ 2023-12-07  6:49 UTC (permalink / raw)
  To: jerinj, Vamsi Attunuru; +Cc: dev, Pavan Nikhilesh

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Preset rearm data to avoid writing multiple fields in fastpath,
Increase maximum outstanding Tx instructions from 128 to 256.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
v4 Changes:
- Fix checkpatch.
- Update release notes.
v3 Chnages:
- Add more comments to the code.
- Re-enable 32b build to prevent ABI break.
v2 Changes:
- Skip compiling for 32b x86 targets.

 drivers/net/octeon_ep/cnxk_ep_rx.c    | 12 ++++++++----
 drivers/net/octeon_ep/otx_ep_common.h |  3 +++
 drivers/net/octeon_ep/otx_ep_rxtx.c   | 27 +++++++++++++++++++++++++++
 drivers/net/octeon_ep/otx_ep_rxtx.h   |  2 +-
 4 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/net/octeon_ep/cnxk_ep_rx.c b/drivers/net/octeon_ep/cnxk_ep_rx.c
index 74f0011283..75bb7225d2 100644
--- a/drivers/net/octeon_ep/cnxk_ep_rx.c
+++ b/drivers/net/octeon_ep/cnxk_ep_rx.c
@@ -93,7 +93,7 @@ cnxk_ep_check_rx_pkts(struct otx_ep_droq *droq)
 	new_pkts = val - droq->pkts_sent_ism_prev;
 	droq->pkts_sent_ism_prev = val;

-	if (val > (uint32_t)(1 << 31)) {
+	if (val > RTE_BIT32(31)) {
 		/* Only subtract the packet count in the HW counter
 		 * when count above halfway to saturation.
 		 */
@@ -128,7 +128,6 @@ cnxk_ep_process_pkts_scalar(struct rte_mbuf **rx_pkts, struct otx_ep_droq *droq,
 {
 	struct rte_mbuf **recv_buf_list = droq->recv_buf_list;
 	uint32_t bytes_rsvd = 0, read_idx = droq->read_idx;
-	uint16_t port_id = droq->otx_ep_dev->port_id;
 	uint16_t nb_desc = droq->nb_desc;
 	uint16_t pkts;

@@ -137,14 +136,19 @@ cnxk_ep_process_pkts_scalar(struct rte_mbuf **rx_pkts, struct otx_ep_droq *droq,
 		struct rte_mbuf *mbuf;
 		uint16_t pkt_len;

+		rte_prefetch0(recv_buf_list[otx_ep_incr_index(read_idx, 2, nb_desc)]);
+		rte_prefetch0(rte_pktmbuf_mtod(recv_buf_list[otx_ep_incr_index(read_idx,
+									       2, nb_desc)],
+			      void *));
+
 		mbuf = recv_buf_list[read_idx];
 		info = rte_pktmbuf_mtod(mbuf, struct otx_ep_droq_info *);
 		read_idx = otx_ep_incr_index(read_idx, 1, nb_desc);
 		pkt_len = rte_bswap16(info->length >> 48);
-		mbuf->data_off += OTX_EP_INFO_SIZE;
 		mbuf->pkt_len = pkt_len;
 		mbuf->data_len = pkt_len;
-		mbuf->port = port_id;
+
+		*(uint64_t *)&mbuf->rearm_data = droq->rearm_data;
 		rx_pkts[pkts] = mbuf;
 		bytes_rsvd += pkt_len;
 	}
diff --git a/drivers/net/octeon_ep/otx_ep_common.h b/drivers/net/octeon_ep/otx_ep_common.h
index 82e57520d3..299b5122d8 100644
--- a/drivers/net/octeon_ep/otx_ep_common.h
+++ b/drivers/net/octeon_ep/otx_ep_common.h
@@ -365,6 +365,9 @@ struct otx_ep_droq {
 	/* receive buffer list contains mbuf ptr list */
 	struct rte_mbuf **recv_buf_list;

+	/* Packet re-arm data. */
+	uint64_t rearm_data;
+
 	/* Packets pending to be processed */
 	uint64_t pkts_pending;

diff --git a/drivers/net/octeon_ep/otx_ep_rxtx.c b/drivers/net/octeon_ep/otx_ep_rxtx.c
index c421ef0a1c..40c4a16a38 100644
--- a/drivers/net/octeon_ep/otx_ep_rxtx.c
+++ b/drivers/net/octeon_ep/otx_ep_rxtx.c
@@ -284,6 +284,32 @@ otx_ep_droq_setup_ring_buffers(struct otx_ep_droq *droq)
 	return 0;
 }

+static inline uint64_t
+otx_ep_set_rearm_data(struct otx_ep_device *otx_ep)
+{
+	uint16_t port_id = otx_ep->port_id;
+	struct rte_mbuf mb_def;
+	uint64_t *tmp;
+
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_off) % 8 != 0);
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, refcnt) - offsetof(struct rte_mbuf, data_off) !=
+			 2);
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, nb_segs) - offsetof(struct rte_mbuf, data_off) !=
+			 4);
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, port) - offsetof(struct rte_mbuf, data_off) !=
+			 6);
+	mb_def.nb_segs = 1;
+	mb_def.data_off = RTE_PKTMBUF_HEADROOM + OTX_EP_INFO_SIZE;
+	mb_def.port = port_id;
+	rte_mbuf_refcnt_set(&mb_def, 1);
+
+	/* Prevent compiler reordering: rearm_data covers previous fields */
+	rte_compiler_barrier();
+	tmp = (uint64_t *)&mb_def.rearm_data;
+
+	return *tmp;
+}
+
 /* OQ initialization */
 static int
 otx_ep_init_droq(struct otx_ep_device *otx_ep, uint32_t q_no,
@@ -340,6 +366,7 @@ otx_ep_init_droq(struct otx_ep_device *otx_ep, uint32_t q_no,
 		goto init_droq_fail;

 	droq->refill_threshold = c_refill_threshold;
+	droq->rearm_data = otx_ep_set_rearm_data(otx_ep);

 	/* Set up OQ registers */
 	ret = otx_ep->fn_list.setup_oq_regs(otx_ep, q_no);
diff --git a/drivers/net/octeon_ep/otx_ep_rxtx.h b/drivers/net/octeon_ep/otx_ep_rxtx.h
index cb68ef3b41..b159c32cae 100644
--- a/drivers/net/octeon_ep/otx_ep_rxtx.h
+++ b/drivers/net/octeon_ep/otx_ep_rxtx.h
@@ -17,7 +17,7 @@

 #define OTX_EP_FSZ 28
 #define OTX2_EP_FSZ 24
-#define OTX_EP_MAX_INSTR 128
+#define OTX_EP_MAX_INSTR 256

 /* SDP_LENGTH_S specifies packet length and is of 8-byte size */
 #define OTX_EP_INFO_SIZE 8
--
2.25.1


^ permalink raw reply	[relevance 3%]

* [PATCH v3 1/3] net/octeon_ep: optimize Rx and Tx routines
    2023-12-06 12:12  3% ` Jerin Jacob
@ 2023-12-06 17:24  3% ` pbhagavatula
  2023-12-07  6:49  3%   ` [PATCH v4 " pbhagavatula
  1 sibling, 1 reply; 200+ results
From: pbhagavatula @ 2023-12-06 17:24 UTC (permalink / raw)
  To: jerinj, Vamsi Attunuru; +Cc: dev, Pavan Nikhilesh

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Preset rearm data to avoid writing multiple fields in fastpath,
Increase maximum outstanding Tx instructions from 128 to 256.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
v3 Chnages:
- Add more comments to the code.
- Re-enable 32b build to prevent ABI break.
v2 Changes:
- Skip compiling for 32b x86 targets.

 drivers/net/octeon_ep/cnxk_ep_rx.c    | 12 ++++++++----
 drivers/net/octeon_ep/otx_ep_common.h |  3 +++
 drivers/net/octeon_ep/otx_ep_rxtx.c   | 27 +++++++++++++++++++++++++++
 drivers/net/octeon_ep/otx_ep_rxtx.h   |  2 +-
 4 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/net/octeon_ep/cnxk_ep_rx.c b/drivers/net/octeon_ep/cnxk_ep_rx.c
index 74f0011283..75bb7225d2 100644
--- a/drivers/net/octeon_ep/cnxk_ep_rx.c
+++ b/drivers/net/octeon_ep/cnxk_ep_rx.c
@@ -93,7 +93,7 @@ cnxk_ep_check_rx_pkts(struct otx_ep_droq *droq)
 	new_pkts = val - droq->pkts_sent_ism_prev;
 	droq->pkts_sent_ism_prev = val;

-	if (val > (uint32_t)(1 << 31)) {
+	if (val > RTE_BIT32(31)) {
 		/* Only subtract the packet count in the HW counter
 		 * when count above halfway to saturation.
 		 */
@@ -128,7 +128,6 @@ cnxk_ep_process_pkts_scalar(struct rte_mbuf **rx_pkts, struct otx_ep_droq *droq,
 {
 	struct rte_mbuf **recv_buf_list = droq->recv_buf_list;
 	uint32_t bytes_rsvd = 0, read_idx = droq->read_idx;
-	uint16_t port_id = droq->otx_ep_dev->port_id;
 	uint16_t nb_desc = droq->nb_desc;
 	uint16_t pkts;

@@ -137,14 +136,19 @@ cnxk_ep_process_pkts_scalar(struct rte_mbuf **rx_pkts, struct otx_ep_droq *droq,
 		struct rte_mbuf *mbuf;
 		uint16_t pkt_len;

+		rte_prefetch0(recv_buf_list[otx_ep_incr_index(read_idx, 2, nb_desc)]);
+		rte_prefetch0(rte_pktmbuf_mtod(recv_buf_list[otx_ep_incr_index(read_idx,
+									       2, nb_desc)],
+			      void *));
+
 		mbuf = recv_buf_list[read_idx];
 		info = rte_pktmbuf_mtod(mbuf, struct otx_ep_droq_info *);
 		read_idx = otx_ep_incr_index(read_idx, 1, nb_desc);
 		pkt_len = rte_bswap16(info->length >> 48);
-		mbuf->data_off += OTX_EP_INFO_SIZE;
 		mbuf->pkt_len = pkt_len;
 		mbuf->data_len = pkt_len;
-		mbuf->port = port_id;
+
+		*(uint64_t *)&mbuf->rearm_data = droq->rearm_data;
 		rx_pkts[pkts] = mbuf;
 		bytes_rsvd += pkt_len;
 	}
diff --git a/drivers/net/octeon_ep/otx_ep_common.h b/drivers/net/octeon_ep/otx_ep_common.h
index 82e57520d3..299b5122d8 100644
--- a/drivers/net/octeon_ep/otx_ep_common.h
+++ b/drivers/net/octeon_ep/otx_ep_common.h
@@ -365,6 +365,9 @@ struct otx_ep_droq {
 	/* receive buffer list contains mbuf ptr list */
 	struct rte_mbuf **recv_buf_list;

+	/* Packet re-arm data. */
+	uint64_t rearm_data;
+
 	/* Packets pending to be processed */
 	uint64_t pkts_pending;

diff --git a/drivers/net/octeon_ep/otx_ep_rxtx.c b/drivers/net/octeon_ep/otx_ep_rxtx.c
index c421ef0a1c..40c4a16a38 100644
--- a/drivers/net/octeon_ep/otx_ep_rxtx.c
+++ b/drivers/net/octeon_ep/otx_ep_rxtx.c
@@ -284,6 +284,32 @@ otx_ep_droq_setup_ring_buffers(struct otx_ep_droq *droq)
 	return 0;
 }

+static inline uint64_t
+otx_ep_set_rearm_data(struct otx_ep_device *otx_ep)
+{
+	uint16_t port_id = otx_ep->port_id;
+	struct rte_mbuf mb_def;
+	uint64_t *tmp;
+
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_off) % 8 != 0);
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, refcnt) - offsetof(struct rte_mbuf, data_off) !=
+			 2);
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, nb_segs) - offsetof(struct rte_mbuf, data_off) !=
+			 4);
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, port) - offsetof(struct rte_mbuf, data_off) !=
+			 6);
+	mb_def.nb_segs = 1;
+	mb_def.data_off = RTE_PKTMBUF_HEADROOM + OTX_EP_INFO_SIZE;
+	mb_def.port = port_id;
+	rte_mbuf_refcnt_set(&mb_def, 1);
+
+	/* Prevent compiler reordering: rearm_data covers previous fields */
+	rte_compiler_barrier();
+	tmp = (uint64_t *)&mb_def.rearm_data;
+
+	return *tmp;
+}
+
 /* OQ initialization */
 static int
 otx_ep_init_droq(struct otx_ep_device *otx_ep, uint32_t q_no,
@@ -340,6 +366,7 @@ otx_ep_init_droq(struct otx_ep_device *otx_ep, uint32_t q_no,
 		goto init_droq_fail;

 	droq->refill_threshold = c_refill_threshold;
+	droq->rearm_data = otx_ep_set_rearm_data(otx_ep);

 	/* Set up OQ registers */
 	ret = otx_ep->fn_list.setup_oq_regs(otx_ep, q_no);
diff --git a/drivers/net/octeon_ep/otx_ep_rxtx.h b/drivers/net/octeon_ep/otx_ep_rxtx.h
index cb68ef3b41..b159c32cae 100644
--- a/drivers/net/octeon_ep/otx_ep_rxtx.h
+++ b/drivers/net/octeon_ep/otx_ep_rxtx.h
@@ -17,7 +17,7 @@

 #define OTX_EP_FSZ 28
 #define OTX2_EP_FSZ 24
-#define OTX_EP_MAX_INSTR 128
+#define OTX_EP_MAX_INSTR 256

 /* SDP_LENGTH_S specifies packet length and is of 8-byte size */
 #define OTX_EP_INFO_SIZE 8
--
2.25.1


^ permalink raw reply	[relevance 3%]

* Re: [PATCH] cfgfile: increase value length
  2023-12-06 15:50  3%       ` Bruce Richardson
@ 2023-12-06 16:46  3%         ` Varghese, Vipin
  0 siblings, 0 replies; 200+ results
From: Varghese, Vipin @ 2023-12-06 16:46 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: Dumitrescu, Cristian, dev, Yigit, Ferruh, Parikh, Neerav

[-- Attachment #1: Type: text/plain, Size: 4430 bytes --]

[AMD Official Use Only - General]

From: Bruce Richardson <bruce.richardson@intel.com>
Sent: 06 December 2023 21:20
To: Varghese, Vipin <Vipin.Varghese@amd.com>
Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; dev@dpdk.org <dev@dpdk.org>; Yigit, Ferruh <Ferruh.Yigit@amd.com>; Parikh, Neerav <Neerav.Parikh@amd.com>
Subject: Re: [PATCH] cfgfile: increase value length

Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.


On Wed, Dec 06, 2023 at 03:22:41PM +0000, Varghese, Vipin wrote:
>    [AMD Official Use Only - General]
>
>    Thanks Bruce & Cristian for the comments.
>    An increase seems ok to me, but is an 8x increase really necessary? If
>    lines in the config files are over 1k in size, then it implies that
>    some
>    other mechanism would surely be better for configuration.
>    Can we make do with an increase to 512 only?
>    VV> We encountered this issue
>    [1]https://bugs.dpdk.org/show_bug.cgi?id=1333 trying to use multiple
>    queue with DSA. But I hear you 256 to 2048 is big jump.
>    Happy to compromise with 1K.
>    VV> Sure let me update this is v2.
>    Since there is a ABI breakage,
>    [2]https://patchwork.dpdk.org/project/dpdk/patch/20231206112952.1588-1-
>    vipin.varghese@amd.com/ I will re work and share v2.

Looking at the bugzilla, I still think even an increase to 1k is too much,
and that we should look to adjust the config file format in some way to
accomodate these longer line settings.

Based on my testing 32 devices with the current format 2048B are appropriate.
That 4 DSA devices with 8 queues each.

Taking the specific example in the bug:
* each entry in the line is wasting 5 characters with the string "lcore"
* each PCI ID is starting with 0000, so we can do like EAL does and assume
  PCI domain is "0000" if just the BDF is given. This may involve changes
  to the PCI driver in question, since i assume these queues are names
  rather than addresses, but it would make them easier to address.

If we did these two items, then:
lcore_dma=lcore10@0000:00:04.2-q0,lcore12@0000:00:04.2-q1,lcore13@0000:00:04.2-q2,lcore14@0000:00:04.2-q3,lcore15@0000:00:04.2-q4,lcore16@0000:00:04.2-q5,lcore17@0000:00:04.2-q6,lcore18@0000:00:04.2-q7,lcore19@0000:00:04.4-q0,lcore20@0000:00:04.4-q1,lcore21@0000:00:04.4-q2,lcore22@0000:00:04.4-q3,lcore23@0000:00:04.4-q4,lcore24@0000:00:04.4-q5,lcore25@0000:00:04.4-q6,lcore26@0000:00:04.4-q7

becomes:
lcore_dma=10@00:04.2-q0,12@00:04.2-q1,13@00:04.2-q2,14@00:04.2-q3,15@00:04.2-q4,16@00:04.2-q5,17@00:04.2-q6,18@00:04.2-q7,19@00:04.4-q0,20@00:04.4-q1,21@00:04.4-q2,22@00:04.4-q3,23@00:04.4-q4,24@00:04.4-q5,25@00:04.4-q6,26@00:04.4-q7

a reduction from 394 chars to 234 (10 chars per device).

I see what you are suggesting, even though DPDK documentation states 9. EAL parameters — Data Plane Development Kit 23.11.0 documentation (dpdk.org)<https://doc.dpdk.org/guides/linux_gsg/linux_eal_parameters.html> `<[domain:]bus:devid.func>`, omit the domain to `bus:devid.func>`. That will reduce the bytes I agree.

However, a better alternative may be to split up the lcore_dma item
entirely, so that we always have one element per line:

lcore_dma0=lcore10@0000:04.2-q0
lcore_dma1=lcore12@0000:04.2-q1
....
lcore_dma15=lcore26@0000:04.4-q7

What is especially good about using this is a solution is that it can be fully
backward compatible and has no ABI issues. If an "lcore_dma=" line exists,
we can split it, otherwise look for lcore_dma0, lcore_dma1 etc.

Ok, but this means the test-dma-perf will need parsing changes and cfgfile library.

As I stated above, the need for really long lines in a config file is a
symptom of a more serious config problem, rather than an issue with the
cfgfile lib itself.

I do not fully agree to this statement, here are my 2 points


  1.
current code is `#ifndef CFG_VALUE_LEN` which means, the user can change the value using compiler flag `-DCFG_VALUE_LEN=[user desired value]` as cflags.
  2.
If not declared as CFLAGS configuration value is assumed to be hardened to take only 256

Hence the reasoning would be `it was not assumed there would be change from 256B was not expected or explored. If 256B is the hardlimit then we should not have used #ifndef`.

But +1 for changing the parsing logic.


/Bruce

[-- Attachment #2: Type: text/html, Size: 8325 bytes --]

^ permalink raw reply	[relevance 3%]

* Re: [PATCH] cfgfile: increase value length
  2023-12-06 15:22  3%     ` Varghese, Vipin
@ 2023-12-06 15:50  3%       ` Bruce Richardson
  2023-12-06 16:46  3%         ` Varghese, Vipin
  0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2023-12-06 15:50 UTC (permalink / raw)
  To: Varghese, Vipin; +Cc: Dumitrescu, Cristian, dev, Yigit, Ferruh, Parikh, Neerav

On Wed, Dec 06, 2023 at 03:22:41PM +0000, Varghese, Vipin wrote:
>    [AMD Official Use Only - General]
> 
>    Thanks Bruce & Cristian for the comments.
>    An increase seems ok to me, but is an 8x increase really necessary? If
>    lines in the config files are over 1k in size, then it implies that
>    some
>    other mechanism would surely be better for configuration.
>    Can we make do with an increase to 512 only?
>    VV> We encountered this issue
>    [1]https://bugs.dpdk.org/show_bug.cgi?id=1333 trying to use multiple
>    queue with DSA. But I hear you 256 to 2048 is big jump.
>    Happy to compromise with 1K.
>    VV> Sure let me update this is v2.
>    Since there is a ABI breakage,
>    [2]https://patchwork.dpdk.org/project/dpdk/patch/20231206112952.1588-1-
>    vipin.varghese@amd.com/ I will re work and share v2.

Looking at the bugzilla, I still think even an increase to 1k is too much,
and that we should look to adjust the config file format in some way to
accomodate these longer line settings.

Taking the specific example in the bug:
* each entry in the line is wasting 5 characters with the string "lcore"
* each PCI ID is starting with 0000, so we can do like EAL does and assume
  PCI domain is "0000" if just the BDF is given. This may involve changes
  to the PCI driver in question, since i assume these queues are names
  rather than addresses, but it would make them easier to address.

If we did these two items, then:
lcore_dma=lcore10@0000:00:04.2-q0,lcore12@0000:00:04.2-q1,lcore13@0000:00:04.2-q2,lcore14@0000:00:04.2-q3,lcore15@0000:00:04.2-q4,lcore16@0000:00:04.2-q5,lcore17@0000:00:04.2-q6,lcore18@0000:00:04.2-q7,lcore19@0000:00:04.4-q0,lcore20@0000:00:04.4-q1,lcore21@0000:00:04.4-q2,lcore22@0000:00:04.4-q3,lcore23@0000:00:04.4-q4,lcore24@0000:00:04.4-q5,lcore25@0000:00:04.4-q6,lcore26@0000:00:04.4-q7

becomes:
lcore_dma=10@00:04.2-q0,12@00:04.2-q1,13@00:04.2-q2,14@00:04.2-q3,15@00:04.2-q4,16@00:04.2-q5,17@00:04.2-q6,18@00:04.2-q7,19@00:04.4-q0,20@00:04.4-q1,21@00:04.4-q2,22@00:04.4-q3,23@00:04.4-q4,24@00:04.4-q5,25@00:04.4-q6,26@00:04.4-q7

a reduction from 394 chars to 234 (10 chars per device).

However, a better alternative may be to split up the lcore_dma item
entirely, so that we always have one element per line:

lcore_dma0=lcore10@0000:04.2-q0
lcore_dma1=lcore12@0000:04.2-q1
....
lcore_dma15=lcore26@0000:04.4-q7

What is especially good about using this is a solution is that it can be fully
backward compatible and has no ABI issues. If an "lcore_dma=" line exists,
we can split it, otherwise look for lcore_dma0, lcore_dma1 etc.

As I stated above, the need for really long lines in a config file is a
symptom of a more serious config problem, rather than an issue with the
cfgfile lib itself.

/Bruce

^ permalink raw reply	[relevance 3%]

* Re: [PATCH] cfgfile: increase value length
  @ 2023-12-06 15:22  3%     ` Varghese, Vipin
  2023-12-06 15:50  3%       ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Varghese, Vipin @ 2023-12-06 15:22 UTC (permalink / raw)
  To: Dumitrescu, Cristian, Richardson, Bruce
  Cc: dev, Yigit, Ferruh, Parikh, Neerav

[-- Attachment #1: Type: text/plain, Size: 3192 bytes --]

[AMD Official Use Only - General]

Thanks Bruce & Cristian for the comments.

An increase seems ok to me, but is an 8x increase really necessary? If
lines in the config files are over 1k in size, then it implies that some
other mechanism would surely be better for configuration.
Can we make do with an increase to 512 only?

VV> We encountered this issue https://bugs.dpdk.org/show_bug.cgi?id=1333 trying to use multiple queue with DSA. But I hear you 256 to 2048 is big jump.


Happy to compromise with 1K.
VV> Sure let me update this is v2.

Since there is a ABI breakage, https://patchwork.dpdk.org/project/dpdk/patch/20231206112952.1588-1-vipin.varghese@amd.com/ I will re work and share v2.

________________________________
From: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
Sent: 06 December 2023 19:04
To: Richardson, Bruce <bruce.richardson@intel.com>; Varghese, Vipin <Vipin.Varghese@amd.com>
Cc: dev@dpdk.org <dev@dpdk.org>; Yigit, Ferruh <Ferruh.Yigit@amd.com>
Subject: RE: [PATCH] cfgfile: increase value length

Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.


> -----Original Message-----
> From: Richardson, Bruce <bruce.richardson@intel.com>
> Sent: Wednesday, December 6, 2023 1:22 PM
> To: Vipin Varghese <vipin.varghese@amd.com>
> Cc: dev@dpdk.org; Dumitrescu, Cristian <cristian.dumitrescu@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>
> Subject: Re: [PATCH] cfgfile: increase value length
>
> On Wed, Dec 06, 2023 at 04:59:52PM +0530, Vipin Varghese wrote:
> > The default value for CFG_VALUE_LEN is set to 256 characters.
> > This limits the parsing for longer strings in configuration file.
> > Setting the default to 2048 characters increases the value array
> > size in `struct rte_cfgfile_entry`.
> >
> > Files using cfgfile library are
> > 1. drivers/net/mvpp2/
> > 2. app/test-dma-perf/
> > 3. app/test/
> > 4. examples/qos_sched/
> >
> > The structure `rte_cfgfile_entry` is not included in DPDK libraries.
> > Modifying from 256 to 2048 allows `app/test-dma-perf/main.c` helps to
> > parse longer string as shared in
> https://bugs.dpdk.org/show_bug.cgi?id=1333
> >
> > Signed-off-by: Vipin Varghese <vipin.varghese@amd.com>
> > Suggested-by: Ferruh Yigit <ferruh.yigit@amd.com>
> > ---
> >  lib/cfgfile/rte_cfgfile.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/lib/cfgfile/rte_cfgfile.h b/lib/cfgfile/rte_cfgfile.h
> > index 232c65c77b..401353c44e 100644
> > --- a/lib/cfgfile/rte_cfgfile.h
> > +++ b/lib/cfgfile/rte_cfgfile.h
> > @@ -24,7 +24,7 @@ extern "C" {
> >  #endif
> >
> >  #ifndef CFG_VALUE_LEN
> > -#define CFG_VALUE_LEN 256
> > +#define CFG_VALUE_LEN 2048
> >  #endif
> >
> An increase seems ok to me, but is an 8x increase really necessary? If
> lines in the config files are over 1k in size, then it implies that some
> other mechanism would surely be better for configuration.
> Can we make do with an increase to 512 only?
>
> /Bruce

Happy to compromise with 1K.

Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>


[-- Attachment #2: Type: text/html, Size: 8779 bytes --]

^ permalink raw reply	[relevance 3%]

* Re: [PATCH v2 1/3] net/octeon_ep: optimize Rx and Tx routines
  @ 2023-12-06 12:12  3% ` Jerin Jacob
  2023-12-06 17:24  3% ` [PATCH v3 " pbhagavatula
  1 sibling, 0 replies; 200+ results
From: Jerin Jacob @ 2023-12-06 12:12 UTC (permalink / raw)
  To: pbhagavatula; +Cc: jerinj, Vamsi Attunuru, dev

On Mon, Nov 27, 2023 at 7:32 AM <pbhagavatula@marvell.com> wrote:
>
> From: Pavan Nikhilesh <pbhagavatula@marvell.com>
>
> Preset rearm data to avoid writing multiple fields in fastpath,
> Increase maximum outstanding Tx instructions from 128 to 256.
>
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
> ---
> v2 Changes:
> - Skip compiling for 32b x86 targets.



ABI issue due to

Error: cannot find librte_net_octeon_ep.so.24.0 in
/export/dpdk-next-net-mrvl/build-32b/install

^ permalink raw reply	[relevance 3%]

* Re: [PATCH 00/18] Convert static log types in libraries to dynamic
  2023-12-05  2:09  3% ` [PATCH 00/18] Convert static log types in libraries to dynamic Stephen Hemminger
  2023-12-05  2:09  2%   ` [PATCH 17/18] hash: move rte_hash_set_alg out of header file Stephen Hemminger
@ 2023-12-06 10:08  3%   ` David Marchand
  1 sibling, 0 replies; 200+ results
From: David Marchand @ 2023-12-06 10:08 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Tue, Dec 5, 2023 at 3:13 AM Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> This patchset removes most of the uses of static LOGTYPE's in DPDK
> libraries. It starts with the easy one and goes on to the more complex ones.
>
> There are several options on how to treat the old static types:
> leave them there, mark as deprecated, or remove them.
> This version removes them since there is no guarantee in current
> DPDK policies that says they can't be removed.

Those logtypes were internal things that should not have been public
in the first place.

And switching to a dynamic logtype for external users (if any) is trivial.

>
> Note: there is one patch in this series that will get
> flagged incorrectly as an ABI change.

Adding such stable symbols is not a problem.
We can ignore this warning (which is there to force maintainers to
inspect such additions).

>
> v14 - rebase on 24.03-rc0
>       skip port, table and pipeline libraries since lots of
>       to be deprecated code.
>
> v13 - rebase because log now moved.
>
> v12 - rebase and add table and pipeline libraries
>
> v11 - fix include check on arm cross build
>
> v10 - add necessary rte_compat.h in thash_gfni stub for arm
>
> v9 - fix handling of crc32 alg in lib/hash.
>      make it an internal global variable.
>      fix gfni stubs for case where they are not used.
>
> Stephen Hemminger (18):
>   gso: don't log message on non TCP/UDP
>   eal: drop no longer used GSO logtype
>   log: drop unused RTE_LOGTYPE_TIMER
>   efd: convert RTE_LOGTYPE_EFD to dynamic type
>   mbuf: convert RTE_LOGTYPE_MBUF to dynamic type
>   acl: convert RTE_LOGTYPE_ACL to dynamic type
>   examples/power: replace use of RTE_LOGTYPE_POWER
>   examples/l3fwd-power: replace use of RTE_LOGTYPE_POWER
>   power: convert RTE_LOGTYPE_POWER to dynamic type
>   ring: convert RTE_LOGTYPE_RING to dynamic type
>   mempool: convert RTE_LOGTYPE_MEMPOOL to dynamic type
>   lpm: convert RTE_LOGTYPE_LPM to dynamic types
>   sched: convert RTE_LOGTYPE_SCHED to dynamic type
>   examples/ipsec-secgw: replace RTE_LOGTYPE_PORT
>   app/test: remove use of RTE_LOGTYPE_PIPELINE
>   hash: mover rte_thash_gfni stubs out of header file
>   hash: move rte_hash_set_alg out of header file
>   hash: convert RTE_LOGTYPE_HASH to dynamic type
>
>  app/test/test_acl.c            |  2 +-
>  app/test/test_table_acl.c      | 50 ++++++++++++-------------
>  app/test/test_table_pipeline.c | 40 ++++++++++----------
>  examples/distributor/main.c    |  2 +-
>  examples/ipsec-secgw/sa.c      |  6 +--
>  examples/l3fwd-power/main.c    | 17 +++++----
>  lib/acl/acl.h                  |  1 +
>  lib/acl/acl_bld.c              |  3 ++
>  lib/acl/acl_gen.c              |  1 +
>  lib/acl/acl_log.h              |  6 +++
>  lib/acl/rte_acl.c              |  3 ++
>  lib/acl/tb_mem.c               |  3 +-
>  lib/efd/rte_efd.c              |  4 ++
>  lib/fib/fib_log.h              |  4 ++
>  lib/fib/rte_fib.c              |  3 ++
>  lib/fib/rte_fib6.c             |  2 +
>  lib/gso/rte_gso.c              |  4 +-
>  lib/gso/rte_gso.h              |  1 +
>  lib/hash/meson.build           |  9 ++++-
>  lib/hash/rte_crc_arm64.h       |  8 ++--
>  lib/hash/rte_crc_x86.h         | 10 ++---
>  lib/hash/rte_cuckoo_hash.c     |  5 +++
>  lib/hash/rte_fbk_hash.c        |  5 +++
>  lib/hash/rte_hash_crc.c        | 68 ++++++++++++++++++++++++++++++++++
>  lib/hash/rte_hash_crc.h        | 48 ++----------------------
>  lib/hash/rte_thash.c           |  3 ++
>  lib/hash/rte_thash_gfni.c      | 50 +++++++++++++++++++++++++
>  lib/hash/rte_thash_gfni.h      | 23 +++---------
>  lib/hash/version.map           |  9 +++++
>  lib/log/log.c                  | 13 -------
>  lib/log/rte_log.h              | 26 ++++++-------
>  lib/lpm/lpm_log.h              |  4 ++
>  lib/lpm/rte_lpm.c              |  3 ++
>  lib/lpm/rte_lpm6.c             |  1 +
>  lib/mbuf/mbuf_log.h            |  4 ++
>  lib/mbuf/rte_mbuf.c            |  4 ++
>  lib/mbuf/rte_mbuf_dyn.c        |  2 +
>  lib/mbuf/rte_mbuf_pool_ops.c   |  2 +
>  lib/mempool/rte_mempool.c      |  2 +
>  lib/mempool/rte_mempool.h      |  8 ++++
>  lib/mempool/version.map        |  3 ++
>  lib/power/power_common.c       |  2 +
>  lib/power/power_common.h       |  2 +
>  lib/power/power_kvm_vm.c       |  1 +
>  lib/power/rte_power.c          |  1 +
>  lib/power/rte_power_uncore.c   |  1 +
>  lib/rib/rib_log.h              |  4 ++
>  lib/rib/rte_rib.c              |  3 ++
>  lib/rib/rte_rib6.c             |  3 ++
>  lib/ring/rte_ring.c            |  3 ++
>  lib/sched/rte_pie.c            |  1 +
>  lib/sched/rte_sched.c          |  5 +++
>  lib/sched/rte_sched_log.h      |  4 ++
>  53 files changed, 329 insertions(+), 163 deletions(-)
>  create mode 100644 lib/acl/acl_log.h
>  create mode 100644 lib/fib/fib_log.h
>  create mode 100644 lib/hash/rte_hash_crc.c
>  create mode 100644 lib/hash/rte_thash_gfni.c
>  create mode 100644 lib/lpm/lpm_log.h
>  create mode 100644 lib/mbuf/mbuf_log.h
>  create mode 100644 lib/rib/rib_log.h
>  create mode 100644 lib/sched/rte_sched_log.h

I fixed a few issues:
- added a release note update for the gso patch,
- fixed some styling issues in meson updates,
- reordered some hunks and patches,
- dropped some whitespace damage and typos,
- dropped unneeded include of rte_compat.h,
- fixed indent,
- marked exported variables as stable (such variable is part of the
application ABI),

Series applied.


-- 
David Marchand


^ permalink raw reply	[relevance 3%]

* [PATCH 17/18] hash: move rte_hash_set_alg out of header file
  2023-12-05  2:09  3% ` [PATCH 00/18] Convert static log types in libraries to dynamic Stephen Hemminger
@ 2023-12-05  2:09  2%   ` Stephen Hemminger
  2023-12-06 10:08  3%   ` [PATCH 00/18] Convert static log types in libraries to dynamic David Marchand
  1 sibling, 0 replies; 200+ results
From: Stephen Hemminger @ 2023-12-05  2:09 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, Ruifeng Wang, Yipeng Wang, Sameh Gobriel,
	Bruce Richardson, Vladimir Medvedkin

The code for setting algorithm for hash is not at all perf sensitive,
and doing it inline has a couple of problems. First, it means that if
multiple files include the header, then the initialization gets done
multiple times. But also, it makes it harder to fix usage of RTE_LOG().

Despite what the checking script say. This is not an ABI change, the
previous version inlined the same code; therefore both old and new code
will work the same.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 lib/hash/meson.build     |  1 +
 lib/hash/rte_crc_arm64.h |  8 ++---
 lib/hash/rte_crc_x86.h   | 10 +++---
 lib/hash/rte_hash_crc.c  | 68 ++++++++++++++++++++++++++++++++++++++++
 lib/hash/rte_hash_crc.h  | 48 ++--------------------------
 lib/hash/version.map     |  7 +++++
 6 files changed, 88 insertions(+), 54 deletions(-)
 create mode 100644 lib/hash/rte_hash_crc.c

diff --git a/lib/hash/meson.build b/lib/hash/meson.build
index e56ee8572564..c345c6f561fc 100644
--- a/lib/hash/meson.build
+++ b/lib/hash/meson.build
@@ -19,6 +19,7 @@ indirect_headers += files(
 
 sources = files(
     'rte_cuckoo_hash.c',
+    'rte_hash_crc.c',
     'rte_fbk_hash.c',
     'rte_thash.c',
     'rte_thash_gfni.c'
diff --git a/lib/hash/rte_crc_arm64.h b/lib/hash/rte_crc_arm64.h
index c9f52510871b..414fe065caa8 100644
--- a/lib/hash/rte_crc_arm64.h
+++ b/lib/hash/rte_crc_arm64.h
@@ -53,7 +53,7 @@ crc32c_arm64_u64(uint64_t data, uint32_t init_val)
 static inline uint32_t
 rte_hash_crc_1byte(uint8_t data, uint32_t init_val)
 {
-	if (likely(crc32_alg & CRC32_ARM64))
+	if (likely(rte_hash_crc32_alg & CRC32_ARM64))
 		return crc32c_arm64_u8(data, init_val);
 
 	return crc32c_1byte(data, init_val);
@@ -67,7 +67,7 @@ rte_hash_crc_1byte(uint8_t data, uint32_t init_val)
 static inline uint32_t
 rte_hash_crc_2byte(uint16_t data, uint32_t init_val)
 {
-	if (likely(crc32_alg & CRC32_ARM64))
+	if (likely(rte_hash_crc32_alg & CRC32_ARM64))
 		return crc32c_arm64_u16(data, init_val);
 
 	return crc32c_2bytes(data, init_val);
@@ -81,7 +81,7 @@ rte_hash_crc_2byte(uint16_t data, uint32_t init_val)
 static inline uint32_t
 rte_hash_crc_4byte(uint32_t data, uint32_t init_val)
 {
-	if (likely(crc32_alg & CRC32_ARM64))
+	if (likely(rte_hash_crc32_alg & CRC32_ARM64))
 		return crc32c_arm64_u32(data, init_val);
 
 	return crc32c_1word(data, init_val);
@@ -95,7 +95,7 @@ rte_hash_crc_4byte(uint32_t data, uint32_t init_val)
 static inline uint32_t
 rte_hash_crc_8byte(uint64_t data, uint32_t init_val)
 {
-	if (likely(crc32_alg & CRC32_ARM64))
+	if (likely(rte_hash_crc32_alg & CRC32_ARM64))
 		return crc32c_arm64_u64(data, init_val);
 
 	return crc32c_2words(data, init_val);
diff --git a/lib/hash/rte_crc_x86.h b/lib/hash/rte_crc_x86.h
index 205bc182be77..3b865e251db2 100644
--- a/lib/hash/rte_crc_x86.h
+++ b/lib/hash/rte_crc_x86.h
@@ -67,7 +67,7 @@ crc32c_sse42_u64(uint64_t data, uint64_t init_val)
 static inline uint32_t
 rte_hash_crc_1byte(uint8_t data, uint32_t init_val)
 {
-	if (likely(crc32_alg & CRC32_SSE42))
+	if (likely(rte_hash_crc32_alg & CRC32_SSE42))
 		return crc32c_sse42_u8(data, init_val);
 
 	return crc32c_1byte(data, init_val);
@@ -81,7 +81,7 @@ rte_hash_crc_1byte(uint8_t data, uint32_t init_val)
 static inline uint32_t
 rte_hash_crc_2byte(uint16_t data, uint32_t init_val)
 {
-	if (likely(crc32_alg & CRC32_SSE42))
+	if (likely(rte_hash_crc32_alg & CRC32_SSE42))
 		return crc32c_sse42_u16(data, init_val);
 
 	return crc32c_2bytes(data, init_val);
@@ -95,7 +95,7 @@ rte_hash_crc_2byte(uint16_t data, uint32_t init_val)
 static inline uint32_t
 rte_hash_crc_4byte(uint32_t data, uint32_t init_val)
 {
-	if (likely(crc32_alg & CRC32_SSE42))
+	if (likely(rte_hash_crc32_alg & CRC32_SSE42))
 		return crc32c_sse42_u32(data, init_val);
 
 	return crc32c_1word(data, init_val);
@@ -110,11 +110,11 @@ static inline uint32_t
 rte_hash_crc_8byte(uint64_t data, uint32_t init_val)
 {
 #ifdef RTE_ARCH_X86_64
-	if (likely(crc32_alg == CRC32_SSE42_x64))
+	if (likely(rte_hash_crc32_alg == CRC32_SSE42_x64))
 		return crc32c_sse42_u64(data, init_val);
 #endif
 
-	if (likely(crc32_alg & CRC32_SSE42))
+	if (likely(rte_hash_crc32_alg & CRC32_SSE42))
 		return crc32c_sse42_u64_mimic(data, init_val);
 
 	return crc32c_2words(data, init_val);
diff --git a/lib/hash/rte_hash_crc.c b/lib/hash/rte_hash_crc.c
new file mode 100644
index 000000000000..1439d8a71f6a
--- /dev/null
+++ b/lib/hash/rte_hash_crc.c
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <rte_cpuflags.h>
+#include <rte_log.h>
+
+#include "rte_hash_crc.h"
+
+RTE_LOG_REGISTER_SUFFIX(hash_crc_logtype, crc, INFO);
+#define RTE_LOGTYPE_HASH_CRC hash_crc_logtype
+
+uint8_t rte_hash_crc32_alg = CRC32_SW;
+
+/**
+ * Allow or disallow use of SSE4.2/ARMv8 intrinsics for CRC32 hash
+ * calculation.
+ *
+ * @param alg
+ *   An OR of following flags:
+ *   - (CRC32_SW) Don't use SSE4.2/ARMv8 intrinsics (default non-[x86/ARMv8])
+ *   - (CRC32_SSE42) Use SSE4.2 intrinsics if available
+ *   - (CRC32_SSE42_x64) Use 64-bit SSE4.2 intrinsic if available (default x86)
+ *   - (CRC32_ARM64) Use ARMv8 CRC intrinsic if available (default ARMv8)
+ *
+ */
+void
+rte_hash_crc_set_alg(uint8_t alg)
+{
+	rte_hash_crc32_alg = CRC32_SW;
+
+	if (alg == CRC32_SW)
+		return;
+
+#if defined RTE_ARCH_X86
+	if (!(alg & CRC32_SSE42_x64))
+		RTE_LOG(WARNING, HASH_CRC,
+			"Unsupported CRC32 algorithm requested using CRC32_x64/CRC32_SSE42\n");
+	if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_EM64T) || alg == CRC32_SSE42)
+		rte_hash_crc32_alg = CRC32_SSE42;
+	else
+		rte_hash_crc32_alg = CRC32_SSE42_x64;
+#endif
+
+#if defined RTE_ARCH_ARM64
+	if (!(alg & CRC32_ARM64))
+		RTE_LOG(WARNING, HASH_CRC,
+			"Unsupported CRC32 algorithm requested using CRC32_ARM64\n");
+	if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_CRC32))
+		rte_hash_crc32_alg = CRC32_ARM64;
+#endif
+
+	if (rte_hash_crc32_alg == CRC32_SW)
+		RTE_LOG(WARNING, HASH_CRC,
+			"Unsupported CRC32 algorithm requested using CRC32_SW\n");
+}
+
+/* Setting the best available algorithm */
+RTE_INIT(rte_hash_crc_init_alg)
+{
+#if defined(RTE_ARCH_X86)
+	rte_hash_crc_set_alg(CRC32_SSE42_x64);
+#elif defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_CRC32)
+	rte_hash_crc_set_alg(CRC32_ARM64);
+#else
+	rte_hash_crc_set_alg(CRC32_SW);
+#endif
+}
diff --git a/lib/hash/rte_hash_crc.h b/lib/hash/rte_hash_crc.h
index 60bf42ce1d97..8ad2422ec333 100644
--- a/lib/hash/rte_hash_crc.h
+++ b/lib/hash/rte_hash_crc.h
@@ -20,8 +20,6 @@ extern "C" {
 #include <rte_branch_prediction.h>
 #include <rte_common.h>
 #include <rte_config.h>
-#include <rte_cpuflags.h>
-#include <rte_log.h>
 
 #include "rte_crc_sw.h"
 
@@ -31,7 +29,7 @@ extern "C" {
 #define CRC32_SSE42_x64     (CRC32_x64|CRC32_SSE42)
 #define CRC32_ARM64         (1U << 3)
 
-static uint8_t crc32_alg = CRC32_SW;
+extern uint8_t rte_hash_crc32_alg;
 
 #if defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_CRC32)
 #include "rte_crc_arm64.h"
@@ -52,48 +50,8 @@ static uint8_t crc32_alg = CRC32_SW;
  *   - (CRC32_SSE42_x64) Use 64-bit SSE4.2 intrinsic if available (default x86)
  *   - (CRC32_ARM64) Use ARMv8 CRC intrinsic if available (default ARMv8)
  */
-static inline void
-rte_hash_crc_set_alg(uint8_t alg)
-{
-	crc32_alg = CRC32_SW;
-
-	if (alg == CRC32_SW)
-		return;
-
-#if defined RTE_ARCH_X86
-	if (!(alg & CRC32_SSE42_x64))
-		RTE_LOG(WARNING, HASH,
-			"Unsupported CRC32 algorithm requested using CRC32_x64/CRC32_SSE42\n");
-	if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_EM64T) || alg == CRC32_SSE42)
-		crc32_alg = CRC32_SSE42;
-	else
-		crc32_alg = CRC32_SSE42_x64;
-#endif
-
-#if defined RTE_ARCH_ARM64
-	if (!(alg & CRC32_ARM64))
-		RTE_LOG(WARNING, HASH,
-			"Unsupported CRC32 algorithm requested using CRC32_ARM64\n");
-	if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_CRC32))
-		crc32_alg = CRC32_ARM64;
-#endif
-
-	if (crc32_alg == CRC32_SW)
-		RTE_LOG(WARNING, HASH,
-			"Unsupported CRC32 algorithm requested using CRC32_SW\n");
-}
-
-/* Setting the best available algorithm */
-RTE_INIT(rte_hash_crc_init_alg)
-{
-#if defined(RTE_ARCH_X86)
-	rte_hash_crc_set_alg(CRC32_SSE42_x64);
-#elif defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_CRC32)
-	rte_hash_crc_set_alg(CRC32_ARM64);
-#else
-	rte_hash_crc_set_alg(CRC32_SW);
-#endif
-}
+void
+rte_hash_crc_set_alg(uint8_t alg);
 
 #ifdef __DOXYGEN__
 
diff --git a/lib/hash/version.map b/lib/hash/version.map
index 56a0cbd4b8a5..ed0743adedbb 100644
--- a/lib/hash/version.map
+++ b/lib/hash/version.map
@@ -9,6 +9,7 @@ DPDK_24 {
 	rte_hash_add_key_with_hash;
 	rte_hash_add_key_with_hash_data;
 	rte_hash_count;
+	rte_hash_crc_set_alg;
 	rte_hash_create;
 	rte_hash_del_key;
 	rte_hash_del_key_with_hash;
@@ -46,3 +47,9 @@ DPDK_24 {
 
 	local: *;
 };
+
+INTERNAL {
+	global:
+
+	rte_hash_crc32_alg;
+};
-- 
2.42.0


^ permalink raw reply	[relevance 2%]

* [PATCH 00/18] Convert static log types in libraries to dynamic
    @ 2023-12-05  2:09  3% ` Stephen Hemminger
  2023-12-05  2:09  2%   ` [PATCH 17/18] hash: move rte_hash_set_alg out of header file Stephen Hemminger
  2023-12-06 10:08  3%   ` [PATCH 00/18] Convert static log types in libraries to dynamic David Marchand
  1 sibling, 2 replies; 200+ results
From: Stephen Hemminger @ 2023-12-05  2:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

This patchset removes most of the uses of static LOGTYPE's in DPDK
libraries. It starts with the easy one and goes on to the more complex ones.

There are several options on how to treat the old static types:
leave them there, mark as deprecated, or remove them.
This version removes them since there is no guarantee in current
DPDK policies that says they can't be removed.

Note: there is one patch in this series that will get
flagged incorrectly as an ABI change.

v14 - rebase on 24.03-rc0
      skip port, table and pipeline libraries since lots of
      to be deprecated code.

v13 - rebase because log now moved.

v12 - rebase and add table and pipeline libraries

v11 - fix include check on arm cross build

v10 - add necessary rte_compat.h in thash_gfni stub for arm

v9 - fix handling of crc32 alg in lib/hash.
     make it an internal global variable.
     fix gfni stubs for case where they are not used.

Stephen Hemminger (18):
  gso: don't log message on non TCP/UDP
  eal: drop no longer used GSO logtype
  log: drop unused RTE_LOGTYPE_TIMER
  efd: convert RTE_LOGTYPE_EFD to dynamic type
  mbuf: convert RTE_LOGTYPE_MBUF to dynamic type
  acl: convert RTE_LOGTYPE_ACL to dynamic type
  examples/power: replace use of RTE_LOGTYPE_POWER
  examples/l3fwd-power: replace use of RTE_LOGTYPE_POWER
  power: convert RTE_LOGTYPE_POWER to dynamic type
  ring: convert RTE_LOGTYPE_RING to dynamic type
  mempool: convert RTE_LOGTYPE_MEMPOOL to dynamic type
  lpm: convert RTE_LOGTYPE_LPM to dynamic types
  sched: convert RTE_LOGTYPE_SCHED to dynamic type
  examples/ipsec-secgw: replace RTE_LOGTYPE_PORT
  app/test: remove use of RTE_LOGTYPE_PIPELINE
  hash: mover rte_thash_gfni stubs out of header file
  hash: move rte_hash_set_alg out of header file
  hash: convert RTE_LOGTYPE_HASH to dynamic type

 app/test/test_acl.c            |  2 +-
 app/test/test_table_acl.c      | 50 ++++++++++++-------------
 app/test/test_table_pipeline.c | 40 ++++++++++----------
 examples/distributor/main.c    |  2 +-
 examples/ipsec-secgw/sa.c      |  6 +--
 examples/l3fwd-power/main.c    | 17 +++++----
 lib/acl/acl.h                  |  1 +
 lib/acl/acl_bld.c              |  3 ++
 lib/acl/acl_gen.c              |  1 +
 lib/acl/acl_log.h              |  6 +++
 lib/acl/rte_acl.c              |  3 ++
 lib/acl/tb_mem.c               |  3 +-
 lib/efd/rte_efd.c              |  4 ++
 lib/fib/fib_log.h              |  4 ++
 lib/fib/rte_fib.c              |  3 ++
 lib/fib/rte_fib6.c             |  2 +
 lib/gso/rte_gso.c              |  4 +-
 lib/gso/rte_gso.h              |  1 +
 lib/hash/meson.build           |  9 ++++-
 lib/hash/rte_crc_arm64.h       |  8 ++--
 lib/hash/rte_crc_x86.h         | 10 ++---
 lib/hash/rte_cuckoo_hash.c     |  5 +++
 lib/hash/rte_fbk_hash.c        |  5 +++
 lib/hash/rte_hash_crc.c        | 68 ++++++++++++++++++++++++++++++++++
 lib/hash/rte_hash_crc.h        | 48 ++----------------------
 lib/hash/rte_thash.c           |  3 ++
 lib/hash/rte_thash_gfni.c      | 50 +++++++++++++++++++++++++
 lib/hash/rte_thash_gfni.h      | 23 +++---------
 lib/hash/version.map           |  9 +++++
 lib/log/log.c                  | 13 -------
 lib/log/rte_log.h              | 26 ++++++-------
 lib/lpm/lpm_log.h              |  4 ++
 lib/lpm/rte_lpm.c              |  3 ++
 lib/lpm/rte_lpm6.c             |  1 +
 lib/mbuf/mbuf_log.h            |  4 ++
 lib/mbuf/rte_mbuf.c            |  4 ++
 lib/mbuf/rte_mbuf_dyn.c        |  2 +
 lib/mbuf/rte_mbuf_pool_ops.c   |  2 +
 lib/mempool/rte_mempool.c      |  2 +
 lib/mempool/rte_mempool.h      |  8 ++++
 lib/mempool/version.map        |  3 ++
 lib/power/power_common.c       |  2 +
 lib/power/power_common.h       |  2 +
 lib/power/power_kvm_vm.c       |  1 +
 lib/power/rte_power.c          |  1 +
 lib/power/rte_power_uncore.c   |  1 +
 lib/rib/rib_log.h              |  4 ++
 lib/rib/rte_rib.c              |  3 ++
 lib/rib/rte_rib6.c             |  3 ++
 lib/ring/rte_ring.c            |  3 ++
 lib/sched/rte_pie.c            |  1 +
 lib/sched/rte_sched.c          |  5 +++
 lib/sched/rte_sched_log.h      |  4 ++
 53 files changed, 329 insertions(+), 163 deletions(-)
 create mode 100644 lib/acl/acl_log.h
 create mode 100644 lib/fib/fib_log.h
 create mode 100644 lib/hash/rte_hash_crc.c
 create mode 100644 lib/hash/rte_thash_gfni.c
 create mode 100644 lib/lpm/lpm_log.h
 create mode 100644 lib/mbuf/mbuf_log.h
 create mode 100644 lib/rib/rib_log.h
 create mode 100644 lib/sched/rte_sched_log.h

-- 
2.42.0


^ permalink raw reply	[relevance 3%]

* Re: [PATCH v13 00/21] Convert static log types in libraries to dynamic types
  @ 2023-12-04 12:32  0%   ` David Marchand
  0 siblings, 0 replies; 200+ results
From: David Marchand @ 2023-12-04 12:32 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Mon, Aug 21, 2023 at 6:09 PM Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> This patchset removes most of the uses of static LOGTYPE's in DPDK
> libraries. It starts with the easy one and goes on to the more complex ones.
>
> There are several options on how to treat the old static types:
> leave them there, mark as deprecated, or remove them.
> This version removes them since there is no guarantee in current
> DPDK policies that says they can't be removed.
>
> Note: there is one patch in this series that will get
> flagged incorrectly as an ABI change.
>
> v13 - rebase because log now moved.
>
> v12 - rebase and add table and pipeline libraries
>
> v11 - fix include check on arm cross build
>
> v10 - add necessary rte_compat.h in thash_gfni stub for arm
>
> v9 - fix handling of crc32 alg in lib/hash.
>      make it an internal global variable.
>      fix gfni stubs for case where they are not used.
>
> Stephen Hemminger (21):
>   gso: don't log message on non TCP/UDP
>   eal: drop no longer used GSO logtype
>   log: drop unused RTE_LOGTYPE_TIMER
>   efd: convert RTE_LOGTYPE_EFD to dynamic type
>   mbuf: convert RTE_LOGTYPE_MBUF to dynamic type
>   acl: convert RTE_LOGTYPE_ACL to dynamic type
>   examples/power: replace use of RTE_LOGTYPE_POWER
>   examples/l3fwd-power: replace use of RTE_LOGTYPE_POWER
>   power: convert RTE_LOGTYPE_POWER to dynamic type
>   ring: convert RTE_LOGTYPE_RING to dynamic type
>   mempool: convert RTE_LOGTYPE_MEMPOOL to dynamic type
>   lpm: convert RTE_LOGTYPE_LPM to dynamic types
>   sched: convert RTE_LOGTYPE_SCHED to dynamic type
>   examples/ipsec-secgw: replace RTE_LOGTYPE_PORT
>   port: convert RTE_LOGTYPE_PORT to dynamic type
>   hash: move rte_thash_gfni stubs out of header file
>   hash: move rte_hash_set_alg out header
>   hash: convert RTE_LOGTYPE_HASH to dynamic type
>   table: convert RTE_LOGTYPE_TABLE to dynamic type
>   app/test: remove use of RTE_LOGTYPE_PIPELINE
>   pipeline: convert RTE_LOGTYPE_PIPELINE to dynamic type
>

This series needs some rebase.
Thanks.


-- 
David Marchand


^ permalink raw reply	[relevance 0%]

* Re: [PATCH] version: 24.03-rc0
  2023-11-30  9:23  3% ` David Marchand
  2023-11-30  9:30  0%   ` Ferruh Yigit
@ 2023-11-30 18:33  0%   ` Patrick Robb
  1 sibling, 0 replies; 200+ results
From: Patrick Robb @ 2023-11-30 18:33 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, thomas, Aaron Conole, Michael Santana, Ferruh Yigit,
	Andrew Rybchenko, Ajit Khaparde, Qi Zhang,
	Jerin Jacob Kollanukkaran, Raslan Darawsheh, Maxime Coquelin,
	Akhil Goyal

[-- Attachment #1: Type: text/plain, Size: 1806 bytes --]

On Thu, Nov 30, 2023 at 4:24 AM David Marchand <david.marchand@redhat.com>
wrote:

>
> What it means:
> - for the https://dpdk.org/git/dpdk repository, all the branches and
> tags are mirrored to https://github.com/DPDK/dpdk as it was done so
> far,
> - for the https://git.dpdk.org/next/dpdk-next-* repositories, only
> branches named "main", "staging" or "for-*" are mirrored to
> https://github.com/DPDK/dpdk with a prefix.
>
Thank you David for clearing some of this up on the CI testing meeting. I
think the final loose end was you were wondering which branches within the
next-* repos we were running from. I'll paste that below:

dpdk-next-crypto: for-main
dpdk-next-eventdev: for-main
dpdk-next-net: main
dpdk-next-net-brcm: main
dpdk-next-net-intel: main
dpdk-next-net-mlx: main
dpdk-next-net-mrvl: for-next-net
dpdk-next-virtio: main
dpdk-next-baseband: for-main


>   One example: changes to the for-main branch of the dpdk-next-crypto
> repo will be mirrored to a github branch next-crypto-for-main
>
>
> For subtree maintainers.
>
> It should change nothing to you guys.
> Please rebase your trees on v24.03-rc0 and push it to dpdk.org.
> And then double check that the mirror happened (looking at git push
> output, and checking https://github.com/DPDK/dpdk/branches).
> If you hit some issue, ping me.
>
>
> For CI.
>
> This is more a fyi, there will be some delay before all mirrors are
> up, so for now, don't swap the next-* repositories in your script yet.
> However, one action that can be taken as v24.03-rc0 is pushed is to
> re-enable ABI checks against the v23.11 official tag.
>
> Okay, we will rebuild our container images to bake in new ABI references
this week. Thanks!


>
> Questions?
>
>
> --
> David Marchand
>
>

[-- Attachment #2: Type: text/html, Size: 3045 bytes --]

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] version: 24.03-rc0
  2023-11-30  9:30  0%   ` Ferruh Yigit
@ 2023-11-30  9:32  0%     ` David Marchand
  0 siblings, 0 replies; 200+ results
From: David Marchand @ 2023-11-30  9:32 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: dev, thomas, Aaron Conole, Michael Santana, Andrew Rybchenko,
	Ajit Khaparde, Qi Zhang, Jerin Jacob Kollanukkaran,
	Raslan Darawsheh, Maxime Coquelin, Akhil Goyal

On Thu, Nov 30, 2023 at 10:30 AM Ferruh Yigit <ferruh.yigit@amd.com> wrote:
>
> On 11/30/2023 9:23 AM, David Marchand wrote:
> > On Wed, Nov 29, 2023 at 5:20 PM David Marchand
> > <david.marchand@redhat.com> wrote:
> >>
> >> Start a new release cycle with empty release notes.
> >> Bump version and ABI minor.
> >> Bump libabigail from 2.1 to 2.4 and enable ABI checks.
> >>
> >> Signed-off-by: David Marchand <david.marchand@redhat.com>
> >
> > Applied, thanks.
> >
> > Copying subtree maintainers, and ci@ mailing list.
> > As a result of the discussion on the ci ml
> > (http://inbox.dpdk.org/ci/CAJvnSUB2zXmHcdZC4rLruRm75MYOHJuWFUTtk8GNVRedfP_xXQ@mail.gmail.com/T/#t),
> > we worked on setting up some automatic mirroring of dpdk.org
> > repositories to the github DPDK repository.
> >
> >
> > What it means:
> > - for the https://dpdk.org/git/dpdk repository, all the branches and
> > tags are mirrored to https://github.com/DPDK/dpdk as it was done so
> > far,
> > - for the https://git.dpdk.org/next/dpdk-next-* repositories, only
> > branches named "main", "staging" or "for-*" are mirrored to
> > https://github.com/DPDK/dpdk with a prefix.
> >   One example: changes to the for-main branch of the dpdk-next-crypto
> > repo will be mirrored to a github branch next-crypto-for-main
> >
> >
> > For subtree maintainers.
> >
> > It should change nothing to you guys.
> > Please rebase your trees on v24.03-rc0 and push it to dpdk.org.
> > And then double check that the mirror happened (looking at git push
> > output, and checking https://github.com/DPDK/dpdk/branches).
> > If you hit some issue, ping me.
> >
>
> I force push a lot, is mirroring configured to cope with this?

It is supposed to be handled, yes.


-- 
David Marchand


^ permalink raw reply	[relevance 0%]

* Re: [PATCH] version: 24.03-rc0
  2023-11-30  9:23  3% ` David Marchand
@ 2023-11-30  9:30  0%   ` Ferruh Yigit
  2023-11-30  9:32  0%     ` David Marchand
  2023-11-30 18:33  0%   ` Patrick Robb
  1 sibling, 1 reply; 200+ results
From: Ferruh Yigit @ 2023-11-30  9:30 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, thomas, Aaron Conole, Michael Santana, Andrew Rybchenko,
	Ajit Khaparde, Qi Zhang, Jerin Jacob Kollanukkaran,
	Raslan Darawsheh, Maxime Coquelin, Akhil Goyal

On 11/30/2023 9:23 AM, David Marchand wrote:
> On Wed, Nov 29, 2023 at 5:20 PM David Marchand
> <david.marchand@redhat.com> wrote:
>>
>> Start a new release cycle with empty release notes.
>> Bump version and ABI minor.
>> Bump libabigail from 2.1 to 2.4 and enable ABI checks.
>>
>> Signed-off-by: David Marchand <david.marchand@redhat.com>
> 
> Applied, thanks.
> 
> Copying subtree maintainers, and ci@ mailing list.
> As a result of the discussion on the ci ml
> (http://inbox.dpdk.org/ci/CAJvnSUB2zXmHcdZC4rLruRm75MYOHJuWFUTtk8GNVRedfP_xXQ@mail.gmail.com/T/#t),
> we worked on setting up some automatic mirroring of dpdk.org
> repositories to the github DPDK repository.
> 
> 
> What it means:
> - for the https://dpdk.org/git/dpdk repository, all the branches and
> tags are mirrored to https://github.com/DPDK/dpdk as it was done so
> far,
> - for the https://git.dpdk.org/next/dpdk-next-* repositories, only
> branches named "main", "staging" or "for-*" are mirrored to
> https://github.com/DPDK/dpdk with a prefix.
>   One example: changes to the for-main branch of the dpdk-next-crypto
> repo will be mirrored to a github branch next-crypto-for-main
> 
> 
> For subtree maintainers.
> 
> It should change nothing to you guys.
> Please rebase your trees on v24.03-rc0 and push it to dpdk.org.
> And then double check that the mirror happened (looking at git push
> output, and checking https://github.com/DPDK/dpdk/branches).
> If you hit some issue, ping me.
> 

I force push a lot, is mirroring configured to cope with this?


> 
> For CI.
> 
> This is more a fyi, there will be some delay before all mirrors are
> up, so for now, don't swap the next-* repositories in your script yet.
> However, one action that can be taken as v24.03-rc0 is pushed is to
> re-enable ABI checks against the v23.11 official tag.
> 
> 
> Questions?
> 
> 


^ permalink raw reply	[relevance 0%]

* Re: [PATCH] version: 24.03-rc0
  2023-11-29 16:18 11% [PATCH] version: 24.03-rc0 David Marchand
@ 2023-11-30  9:23  3% ` David Marchand
  2023-11-30  9:30  0%   ` Ferruh Yigit
  2023-11-30 18:33  0%   ` Patrick Robb
  0 siblings, 2 replies; 200+ results
From: David Marchand @ 2023-11-30  9:23 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, thomas, Aaron Conole, Michael Santana, Ferruh Yigit,
	Andrew Rybchenko, Ajit Khaparde, Qi Zhang,
	Jerin Jacob Kollanukkaran, Raslan Darawsheh, Maxime Coquelin,
	Akhil Goyal

On Wed, Nov 29, 2023 at 5:20 PM David Marchand
<david.marchand@redhat.com> wrote:
>
> Start a new release cycle with empty release notes.
> Bump version and ABI minor.
> Bump libabigail from 2.1 to 2.4 and enable ABI checks.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>

Applied, thanks.

Copying subtree maintainers, and ci@ mailing list.
As a result of the discussion on the ci ml
(http://inbox.dpdk.org/ci/CAJvnSUB2zXmHcdZC4rLruRm75MYOHJuWFUTtk8GNVRedfP_xXQ@mail.gmail.com/T/#t),
we worked on setting up some automatic mirroring of dpdk.org
repositories to the github DPDK repository.


What it means:
- for the https://dpdk.org/git/dpdk repository, all the branches and
tags are mirrored to https://github.com/DPDK/dpdk as it was done so
far,
- for the https://git.dpdk.org/next/dpdk-next-* repositories, only
branches named "main", "staging" or "for-*" are mirrored to
https://github.com/DPDK/dpdk with a prefix.
  One example: changes to the for-main branch of the dpdk-next-crypto
repo will be mirrored to a github branch next-crypto-for-main


For subtree maintainers.

It should change nothing to you guys.
Please rebase your trees on v24.03-rc0 and push it to dpdk.org.
And then double check that the mirror happened (looking at git push
output, and checking https://github.com/DPDK/dpdk/branches).
If you hit some issue, ping me.


For CI.

This is more a fyi, there will be some delay before all mirrors are
up, so for now, don't swap the next-* repositories in your script yet.
However, one action that can be taken as v24.03-rc0 is pushed is to
re-enable ABI checks against the v23.11 official tag.


Questions?


-- 
David Marchand


^ permalink raw reply	[relevance 3%]

* [PATCH v5 01/19] mbuf: replace term sanity check
  @ 2023-11-29 17:25  2%   ` Stephen Hemminger
  0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2023-11-29 17:25 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, Andrew Rybchenko, Morten Brørup,
	Steven Webster, Matt Peters

Replace rte_mbuf_sanity_check() with rte_mbuf_verify()
to match the similar macro RTE_VERIFY() in rte_debug.h

The term sanity check is on the Tier 2 list of words
that should be replaced.

Note: the rte_mbuf_verify() function is added without
the experimental tag since it is intended as direct replacement
for old function name.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Acked-by: Morten Brørup <mb@smartsharesystems.com>
---
 app/test/test_mbuf.c                 | 28 +++++------
 doc/guides/prog_guide/mbuf_lib.rst   |  4 +-
 doc/guides/rel_notes/deprecation.rst |  3 ++
 drivers/net/avp/avp_ethdev.c         | 18 +++----
 drivers/net/sfc/sfc_ef100_rx.c       |  6 +--
 drivers/net/sfc/sfc_ef10_essb_rx.c   |  4 +-
 drivers/net/sfc/sfc_ef10_rx.c        |  4 +-
 drivers/net/sfc/sfc_rx.c             |  2 +-
 examples/ipv4_multicast/main.c       |  2 +-
 lib/mbuf/rte_mbuf.c                  | 23 +++++----
 lib/mbuf/rte_mbuf.h                  | 71 +++++++++++++++-------------
 lib/mbuf/version.map                 |  1 +
 12 files changed, 90 insertions(+), 76 deletions(-)

diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index d7393df7eb5d..261c6e5d71e9 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -261,8 +261,8 @@ test_one_pktmbuf(struct rte_mempool *pktmbuf_pool)
 		GOTO_FAIL("Buffer should be continuous");
 	memset(hdr, 0x55, MBUF_TEST_HDR2_LEN);
 
-	rte_mbuf_sanity_check(m, 1);
-	rte_mbuf_sanity_check(m, 0);
+	rte_mbuf_verify(m, 1);
+	rte_mbuf_verify(m, 0);
 	rte_pktmbuf_dump(stdout, m, 0);
 
 	/* this prepend should fail */
@@ -1161,7 +1161,7 @@ test_refcnt_mbuf(void)
 
 #ifdef RTE_EXEC_ENV_WINDOWS
 static int
-test_failing_mbuf_sanity_check(struct rte_mempool *pktmbuf_pool)
+test_failing_mbuf_verify(struct rte_mempool *pktmbuf_pool)
 {
 	RTE_SET_USED(pktmbuf_pool);
 	return TEST_SKIPPED;
@@ -1180,12 +1180,12 @@ mbuf_check_pass(struct rte_mbuf *buf)
 }
 
 static int
-test_failing_mbuf_sanity_check(struct rte_mempool *pktmbuf_pool)
+test_failing_mbuf_verify(struct rte_mempool *pktmbuf_pool)
 {
 	struct rte_mbuf *buf;
 	struct rte_mbuf badbuf;
 
-	printf("Checking rte_mbuf_sanity_check for failure conditions\n");
+	printf("Checking rte_mbuf_verify for failure conditions\n");
 
 	/* get a good mbuf to use to make copies */
 	buf = rte_pktmbuf_alloc(pktmbuf_pool);
@@ -1707,7 +1707,7 @@ test_mbuf_validate_tx_offload(const char *test_name,
 		GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("%s: Bad packet length\n", __func__);
-	rte_mbuf_sanity_check(m, 0);
+	rte_mbuf_verify(m, 0);
 	m->ol_flags = ol_flags;
 	m->tso_segsz = segsize;
 	ret = rte_validate_tx_offload(m);
@@ -1914,7 +1914,7 @@ test_pktmbuf_read(struct rte_mempool *pktmbuf_pool)
 		GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("%s: Bad packet length\n", __func__);
-	rte_mbuf_sanity_check(m, 0);
+	rte_mbuf_verify(m, 0);
 
 	data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN2);
 	if (data == NULL)
@@ -1963,7 +1963,7 @@ test_pktmbuf_read_from_offset(struct rte_mempool *pktmbuf_pool)
 
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("%s: Bad packet length\n", __func__);
-	rte_mbuf_sanity_check(m, 0);
+	rte_mbuf_verify(m, 0);
 
 	/* prepend an ethernet header */
 	hdr = (struct ether_hdr *)rte_pktmbuf_prepend(m, hdr_len);
@@ -2108,7 +2108,7 @@ create_packet(struct rte_mempool *pktmbuf_pool,
 			GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
 		if (rte_pktmbuf_pkt_len(pkt_seg) != 0)
 			GOTO_FAIL("%s: Bad packet length\n", __func__);
-		rte_mbuf_sanity_check(pkt_seg, 0);
+		rte_mbuf_verify(pkt_seg, 0);
 		/* Add header only for the first segment */
 		if (test_data->flags == MBUF_HEADER && seg == 0) {
 			hdr_len = sizeof(struct rte_ether_hdr);
@@ -2320,7 +2320,7 @@ test_pktmbuf_ext_shinfo_init_helper(struct rte_mempool *pktmbuf_pool)
 		GOTO_FAIL("%s: mbuf allocation failed!\n", __func__);
 	if (rte_pktmbuf_pkt_len(m) != 0)
 		GOTO_FAIL("%s: Bad packet length\n", __func__);
-	rte_mbuf_sanity_check(m, 0);
+	rte_mbuf_verify(m, 0);
 
 	ext_buf_addr = rte_malloc("External buffer", buf_len,
 			RTE_CACHE_LINE_SIZE);
@@ -2484,8 +2484,8 @@ test_pktmbuf_ext_pinned_buffer(struct rte_mempool *std_pool)
 		GOTO_FAIL("%s: test_pktmbuf_copy(pinned) failed\n",
 			  __func__);
 
-	if (test_failing_mbuf_sanity_check(pinned_pool) < 0)
-		GOTO_FAIL("%s: test_failing_mbuf_sanity_check(pinned)"
+	if (test_failing_mbuf_verify(pinned_pool) < 0)
+		GOTO_FAIL("%s: test_failing_mbuf_verify(pinned)"
 			  " failed\n", __func__);
 
 	if (test_mbuf_linearize_check(pinned_pool) < 0)
@@ -2859,8 +2859,8 @@ test_mbuf(void)
 		goto err;
 	}
 
-	if (test_failing_mbuf_sanity_check(pktmbuf_pool) < 0) {
-		printf("test_failing_mbuf_sanity_check() failed\n");
+	if (test_failing_mbuf_verify(pktmbuf_pool) < 0) {
+		printf("test_failing_mbuf_verify() failed\n");
 		goto err;
 	}
 
diff --git a/doc/guides/prog_guide/mbuf_lib.rst b/doc/guides/prog_guide/mbuf_lib.rst
index 049357c75563..0accb51a98c7 100644
--- a/doc/guides/prog_guide/mbuf_lib.rst
+++ b/doc/guides/prog_guide/mbuf_lib.rst
@@ -266,8 +266,8 @@ can be found in several of the sample applications, for example, the IPv4 Multic
 Debug
 -----
 
-In debug mode, the functions of the mbuf library perform sanity checks before any operation (such as, buffer corruption,
-bad type, and so on).
+In debug mode, the functions of the mbuf library perform consistency checks
+before any operation (such as, buffer corruption, bad type, and so on).
 
 Use Cases
 ---------
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 81b93515cbd9..1e1544b5b644 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -146,3 +146,6 @@ Deprecation Notices
   will be deprecated and subsequently removed in DPDK 24.11 release.
   Before this, the new port library API (functions rte_swx_port_*)
   will gradually transition from experimental to stable status.
+
+* mbuf: The function ``rte_mbuf_sanity_check`` is deprecated.
+  Use the new function ``rte_mbuf_verify`` instead.
diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c
index 53d9e38c939b..ae76fad84948 100644
--- a/drivers/net/avp/avp_ethdev.c
+++ b/drivers/net/avp/avp_ethdev.c
@@ -1231,7 +1231,7 @@ _avp_mac_filter(struct avp_dev *avp, struct rte_mbuf *m)
 
 #ifdef RTE_LIBRTE_AVP_DEBUG_BUFFERS
 static inline void
-__avp_dev_buffer_sanity_check(struct avp_dev *avp, struct rte_avp_desc *buf)
+__avp_dev_buffer_check(struct avp_dev *avp, struct rte_avp_desc *buf)
 {
 	struct rte_avp_desc *first_buf;
 	struct rte_avp_desc *pkt_buf;
@@ -1272,12 +1272,12 @@ __avp_dev_buffer_sanity_check(struct avp_dev *avp, struct rte_avp_desc *buf)
 			  first_buf->pkt_len, pkt_len);
 }
 
-#define avp_dev_buffer_sanity_check(a, b) \
-	__avp_dev_buffer_sanity_check((a), (b))
+#define avp_dev_buffer_check(a, b) \
+	__avp_dev_buffer_check((a), (b))
 
 #else /* RTE_LIBRTE_AVP_DEBUG_BUFFERS */
 
-#define avp_dev_buffer_sanity_check(a, b) do {} while (0)
+#define avp_dev_buffer_check(a, b) do {} while (0)
 
 #endif
 
@@ -1302,7 +1302,7 @@ avp_dev_copy_from_buffers(struct avp_dev *avp,
 	void *pkt_data;
 	unsigned int i;
 
-	avp_dev_buffer_sanity_check(avp, buf);
+	avp_dev_buffer_check(avp, buf);
 
 	/* setup the first source buffer */
 	pkt_buf = avp_dev_translate_buffer(avp, buf);
@@ -1370,7 +1370,7 @@ avp_dev_copy_from_buffers(struct avp_dev *avp,
 	rte_pktmbuf_pkt_len(m) = total_length;
 	m->vlan_tci = vlan_tci;
 
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	return m;
 }
@@ -1614,7 +1614,7 @@ avp_dev_copy_to_buffers(struct avp_dev *avp,
 	char *pkt_data;
 	unsigned int i;
 
-	__rte_mbuf_sanity_check(mbuf, 1);
+	__rte_mbuf_verify(mbuf, 1);
 
 	m = mbuf;
 	src_offset = 0;
@@ -1680,7 +1680,7 @@ avp_dev_copy_to_buffers(struct avp_dev *avp,
 		first_buf->vlan_tci = mbuf->vlan_tci;
 	}
 
-	avp_dev_buffer_sanity_check(avp, buffers[0]);
+	avp_dev_buffer_check(avp, buffers[0]);
 
 	return total_length;
 }
@@ -1798,7 +1798,7 @@ avp_xmit_scattered_pkts(void *tx_queue,
 
 #ifdef RTE_LIBRTE_AVP_DEBUG_BUFFERS
 	for (i = 0; i < nb_pkts; i++)
-		avp_dev_buffer_sanity_check(avp, tx_bufs[i]);
+		avp_dev_buffer_check(avp, tx_bufs[i]);
 #endif
 
 	/* send the packets */
diff --git a/drivers/net/sfc/sfc_ef100_rx.c b/drivers/net/sfc/sfc_ef100_rx.c
index 2677003da326..8199b56f2740 100644
--- a/drivers/net/sfc/sfc_ef100_rx.c
+++ b/drivers/net/sfc/sfc_ef100_rx.c
@@ -179,7 +179,7 @@ sfc_ef100_rx_qrefill(struct sfc_ef100_rxq *rxq)
 			struct sfc_ef100_rx_sw_desc *rxd;
 			rte_iova_t dma_addr;
 
-			__rte_mbuf_raw_sanity_check(m);
+			__rte_mbuf_raw_verify(m);
 
 			dma_addr = rte_mbuf_data_iova_default(m);
 			if (rxq->flags & SFC_EF100_RXQ_NIC_DMA_MAP) {
@@ -551,7 +551,7 @@ sfc_ef100_rx_process_ready_pkts(struct sfc_ef100_rxq *rxq,
 		rxq->ready_pkts--;
 
 		pkt = sfc_ef100_rx_next_mbuf(rxq);
-		__rte_mbuf_raw_sanity_check(pkt);
+		__rte_mbuf_raw_verify(pkt);
 
 		RTE_BUILD_BUG_ON(sizeof(pkt->rearm_data[0]) !=
 				 sizeof(rxq->rearm_data));
@@ -575,7 +575,7 @@ sfc_ef100_rx_process_ready_pkts(struct sfc_ef100_rxq *rxq,
 			struct rte_mbuf *seg;
 
 			seg = sfc_ef100_rx_next_mbuf(rxq);
-			__rte_mbuf_raw_sanity_check(seg);
+			__rte_mbuf_raw_verify(seg);
 
 			seg->data_off = RTE_PKTMBUF_HEADROOM;
 
diff --git a/drivers/net/sfc/sfc_ef10_essb_rx.c b/drivers/net/sfc/sfc_ef10_essb_rx.c
index 78bd430363b1..74647e2792b1 100644
--- a/drivers/net/sfc/sfc_ef10_essb_rx.c
+++ b/drivers/net/sfc/sfc_ef10_essb_rx.c
@@ -125,7 +125,7 @@ sfc_ef10_essb_next_mbuf(const struct sfc_ef10_essb_rxq *rxq,
 	struct rte_mbuf *m;
 
 	m = (struct rte_mbuf *)((uintptr_t)mbuf + rxq->buf_stride);
-	__rte_mbuf_raw_sanity_check(m);
+	__rte_mbuf_raw_verify(m);
 	return m;
 }
 
@@ -136,7 +136,7 @@ sfc_ef10_essb_mbuf_by_index(const struct sfc_ef10_essb_rxq *rxq,
 	struct rte_mbuf *m;
 
 	m = (struct rte_mbuf *)((uintptr_t)mbuf + idx * rxq->buf_stride);
-	__rte_mbuf_raw_sanity_check(m);
+	__rte_mbuf_raw_verify(m);
 	return m;
 }
 
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 30a320d0791c..72b03b3bba7a 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -148,7 +148,7 @@ sfc_ef10_rx_qrefill(struct sfc_ef10_rxq *rxq)
 			struct sfc_ef10_rx_sw_desc *rxd;
 			rte_iova_t phys_addr;
 
-			__rte_mbuf_raw_sanity_check(m);
+			__rte_mbuf_raw_verify(m);
 
 			SFC_ASSERT((id & ~ptr_mask) == 0);
 			rxd = &rxq->sw_ring[id];
@@ -297,7 +297,7 @@ sfc_ef10_rx_process_event(struct sfc_ef10_rxq *rxq, efx_qword_t rx_ev,
 		rxd = &rxq->sw_ring[pending++ & ptr_mask];
 		m = rxd->mbuf;
 
-		__rte_mbuf_raw_sanity_check(m);
+		__rte_mbuf_raw_verify(m);
 
 		m->data_off = RTE_PKTMBUF_HEADROOM;
 		rte_pktmbuf_data_len(m) = seg_len;
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 1dde2c111001..645c8643d1c1 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -120,7 +120,7 @@ sfc_efx_rx_qrefill(struct sfc_efx_rxq *rxq)
 		     ++i, id = (id + 1) & rxq->ptr_mask) {
 			m = objs[i];
 
-			__rte_mbuf_raw_sanity_check(m);
+			__rte_mbuf_raw_verify(m);
 
 			rxd = &rxq->sw_desc[id];
 			rxd->mbuf = m;
diff --git a/examples/ipv4_multicast/main.c b/examples/ipv4_multicast/main.c
index 6d0a8501eff5..f39658f4e249 100644
--- a/examples/ipv4_multicast/main.c
+++ b/examples/ipv4_multicast/main.c
@@ -258,7 +258,7 @@ mcast_out_pkt(struct rte_mbuf *pkt, int use_clone)
 	hdr->pkt_len = (uint16_t)(hdr->data_len + pkt->pkt_len);
 	hdr->nb_segs = pkt->nb_segs + 1;
 
-	__rte_mbuf_sanity_check(hdr, 1);
+	__rte_mbuf_verify(hdr, 1);
 	return hdr;
 }
 /* >8 End of mcast_out_kt. */
diff --git a/lib/mbuf/rte_mbuf.c b/lib/mbuf/rte_mbuf.c
index 686e797c80c4..91cb2f84f6a1 100644
--- a/lib/mbuf/rte_mbuf.c
+++ b/lib/mbuf/rte_mbuf.c
@@ -363,9 +363,9 @@ rte_pktmbuf_pool_create_extbuf(const char *name, unsigned int n,
 	return mp;
 }
 
-/* do some sanity checks on a mbuf: panic if it fails */
+/* do some checks on a mbuf: panic if it fails */
 void
-rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
+rte_mbuf_verify(const struct rte_mbuf *m, int is_header)
 {
 	const char *reason;
 
@@ -373,6 +373,13 @@ rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
 		rte_panic("%s\n", reason);
 }
 
+/* For ABI compatibility, to be removed in next release */
+void
+rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
+{
+	rte_mbuf_verify(m, is_header);
+}
+
 int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
 		   const char **reason)
 {
@@ -492,7 +499,7 @@ void rte_pktmbuf_free_bulk(struct rte_mbuf **mbufs, unsigned int count)
 		if (unlikely(m == NULL))
 			continue;
 
-		__rte_mbuf_sanity_check(m, 1);
+		__rte_mbuf_verify(m, 1);
 
 		do {
 			m_next = m->next;
@@ -542,7 +549,7 @@ rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp)
 		return NULL;
 	}
 
-	__rte_mbuf_sanity_check(mc, 1);
+	__rte_mbuf_verify(mc, 1);
 	return mc;
 }
 
@@ -592,7 +599,7 @@ rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp,
 	struct rte_mbuf *mc, *m_last, **prev;
 
 	/* garbage in check */
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	/* check for request to copy at offset past end of mbuf */
 	if (unlikely(off >= m->pkt_len))
@@ -656,7 +663,7 @@ rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp,
 	}
 
 	/* garbage out check */
-	__rte_mbuf_sanity_check(mc, 1);
+	__rte_mbuf_verify(mc, 1);
 	return mc;
 }
 
@@ -667,7 +674,7 @@ rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len)
 	unsigned int len;
 	unsigned int nb_segs;
 
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	fprintf(f, "dump mbuf at %p, iova=%#" PRIx64 ", buf_len=%u\n", m, rte_mbuf_iova_get(m),
 		m->buf_len);
@@ -685,7 +692,7 @@ rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len)
 	nb_segs = m->nb_segs;
 
 	while (m && nb_segs != 0) {
-		__rte_mbuf_sanity_check(m, 0);
+		__rte_mbuf_verify(m, 0);
 
 		fprintf(f, "  segment at %p, data=%p, len=%u, off=%u, refcnt=%u\n",
 			m, rte_pktmbuf_mtod(m, void *),
diff --git a/lib/mbuf/rte_mbuf.h b/lib/mbuf/rte_mbuf.h
index 286b32b788a5..380663a0893b 100644
--- a/lib/mbuf/rte_mbuf.h
+++ b/lib/mbuf/rte_mbuf.h
@@ -339,13 +339,13 @@ rte_pktmbuf_priv_flags(struct rte_mempool *mp)
 
 #ifdef RTE_LIBRTE_MBUF_DEBUG
 
-/**  check mbuf type in debug mode */
-#define __rte_mbuf_sanity_check(m, is_h) rte_mbuf_sanity_check(m, is_h)
+/**  do mbuf type in debug mode */
+#define __rte_mbuf_verify(m, is_h) rte_mbuf_verify(m, is_h)
 
 #else /*  RTE_LIBRTE_MBUF_DEBUG */
 
-/**  check mbuf type in debug mode */
-#define __rte_mbuf_sanity_check(m, is_h) do { } while (0)
+/**  ignore mbuf checks if not in debug mode */
+#define __rte_mbuf_verify(m, is_h) do { } while (0)
 
 #endif /*  RTE_LIBRTE_MBUF_DEBUG */
 
@@ -514,10 +514,9 @@ rte_mbuf_ext_refcnt_update(struct rte_mbuf_ext_shared_info *shinfo,
 
 
 /**
- * Sanity checks on an mbuf.
+ * Check that the mbuf is valid and panic if corrupted.
  *
- * Check the consistency of the given mbuf. The function will cause a
- * panic if corruption is detected.
+ * Acts assertion that mbuf is consistent. If not it calls rte_panic().
  *
  * @param m
  *   The mbuf to be checked.
@@ -526,13 +525,17 @@ rte_mbuf_ext_refcnt_update(struct rte_mbuf_ext_shared_info *shinfo,
  *   of a packet (in this case, some fields like nb_segs are not checked)
  */
 void
+rte_mbuf_verify(const struct rte_mbuf *m, int is_header);
+
+/* Older deprecated name for rte_mbuf_verify() */
+void __rte_deprecated
 rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header);
 
 /**
- * Sanity checks on a mbuf.
+ * Do consistency checks on a mbuf.
  *
- * Almost like rte_mbuf_sanity_check(), but this function gives the reason
- * if corruption is detected rather than panic.
+ * Check the consistency of the given mbuf and if not valid
+ * return the reason.
  *
  * @param m
  *   The mbuf to be checked.
@@ -551,7 +554,7 @@ int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
 		   const char **reason);
 
 /**
- * Sanity checks on a reinitialized mbuf in debug mode.
+ * Do checks on a reinitialized mbuf in debug mode.
  *
  * Check the consistency of the given reinitialized mbuf.
  * The function will cause a panic if corruption is detected.
@@ -563,16 +566,16 @@ int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
  *   The mbuf to be checked.
  */
 static __rte_always_inline void
-__rte_mbuf_raw_sanity_check(__rte_unused const struct rte_mbuf *m)
+__rte_mbuf_raw_verify(__rte_unused const struct rte_mbuf *m)
 {
 	RTE_ASSERT(rte_mbuf_refcnt_read(m) == 1);
 	RTE_ASSERT(m->next == NULL);
 	RTE_ASSERT(m->nb_segs == 1);
-	__rte_mbuf_sanity_check(m, 0);
+	__rte_mbuf_verify(m, 0);
 }
 
 /** For backwards compatibility. */
-#define MBUF_RAW_ALLOC_CHECK(m) __rte_mbuf_raw_sanity_check(m)
+#define MBUF_RAW_ALLOC_CHECK(m) __rte_mbuf_raw_verify(m)
 
 /**
  * Allocate an uninitialized mbuf from mempool *mp*.
@@ -599,7 +602,7 @@ static inline struct rte_mbuf *rte_mbuf_raw_alloc(struct rte_mempool *mp)
 
 	if (rte_mempool_get(mp, (void **)&m) < 0)
 		return NULL;
-	__rte_mbuf_raw_sanity_check(m);
+	__rte_mbuf_raw_verify(m);
 	return m;
 }
 
@@ -622,7 +625,7 @@ rte_mbuf_raw_free(struct rte_mbuf *m)
 {
 	RTE_ASSERT(!RTE_MBUF_CLONED(m) &&
 		  (!RTE_MBUF_HAS_EXTBUF(m) || RTE_MBUF_HAS_PINNED_EXTBUF(m)));
-	__rte_mbuf_raw_sanity_check(m);
+	__rte_mbuf_raw_verify(m);
 	rte_mempool_put(m->pool, m);
 }
 
@@ -885,7 +888,7 @@ static inline void rte_pktmbuf_reset(struct rte_mbuf *m)
 	rte_pktmbuf_reset_headroom(m);
 
 	m->data_len = 0;
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 }
 
 /**
@@ -941,22 +944,22 @@ static inline int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool,
 	switch (count % 4) {
 	case 0:
 		while (idx != count) {
-			__rte_mbuf_raw_sanity_check(mbufs[idx]);
+			__rte_mbuf_raw_verify(mbufs[idx]);
 			rte_pktmbuf_reset(mbufs[idx]);
 			idx++;
 			/* fall-through */
 	case 3:
-			__rte_mbuf_raw_sanity_check(mbufs[idx]);
+			__rte_mbuf_raw_verify(mbufs[idx]);
 			rte_pktmbuf_reset(mbufs[idx]);
 			idx++;
 			/* fall-through */
 	case 2:
-			__rte_mbuf_raw_sanity_check(mbufs[idx]);
+			__rte_mbuf_raw_verify(mbufs[idx]);
 			rte_pktmbuf_reset(mbufs[idx]);
 			idx++;
 			/* fall-through */
 	case 1:
-			__rte_mbuf_raw_sanity_check(mbufs[idx]);
+			__rte_mbuf_raw_verify(mbufs[idx]);
 			rte_pktmbuf_reset(mbufs[idx]);
 			idx++;
 			/* fall-through */
@@ -1184,8 +1187,8 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
 	mi->pkt_len = mi->data_len;
 	mi->nb_segs = 1;
 
-	__rte_mbuf_sanity_check(mi, 1);
-	__rte_mbuf_sanity_check(m, 0);
+	__rte_mbuf_verify(mi, 1);
+	__rte_mbuf_verify(m, 0);
 }
 
 /**
@@ -1340,7 +1343,7 @@ static inline int __rte_pktmbuf_pinned_extbuf_decref(struct rte_mbuf *m)
 static __rte_always_inline struct rte_mbuf *
 rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
 {
-	__rte_mbuf_sanity_check(m, 0);
+	__rte_mbuf_verify(m, 0);
 
 	if (likely(rte_mbuf_refcnt_read(m) == 1)) {
 
@@ -1411,7 +1414,7 @@ static inline void rte_pktmbuf_free(struct rte_mbuf *m)
 	struct rte_mbuf *m_next;
 
 	if (m != NULL)
-		__rte_mbuf_sanity_check(m, 1);
+		__rte_mbuf_verify(m, 1);
 
 	while (m != NULL) {
 		m_next = m->next;
@@ -1492,7 +1495,7 @@ rte_pktmbuf_copy(const struct rte_mbuf *m, struct rte_mempool *mp,
  */
 static inline void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
 {
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	do {
 		rte_mbuf_refcnt_update(m, v);
@@ -1509,7 +1512,7 @@ static inline void rte_pktmbuf_refcnt_update(struct rte_mbuf *m, int16_t v)
  */
 static inline uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
 {
-	__rte_mbuf_sanity_check(m, 0);
+	__rte_mbuf_verify(m, 0);
 	return m->data_off;
 }
 
@@ -1523,7 +1526,7 @@ static inline uint16_t rte_pktmbuf_headroom(const struct rte_mbuf *m)
  */
 static inline uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
 {
-	__rte_mbuf_sanity_check(m, 0);
+	__rte_mbuf_verify(m, 0);
 	return (uint16_t)(m->buf_len - rte_pktmbuf_headroom(m) -
 			  m->data_len);
 }
@@ -1538,7 +1541,7 @@ static inline uint16_t rte_pktmbuf_tailroom(const struct rte_mbuf *m)
  */
 static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
 {
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 	while (m->next != NULL)
 		m = m->next;
 	return m;
@@ -1582,7 +1585,7 @@ static inline struct rte_mbuf *rte_pktmbuf_lastseg(struct rte_mbuf *m)
 static inline char *rte_pktmbuf_prepend(struct rte_mbuf *m,
 					uint16_t len)
 {
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	if (unlikely(len > rte_pktmbuf_headroom(m)))
 		return NULL;
@@ -1617,7 +1620,7 @@ static inline char *rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
 	void *tail;
 	struct rte_mbuf *m_last;
 
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	m_last = rte_pktmbuf_lastseg(m);
 	if (unlikely(len > rte_pktmbuf_tailroom(m_last)))
@@ -1645,7 +1648,7 @@ static inline char *rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
  */
 static inline char *rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
 {
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	if (unlikely(len > m->data_len))
 		return NULL;
@@ -1677,7 +1680,7 @@ static inline int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
 {
 	struct rte_mbuf *m_last;
 
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 
 	m_last = rte_pktmbuf_lastseg(m);
 	if (unlikely(len > m_last->data_len))
@@ -1699,7 +1702,7 @@ static inline int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len)
  */
 static inline int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m)
 {
-	__rte_mbuf_sanity_check(m, 1);
+	__rte_mbuf_verify(m, 1);
 	return m->nb_segs == 1;
 }
 
diff --git a/lib/mbuf/version.map b/lib/mbuf/version.map
index daa65e2bbdb2..c85370e430b2 100644
--- a/lib/mbuf/version.map
+++ b/lib/mbuf/version.map
@@ -31,6 +31,7 @@ DPDK_24 {
 	rte_mbuf_set_platform_mempool_ops;
 	rte_mbuf_set_user_mempool_ops;
 	rte_mbuf_user_mempool_ops;
+	rte_mbuf_verify;
 	rte_pktmbuf_clone;
 	rte_pktmbuf_copy;
 	rte_pktmbuf_dump;
-- 
2.42.0


^ permalink raw reply	[relevance 2%]

* [PATCH] version: 24.03-rc0
@ 2023-11-29 16:18 11% David Marchand
  2023-11-30  9:23  3% ` David Marchand
  0 siblings, 1 reply; 200+ results
From: David Marchand @ 2023-11-29 16:18 UTC (permalink / raw)
  To: dev; +Cc: thomas, Aaron Conole, Michael Santana

Start a new release cycle with empty release notes.
Bump version and ABI minor.
Bump libabigail from 2.1 to 2.4 and enable ABI checks.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 .ci/linux-build.sh                     |   7 +-
 .github/workflows/build.yml            |   6 +-
 ABI_VERSION                            |   2 +-
 VERSION                                |   2 +-
 doc/guides/rel_notes/index.rst         |   1 +
 doc/guides/rel_notes/release_24_03.rst | 138 +++++++++++++++++++++++++
 6 files changed, 148 insertions(+), 8 deletions(-)
 create mode 100644 doc/guides/rel_notes/release_24_03.rst

diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh
index 4cdbe9b9e9..1edbf5afc2 100755
--- a/.ci/linux-build.sh
+++ b/.ci/linux-build.sh
@@ -12,15 +12,16 @@ fi
 install_libabigail() {
     version=$1
     instdir=$2
+    tarball=$version.tar.xz
 
-    wget -q "http://mirrors.kernel.org/sourceware/libabigail/${version}.tar.gz"
-    tar -xf ${version}.tar.gz
+    wget -q "http://mirrors.kernel.org/sourceware/libabigail/$tarball"
+    tar -xf $tarball
     cd $version && autoreconf -vfi && cd -
     mkdir $version/build
     cd $version/build && ../configure --prefix=$instdir && cd -
     make -C $version/build all install
     rm -rf $version
-    rm ${version}.tar.gz
+    rm $tarball
 }
 
 configure_coredump() {
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 272a6ffc7f..af514e9545 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -23,11 +23,11 @@ jobs:
       BUILD_EXAMPLES: ${{ contains(matrix.config.checks, 'examples') }}
       CC: ccache ${{ matrix.config.compiler }}
       DEF_LIB: ${{ matrix.config.library }}
-      LIBABIGAIL_VERSION: libabigail-2.1
+      LIBABIGAIL_VERSION: libabigail-2.4
       MINGW: ${{ matrix.config.cross == 'mingw' }}
       MINI: ${{ matrix.config.mini != '' }}
       PPC64LE: ${{ matrix.config.cross == 'ppc64le' }}
-      REF_GIT_TAG: none
+      REF_GIT_TAG: v23.11
       RISCV64: ${{ matrix.config.cross == 'riscv64' }}
       RUN_TESTS: ${{ contains(matrix.config.checks, 'tests') }}
       STDATOMIC: ${{ contains(matrix.config.checks, 'stdatomic') }}
@@ -47,7 +47,7 @@ jobs:
             checks: stdatomic
           - os: ubuntu-20.04
             compiler: gcc
-            checks: debug+doc+examples+tests
+            checks: abi+debug+doc+examples+tests
           - os: ubuntu-20.04
             compiler: clang
             checks: asan+doc+tests
diff --git a/ABI_VERSION b/ABI_VERSION
index d9133a54b6..0dad123924 100644
--- a/ABI_VERSION
+++ b/ABI_VERSION
@@ -1 +1 @@
-24.0
+24.1
diff --git a/VERSION b/VERSION
index 94c0153b26..04137136bd 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-23.11.0
+24.03.0-rc0
diff --git a/doc/guides/rel_notes/index.rst b/doc/guides/rel_notes/index.rst
index d072815279..88f2b30b03 100644
--- a/doc/guides/rel_notes/index.rst
+++ b/doc/guides/rel_notes/index.rst
@@ -8,6 +8,7 @@ Release Notes
     :maxdepth: 1
     :numbered:
 
+    release_24_03
     release_23_11
     release_23_07
     release_23_03
diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
new file mode 100644
index 0000000000..e9c9717706
--- /dev/null
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -0,0 +1,138 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+   Copyright 2023 The DPDK contributors
+
+.. include:: <isonum.txt>
+
+DPDK Release 24.03
+==================
+
+.. **Read this first.**
+
+   The text in the sections below explains how to update the release notes.
+
+   Use proper spelling, capitalization and punctuation in all sections.
+
+   Variable and config names should be quoted as fixed width text:
+   ``LIKE_THIS``.
+
+   Build the docs and view the output file to ensure the changes are correct::
+
+      ninja -C build doc
+      xdg-open build/doc/guides/html/rel_notes/release_24_03.html
+
+
+New Features
+------------
+
+.. This section should contain new features added in this release.
+   Sample format:
+
+   * **Add a title in the past tense with a full stop.**
+
+     Add a short 1-2 sentence description in the past tense.
+     The description should be enough to allow someone scanning
+     the release notes to understand the new feature.
+
+     If the feature adds a lot of sub-features you can use a bullet list
+     like this:
+
+     * Added feature foo to do something.
+     * Enhanced feature bar to do something else.
+
+     Refer to the previous release notes for examples.
+
+     Suggested order in release notes items:
+     * Core libs (EAL, mempool, ring, mbuf, buses)
+     * Device abstraction libs and PMDs (ordered alphabetically by vendor name)
+       - ethdev (lib, PMDs)
+       - cryptodev (lib, PMDs)
+       - eventdev (lib, PMDs)
+       - etc
+     * Other libs
+     * Apps, Examples, Tools (if significant)
+
+     This section is a comment. Do not overwrite or remove it.
+     Also, make sure to start the actual text at the margin.
+     =======================================================
+
+
+Removed Items
+-------------
+
+.. This section should contain removed items in this release. Sample format:
+
+   * Add a short 1-2 sentence description of the removed item
+     in the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =======================================================
+
+
+API Changes
+-----------
+
+.. This section should contain API changes. Sample format:
+
+   * sample: Add a short 1-2 sentence description of the API change
+     which was announced in the previous releases and made in this release.
+     Start with a scope label like "ethdev:".
+     Use fixed width quotes for ``function_names`` or ``struct_names``.
+     Use the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =======================================================
+
+
+ABI Changes
+-----------
+
+.. This section should contain ABI changes. Sample format:
+
+   * sample: Add a short 1-2 sentence description of the ABI change
+     which was announced in the previous releases and made in this release.
+     Start with a scope label like "ethdev:".
+     Use fixed width quotes for ``function_names`` or ``struct_names``.
+     Use the past tense.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =======================================================
+
+* No ABI change that would break compatibility with 23.11.
+
+
+Known Issues
+------------
+
+.. This section should contain new known issues in this release. Sample format:
+
+   * **Add title in present tense with full stop.**
+
+     Add a short 1-2 sentence description of the known issue
+     in the present tense. Add information on any known workarounds.
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =======================================================
+
+
+Tested Platforms
+----------------
+
+.. This section should contain a list of platforms that were tested
+   with this release.
+
+   The format is:
+
+   * <vendor> platform with <vendor> <type of devices> combinations
+
+     * List of CPU
+     * List of OS
+     * List of devices
+     * Other relevant details...
+
+   This section is a comment. Do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =======================================================
-- 
2.42.0


^ permalink raw reply	[relevance 11%]

* Re: [PATCH] doc: add sunset clause for experimental tag
  2023-11-29 15:27  4% [PATCH] doc: add sunset clause for experimental tag Stephen Hemminger
@ 2023-11-29 15:46  0% ` Bruce Richardson
  0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2023-11-29 15:46 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Wed, Nov 29, 2023 at 07:27:38AM -0800, Stephen Hemminger wrote:
> The experimental tag is intended as temporary to avoid having
> all of DPDK APIs as experimental and thereby rendering the
> stable policy as worthless.
> 
> Add some wording into the existing policy in doc.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  doc/guides/contributing/abi_policy.rst | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/doc/guides/contributing/abi_policy.rst b/doc/guides/contributing/abi_policy.rst
> index 5fd405258592..fbf26ea24fd6 100644
> --- a/doc/guides/contributing/abi_policy.rst
> +++ b/doc/guides/contributing/abi_policy.rst
> @@ -328,6 +328,16 @@ new APIs and start finding issues with them, new DPDK APIs will be automatically
>  marked as ``experimental`` to allow for a period of stabilization before they
>  become part of a tracked ABI version.
>  
> +The experimental tag has as limited lifetime (sunset provision).
> +It is expected to be removed in a future release.
> +The tag may be removed as soon as the second release with the new DPDK API.
> +After one year, the API must be stable and tag removed unless an
> +exception is approved by the technical board.
> +

We should also mention about the API being possibly removed or reworked.

> +For example, the symbol ``rte_flow_dev_dump`` was introduced
> +in 20.02 release as ``experimental``. The tag could have been removed
> +in 20.05 release, and should have been removed in 21.03 release.
> +
>  Note that marking an API as experimental is a multi step process.
>  To mark an API as experimental, the symbols which are desired to be exported
>  must be placed in an EXPERIMENTAL version block in the corresponding libraries'
> -- 
> 2.42.0
> 

^ permalink raw reply	[relevance 0%]

* [PATCH] doc: add sunset clause for experimental tag
@ 2023-11-29 15:27  4% Stephen Hemminger
  2023-11-29 15:46  0% ` Bruce Richardson
  0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2023-11-29 15:27 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The experimental tag is intended as temporary to avoid having
all of DPDK APIs as experimental and thereby rendering the
stable policy as worthless.

Add some wording into the existing policy in doc.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 doc/guides/contributing/abi_policy.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/doc/guides/contributing/abi_policy.rst b/doc/guides/contributing/abi_policy.rst
index 5fd405258592..fbf26ea24fd6 100644
--- a/doc/guides/contributing/abi_policy.rst
+++ b/doc/guides/contributing/abi_policy.rst
@@ -328,6 +328,16 @@ new APIs and start finding issues with them, new DPDK APIs will be automatically
 marked as ``experimental`` to allow for a period of stabilization before they
 become part of a tracked ABI version.
 
+The experimental tag has as limited lifetime (sunset provision).
+It is expected to be removed in a future release.
+The tag may be removed as soon as the second release with the new DPDK API.
+After one year, the API must be stable and tag removed unless an
+exception is approved by the technical board.
+
+For example, the symbol ``rte_flow_dev_dump`` was introduced
+in 20.02 release as ``experimental``. The tag could have been removed
+in 20.05 release, and should have been removed in 21.03 release.
+
 Note that marking an API as experimental is a multi step process.
 To mark an API as experimental, the symbols which are desired to be exported
 must be placed in an EXPERIMENTAL version block in the corresponding libraries'
-- 
2.42.0


^ permalink raw reply	[relevance 4%]

* DPDK 23.11 released
@ 2023-11-28 16:15  4% David Marchand
  0 siblings, 0 replies; 200+ results
From: David Marchand @ 2023-11-28 16:15 UTC (permalink / raw)
  To: announce; +Cc: Thomas Monjalon

A new major release is available:
    https://fast.dpdk.org/rel/dpdk-23.11.tar.xz

The number of commits has been stable for the 23.xx releases:
    1161 commits from 161 authors
    1647 files changed, 97078 insertions(+), 44688 deletions(-)

The branch 23.11 should be supported for three years,
making it recommended for system integration and deployment.

The new major ABI version is 24.
The next releases 24.03 and 24.07 will be ABI-compatible with 23.11.

Below are some highlights of this release:
    - build requires C11 compiler
    - early support of MSVC build
    - new atomic operations API
    - power management on AMD CPU
    - mbuf recycling
    - RSS algorithm management
    - maximum Rx buffer size
    - flow action type for P4-defined actions
    - flow group miss action
    - flow item for packet type matching
    - TLS record offload
    - security Rx inject
    - eventdev link profiles
    - eventdev adapter for dmadev
    - event dispatcher library
    - nfp vDPA driver
    - graph application
    - removed flow_classify library
    - removed KNI library and driver

More details in the release notes:
    https://doc.dpdk.org/guides/rel_notes/release_23_11.html


There are 40 new contributors (including authors, reviewers and testers).
Welcome to Alan Brady, Ales Musil, Andrey Ignatov, Artemy Kovalyov,
Chang Miao, Fengjiang Liu, Igor de Paula, Jayaprakash Shanmugam,
John Romein, Jonathan Erb, Jonathan Tsai, Josh Hay, Julian Grajkowski,
Karen Kelly, Kuan Xu, Madhu Chittim, Mahesh Adulla, Matthew Dirba,
Paul Szczepanek, Peter Nilsson, Sam Andrew, Sampath Peechu,
Saurabh Singhal, Shailendra Bhatnagar, Shihong Wang, Shubham Rohila,
Shujing Dong, Sibaranjan Pattnayak, Sinan Kaya, Sivaprasad Tummala,
Sivaramakrishnan Venkat, Timothy Miskell, Tomer Shmilovich, Trevor Tao,
Trevor Tao, Vamsi Krishna Attunuru, Wajeeh Atrash, Wei Hu,
Xiaoming Jiang, Zhenning Xiao.

Below is the number of commits per employer (with authors count):
    240    Marvell (29)
    203    Intel (39)
    140    Corigine (9)
    139    NVIDIA (25)
     96    Huawei (4)
     90    Red Hat (4)
     71    Microsoft (5)
     64    stephen@networkplumber.org (1)
     24    AMD (9)
     16    NXP (4)
     13    Trustnet (1)
     12    Arm (5)
        ...

A big thank to all courageous people who took on the non rewarding task
of reviewing other's job.
Based on Reviewed-by and Acked-by tags, the top non-PMD reviewers are:
    78     Morten Brørup <mb@smartsharesystems.com>
    60     Bruce Richardson <bruce.richardson@intel.com>
    55     David Marchand <david.marchand@redhat.com>
    47     Ferruh Yigit <ferruh.yigit@amd.com>
    33     Konstantin Ananyev <konstantin.v.ananyev@yandex.ru>
    29     Maxime Coquelin <maxime.coquelin@redhat.com>
    27     Tyler Retzlaff <roretzla@linux.microsoft.com>
    21     Chengwen Feng <fengchengwen@huawei.com>
    20     Stephen Hemminger <stephen@networkplumber.org>
    20     Akhil Goyal <gakhil@marvell.com>

A special thanks to Stephen Hemminger who started cleaning stale patches in
patchwork.
We still have many Bugzilla tickets and unattended patches, all help is
welcome.


The next version will be 24.03 in March.
The new features for 24.03 can be submitted during the next weeks:
    http://core.dpdk.org/roadmap#dates

Please share your roadmap.

Thanks everyone!


-- 
David Marchand


^ permalink raw reply	[relevance 4%]

* Re: [PATCH 2/2] devtools: remove ABI exception for crypto asym operations
  2023-11-23  8:58  9% ` [PATCH 2/2] devtools: remove ABI exception for crypto asym operations David Marchand
  2023-11-24 19:39  4%   ` [EXT] " Akhil Goyal
@ 2023-11-27  7:35  4%   ` David Marchand
  1 sibling, 0 replies; 200+ results
From: David Marchand @ 2023-11-27  7:35 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, thomas, Stephen Hemminger, Akhil Goyal, Maxime Coquelin

On Thu, Nov 23, 2023 at 9:58 AM David Marchand
<david.marchand@redhat.com> wrote:
>
> Those API are now stable.
>
> Fixes: 79a4c2cda131 ("cryptodev: promote some functions as stable")
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>

Series applied, thanks.


-- 
David Marchand


^ permalink raw reply	[relevance 4%]

* RE: [EXT] [PATCH 2/2] devtools: remove ABI exception for crypto asym operations
  2023-11-23  8:58  9% ` [PATCH 2/2] devtools: remove ABI exception for crypto asym operations David Marchand
@ 2023-11-24 19:39  4%   ` Akhil Goyal
  2023-11-27  7:35  4%   ` David Marchand
  1 sibling, 0 replies; 200+ results
From: Akhil Goyal @ 2023-11-24 19:39 UTC (permalink / raw)
  To: David Marchand, dev; +Cc: thomas, Stephen Hemminger

> Those API are now stable.
> 
> Fixes: 79a4c2cda131 ("cryptodev: promote some functions as stable")
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
Acked-by: Akhil Goyal <gakhil@marvell.com>

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 1/2] devtools: remove ABI exception for baseband FFT
  2023-11-23  8:58  9% [PATCH 1/2] devtools: remove ABI exception for baseband FFT David Marchand
  2023-11-23  8:58  9% ` [PATCH 2/2] devtools: remove ABI exception for crypto asym operations David Marchand
@ 2023-11-23  9:36  4% ` Maxime Coquelin
  1 sibling, 0 replies; 200+ results
From: Maxime Coquelin @ 2023-11-23  9:36 UTC (permalink / raw)
  To: David Marchand, dev; +Cc: thomas, Stephen Hemminger



On 11/23/23 09:58, David Marchand wrote:
> Those API are now stable.
> 
> Fixes: c96b519bd1c3 ("bbdev: promote some functions as stable")
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
>   devtools/libabigail.abignore | 4 ----
>   1 file changed, 4 deletions(-)
> 
> diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
> index 325f34e0b6..3ff51509de 100644
> --- a/devtools/libabigail.abignore
> +++ b/devtools/libabigail.abignore
> @@ -37,10 +37,6 @@
>           type_kind = enum
>           changed_enumerators = RTE_CRYPTO_ASYM_XFORM_ECPM, RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
>   
> -; Ignore changes to bbdev FFT API which is experimental
> -[suppress_type]
> -        name = rte_bbdev_fft_op
> -
>   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>   ; Temporary exceptions till next major ABI version ;
>   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime


^ permalink raw reply	[relevance 4%]

* [PATCH 2/2] devtools: remove ABI exception for crypto asym operations
  2023-11-23  8:58  9% [PATCH 1/2] devtools: remove ABI exception for baseband FFT David Marchand
@ 2023-11-23  8:58  9% ` David Marchand
  2023-11-24 19:39  4%   ` [EXT] " Akhil Goyal
  2023-11-27  7:35  4%   ` David Marchand
  2023-11-23  9:36  4% ` [PATCH 1/2] devtools: remove ABI exception for baseband FFT Maxime Coquelin
  1 sibling, 2 replies; 200+ results
From: David Marchand @ 2023-11-23  8:58 UTC (permalink / raw)
  To: dev; +Cc: thomas, Stephen Hemminger, Akhil Goyal

Those API are now stable.

Fixes: 79a4c2cda131 ("cryptodev: promote some functions as stable")

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 devtools/libabigail.abignore | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index 3ff51509de..21b8cd6113 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -30,13 +30,6 @@
 ; Experimental APIs exceptions ;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-; Ignore changes to asymmetric crypto API which is experimental
-[suppress_type]
-        name = rte_crypto_asym_op
-[suppress_type]
-        type_kind = enum
-        changed_enumerators = RTE_CRYPTO_ASYM_XFORM_ECPM, RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Temporary exceptions till next major ABI version ;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-- 
2.41.0


^ permalink raw reply	[relevance 9%]

* [PATCH 1/2] devtools: remove ABI exception for baseband FFT
@ 2023-11-23  8:58  9% David Marchand
  2023-11-23  8:58  9% ` [PATCH 2/2] devtools: remove ABI exception for crypto asym operations David Marchand
  2023-11-23  9:36  4% ` [PATCH 1/2] devtools: remove ABI exception for baseband FFT Maxime Coquelin
  0 siblings, 2 replies; 200+ results
From: David Marchand @ 2023-11-23  8:58 UTC (permalink / raw)
  To: dev; +Cc: thomas, Stephen Hemminger, Maxime Coquelin

Those API are now stable.

Fixes: c96b519bd1c3 ("bbdev: promote some functions as stable")

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 devtools/libabigail.abignore | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index 325f34e0b6..3ff51509de 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -37,10 +37,6 @@
         type_kind = enum
         changed_enumerators = RTE_CRYPTO_ASYM_XFORM_ECPM, RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
 
-; Ignore changes to bbdev FFT API which is experimental
-[suppress_type]
-        name = rte_bbdev_fft_op
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Temporary exceptions till next major ABI version ;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-- 
2.41.0


^ permalink raw reply	[relevance 9%]

* RE: [PATCH] app/test-pmd: fix L4 checksum with padding data
  2023-11-20 10:46  3%         ` Ferruh Yigit
@ 2023-11-22  3:04  0%           ` Deng, KaiwenX
  0 siblings, 0 replies; 200+ results
From: Deng, KaiwenX @ 2023-11-22  3:04 UTC (permalink / raw)
  To: Ferruh Yigit, Stephen Hemminger, Morten Brørup, Zhang, Qi Z
  Cc: dev, stable, Yang,  Qiming, Zhou, YidingX, Singh, Aman Deep,
	Zhang, Yuying, Matz, Olivier, De Lara Guarch, Pablo



> -----Original Message-----
> From: Ferruh Yigit <ferruh.yigit@amd.com>
> Sent: Monday, November 20, 2023 6:46 PM
> To: Deng, KaiwenX <kaiwenx.deng@intel.com>; Stephen Hemminger
> <stephen@networkplumber.org>; Morten Brørup
> <mb@smartsharesystems.com>
> Cc: dev@dpdk.org; stable@dpdk.org; Yang, Qiming <qiming.yang@intel.com>;
> Zhou, YidingX <yidingx.zhou@intel.com>; Singh, Aman Deep
> <aman.deep.singh@intel.com>; Zhang, Yuying <yuying.zhang@intel.com>;
> Matz, Olivier <olivier.matz@6wind.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>
> Subject: Re: [PATCH] app/test-pmd: fix L4 checksum with padding data
> 
> On 11/20/2023 9:21 AM, Deng, KaiwenX wrote:
> >
> >
> >> -----Original Message-----
> >> From: Ferruh Yigit <ferruh.yigit@amd.com>
> >> Sent: Friday, November 17, 2023 8:50 AM
> >> To: Stephen Hemminger <stephen@networkplumber.org>
> >> Cc: Deng, KaiwenX <kaiwenx.deng@intel.com>; dev@dpdk.org;
> >> stable@dpdk.org; Yang, Qiming <qiming.yang@intel.com>; Zhou, YidingX
> >> <yidingx.zhou@intel.com>; Singh, Aman Deep
> >> <aman.deep.singh@intel.com>; Zhang, Yuying <yuying.zhang@intel.com>;
> >> Matz, Olivier <olivier.matz@6wind.com>; De Lara Guarch, Pablo
> >> <pablo.de.lara.guarch@intel.com>
> >> Subject: Re: [PATCH] app/test-pmd: fix L4 checksum with padding data
> >>
> >> On 11/16/2023 10:58 PM, Stephen Hemminger wrote:
> >>> On Thu, 2 Nov 2023 19:20:07 +0000
> >>> Ferruh Yigit <ferruh.yigit@amd.com> wrote:
> >>>
> >>>> On 8/4/2023 9:28 AM, Kaiwen Deng wrote:
> >>>>> IEEE 802 packets may have a minimum size limit. The data fields
> >>>>> should be padded when necessary. In some cases, the padding data
> >>>>> is not zero. Testpmd does not trim these IP packets to the true
> >>>>> length of the frame, so errors will occur when calculating TCP or
> >>>>> UDP checksum.
> >>>>>
> >>>>
> >>>> Hi Kaiwen,
> >>>>
> >>>> I am trying to understand the problem, what is the testcase that
> >>>> has checksum error?
> >>>>
> >>>> Are the received mbuf data_len & pkt_len wrong? Instead of trying
> >>>> to fix the mbuf during forwarding, can we fix where packet generated?
> >>>
> >>> The root cause is that get_udptcp_cksum_mbuf is using m->pkt_len
> >>> which maybe larger than the actual data. The real issue is there and
> >>> in rte_ip.h checksum code. The correct fix would be to use l3_len instead.
> >>>
> >>
> >> I see, you are right.
> >>
> >> In 'rte_ipv4_udptcp_cksum_mbuf()',
> >> as payload length "mbuf->pkt_len - l4_off" is used, which includes
> >> padding and if padding is not zero it will end up producing wrong
> checksum.
> >>
> >>
> >> I agree using 'l3_len' instead is correct fix.
> >>
> >> But this requires ABI/API change,
> >> plus do we have any reason to keep the padding, discarding it as this
> >> patch does is also simpler alternative.
> >>
> >>
> >> Other alternative can be to zero the padding bytes. I guess standard
> >> doesn't enforce them to be zero, but we can do this to remove its
> >> impact on checksum calculation.
> > I'm not sure if this is ok, it feels like it would reduce performance.
> > I can try this alternative if needed.
> >
> 
> Yes impacts performance, so not a good alternative, please scratch it.
> 
> As discussion with Stephen and Morten, consensus is to fix SW functions that
> calculates checksum.
> 'rte_ipv4_udptcp_cksum_mbuf()' & 'rte_ipv6_udptcp_cksum_mbuf()'.
> 
> Instead of using packet_len, those functions can use packet length, which will
> make the checksum correct.
> 
> 
> Can you please send a patch to fix those functions? I think this can be done
> without changing function fingerprint, so without causing any ABI/API break.
> 
> 
> >>
> >>
> >> @Kaiwen, did you able to test this with HW offload, what is the
> >> behavior of the HW, does is remove padding bytes?
> >>
> > I tested the HW offload case and the same tcp/udp checksum error
> > occurs when padding is not 0, But if change pkt_len to the true length of the
> frame, the checksum is correct.
> >
> 
> I was expecting HW not impacted, since padding is part of the spec, my
> assumption would be HW only take the actual payload size into account,
> instead of buffer size.
> 
> Can you please double check? Which HW you are testing with, can you please
> add maintainer of that HW to this discussion?

I've tested hw offloads for udp and tcp with Intel E810. The hardware takes the size 

of the buffer into account when calculating the udp/tcp checksum, not the size of the 

actual payload.

Hi @Zhang, Qi Z,

Can you help confirm if this behavior is normal in hw?

Thanks!
> 
> If HW requires padding to be removed, we may go with your solution.
> 
> 
> >>
> >>> It also looks like test-pmd is not validating the IP header.
> >>> Both parse_ipv4() and parse_ipv6() should check if packet was truncated.
> >>> Same for both UDP and TCP lengths.
> >>>
> >>
> >


^ permalink raw reply	[relevance 0%]

* Re: [PATCH] app/test-pmd: fix L4 checksum with padding data
  @ 2023-11-20 10:47  0%             ` Ferruh Yigit
  0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2023-11-20 10:47 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Kaiwen Deng, dev, stable, qiming.yang, yidingx.zhou, Aman Singh,
	Yuying Zhang, Olivier Matz, Pablo de Lara

On 11/17/2023 4:22 PM, Stephen Hemminger wrote:
> On Fri, 17 Nov 2023 09:29:41 +0000
> Ferruh Yigit <ferruh.yigit@amd.com> wrote:
> 
>>>> I agree using 'l3_len' instead is correct fix.
>>>>
>>>> But this requires ABI/API change,
>>>> plus do we have any reason to keep the padding, discarding it as this
>>>> patch does is also simpler alternative.  
>>>
>>>
>>> Possibly an API version to change the args would work to fix.
>>>  
>>
>> rte_ipv4_udptcp_cksum_mbuf() and rte_ipv6_udptcp_cksum_mbuf() are inline
>> functions, unfortunately we can't version them.
>>
>> But those functions already gets IP header as parameter, can't we use IP
>> header to get the payload size? If so this can be fixed without updating
>> API.
> 
> Inlines are easier. Just make a fixed new function and make sure the old
> one is not used.  They shouldn't have been inline in the first place.
>

I guess inlines as because of performance concerns, since it is in datapath.

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] app/test-pmd: fix L4 checksum with padding data
  2023-11-20  9:21  0%       ` Deng, KaiwenX
@ 2023-11-20 10:46  3%         ` Ferruh Yigit
  2023-11-22  3:04  0%           ` Deng, KaiwenX
  0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2023-11-20 10:46 UTC (permalink / raw)
  To: Deng, KaiwenX, Stephen Hemminger, Morten Brørup
  Cc: dev, stable, Yang, Qiming, Zhou, YidingX, Singh, Aman Deep,
	Zhang, Yuying, Matz, Olivier, De Lara Guarch, Pablo

On 11/20/2023 9:21 AM, Deng, KaiwenX wrote:
> 
> 
>> -----Original Message-----
>> From: Ferruh Yigit <ferruh.yigit@amd.com>
>> Sent: Friday, November 17, 2023 8:50 AM
>> To: Stephen Hemminger <stephen@networkplumber.org>
>> Cc: Deng, KaiwenX <kaiwenx.deng@intel.com>; dev@dpdk.org;
>> stable@dpdk.org; Yang, Qiming <qiming.yang@intel.com>; Zhou, YidingX
>> <yidingx.zhou@intel.com>; Singh, Aman Deep <aman.deep.singh@intel.com>;
>> Zhang, Yuying <yuying.zhang@intel.com>; Matz, Olivier
>> <olivier.matz@6wind.com>; De Lara Guarch, Pablo
>> <pablo.de.lara.guarch@intel.com>
>> Subject: Re: [PATCH] app/test-pmd: fix L4 checksum with padding data
>>
>> On 11/16/2023 10:58 PM, Stephen Hemminger wrote:
>>> On Thu, 2 Nov 2023 19:20:07 +0000
>>> Ferruh Yigit <ferruh.yigit@amd.com> wrote:
>>>
>>>> On 8/4/2023 9:28 AM, Kaiwen Deng wrote:
>>>>> IEEE 802 packets may have a minimum size limit. The data fields
>>>>> should be padded when necessary. In some cases, the padding data is
>>>>> not zero. Testpmd does not trim these IP packets to the true length
>>>>> of the frame, so errors will occur when calculating TCP or UDP
>>>>> checksum.
>>>>>
>>>>
>>>> Hi Kaiwen,
>>>>
>>>> I am trying to understand the problem, what is the testcase that has
>>>> checksum error?
>>>>
>>>> Are the received mbuf data_len & pkt_len wrong? Instead of trying to
>>>> fix the mbuf during forwarding, can we fix where packet generated?
>>>
>>> The root cause is that get_udptcp_cksum_mbuf is using m->pkt_len which
>>> maybe larger than the actual data. The real issue is there and in
>>> rte_ip.h checksum code. The correct fix would be to use l3_len instead.
>>>
>>
>> I see, you are right.
>>
>> In 'rte_ipv4_udptcp_cksum_mbuf()',
>> as payload length "mbuf->pkt_len - l4_off" is used, which includes padding
>> and if padding is not zero it will end up producing wrong checksum.
>>
>>
>> I agree using 'l3_len' instead is correct fix.
>>
>> But this requires ABI/API change,
>> plus do we have any reason to keep the padding, discarding it as this patch
>> does is also simpler alternative.
>>
>>
>> Other alternative can be to zero the padding bytes. I guess standard doesn't
>> enforce them to be zero, but we can do this to remove its impact on checksum
>> calculation.
> I'm not sure if this is ok, it feels like it would reduce performance. 
> I can try this alternative if needed.
>

Yes impacts performance, so not a good alternative, please scratch it.

As discussion with Stephen and Morten, consensus is to fix SW functions
that calculates checksum.
'rte_ipv4_udptcp_cksum_mbuf()' & 'rte_ipv6_udptcp_cksum_mbuf()'.

Instead of using packet_len, those functions can use packet length,
which will make the checksum correct.


Can you please send a patch to fix those functions? I think this can be
done without changing function fingerprint, so without causing any
ABI/API break.


>>
>>
>> @Kaiwen, did you able to test this with HW offload, what is the behavior of
>> the HW, does is remove padding bytes?
>>
> I tested the HW offload case and the same tcp/udp checksum error occurs when padding is not 0, 
> But if change pkt_len to the true length of the frame, the checksum is correct.
>

I was expecting HW not impacted, since padding is part of the spec, my
assumption would be HW only take the actual payload size into account,
instead of buffer size.

Can you please double check? Which HW you are testing with, can you
please add maintainer of that HW to this discussion?

If HW requires padding to be removed, we may go with your solution.


>>
>>> It also looks like test-pmd is not validating the IP header.
>>> Both parse_ipv4() and parse_ipv6() should check if packet was truncated.
>>> Same for both UDP and TCP lengths.
>>>
>>
> 


^ permalink raw reply	[relevance 3%]

* RE: [PATCH] app/test-pmd: fix L4 checksum with padding data
    @ 2023-11-20  9:21  0%       ` Deng, KaiwenX
  2023-11-20 10:46  3%         ` Ferruh Yigit
  1 sibling, 1 reply; 200+ results
From: Deng, KaiwenX @ 2023-11-20  9:21 UTC (permalink / raw)
  To: Ferruh Yigit, Stephen Hemminger
  Cc: dev, stable, Yang,  Qiming, Zhou, YidingX, Singh, Aman Deep,
	Zhang, Yuying, Matz, Olivier, De Lara Guarch, Pablo



> -----Original Message-----
> From: Ferruh Yigit <ferruh.yigit@amd.com>
> Sent: Friday, November 17, 2023 8:50 AM
> To: Stephen Hemminger <stephen@networkplumber.org>
> Cc: Deng, KaiwenX <kaiwenx.deng@intel.com>; dev@dpdk.org;
> stable@dpdk.org; Yang, Qiming <qiming.yang@intel.com>; Zhou, YidingX
> <yidingx.zhou@intel.com>; Singh, Aman Deep <aman.deep.singh@intel.com>;
> Zhang, Yuying <yuying.zhang@intel.com>; Matz, Olivier
> <olivier.matz@6wind.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>
> Subject: Re: [PATCH] app/test-pmd: fix L4 checksum with padding data
> 
> On 11/16/2023 10:58 PM, Stephen Hemminger wrote:
> > On Thu, 2 Nov 2023 19:20:07 +0000
> > Ferruh Yigit <ferruh.yigit@amd.com> wrote:
> >
> >> On 8/4/2023 9:28 AM, Kaiwen Deng wrote:
> >>> IEEE 802 packets may have a minimum size limit. The data fields
> >>> should be padded when necessary. In some cases, the padding data is
> >>> not zero. Testpmd does not trim these IP packets to the true length
> >>> of the frame, so errors will occur when calculating TCP or UDP
> >>> checksum.
> >>>
> >>
> >> Hi Kaiwen,
> >>
> >> I am trying to understand the problem, what is the testcase that has
> >> checksum error?
> >>
> >> Are the received mbuf data_len & pkt_len wrong? Instead of trying to
> >> fix the mbuf during forwarding, can we fix where packet generated?
> >
> > The root cause is that get_udptcp_cksum_mbuf is using m->pkt_len which
> > maybe larger than the actual data. The real issue is there and in
> > rte_ip.h checksum code. The correct fix would be to use l3_len instead.
> >
> 
> I see, you are right.
> 
> In 'rte_ipv4_udptcp_cksum_mbuf()',
> as payload length "mbuf->pkt_len - l4_off" is used, which includes padding
> and if padding is not zero it will end up producing wrong checksum.
> 
> 
> I agree using 'l3_len' instead is correct fix.
> 
> But this requires ABI/API change,
> plus do we have any reason to keep the padding, discarding it as this patch
> does is also simpler alternative.
> 
> 
> Other alternative can be to zero the padding bytes. I guess standard doesn't
> enforce them to be zero, but we can do this to remove its impact on checksum
> calculation.
I'm not sure if this is ok, it feels like it would reduce performance. 
I can try this alternative if needed.
> 
> 
> @Kaiwen, did you able to test this with HW offload, what is the behavior of
> the HW, does is remove padding bytes?
> 
I tested the HW offload case and the same tcp/udp checksum error occurs when padding is not 0, 
But if change pkt_len to the true length of the frame, the checksum is correct.
> 
> > It also looks like test-pmd is not validating the IP header.
> > Both parse_ipv4() and parse_ipv6() should check if packet was truncated.
> > Same for both UDP and TCP lengths.
> >
> 


^ permalink raw reply	[relevance 0%]

Results 601-800 of ~18000   |  | reverse | sort options + mbox downloads above
-- links below jump to the message on this page --
2023-01-17  9:10     [PATCH 0/2] add ring telemetry cmds Jie Hai
2023-11-09 10:20     ` [RESEND v7 0/3] add telemetry cmds for ring Jie Hai
2023-11-09 10:20       ` [RESEND v7 1/3] ring: fix unmatched type definition and usage Jie Hai
2024-02-18 18:11  3%     ` Thomas Monjalon
2024-02-19  8:24  0%       ` Jie Hai
2024-01-27  8:33  0%   ` [RESEND v7 0/3] add telemetry cmds for ring Jie Hai
2024-02-19  8:32  3% ` [PATCH v8 0/2] " Jie Hai
2023-03-29 23:40     [PATCH v12 00/22] Covert static log types in libraries to dynamic Stephen Hemminger
2023-08-21 16:09     ` [PATCH v13 00/21] Convert static log types in libraries to dynamic types Stephen Hemminger
2023-12-04 12:32  0%   ` David Marchand
2023-12-05  2:09  3% ` [PATCH 00/18] Convert static log types in libraries to dynamic Stephen Hemminger
2023-12-05  2:09  2%   ` [PATCH 17/18] hash: move rte_hash_set_alg out of header file Stephen Hemminger
2023-12-06 10:08  3%   ` [PATCH 00/18] Convert static log types in libraries to dynamic David Marchand
2023-08-02 23:25     [PATCH v4 00/19] replace use of term "sanity check" Stephen Hemminger
2023-11-29 17:25     ` [PATCH v5 00/19] remove use of the " Stephen Hemminger
2023-11-29 17:25  2%   ` [PATCH v5 01/19] mbuf: replace term sanity check Stephen Hemminger
2023-08-04  8:28     [PATCH] app/test-pmd: fix L4 checksum with padding data Kaiwen Deng
2023-11-02 19:20     ` Ferruh Yigit
2023-11-16 22:58       ` Stephen Hemminger
2023-11-17  0:50         ` Ferruh Yigit
2023-11-17  3:28           ` Stephen Hemminger
2023-11-17  9:29             ` Ferruh Yigit
2023-11-17 16:22               ` Stephen Hemminger
2023-11-20 10:47  0%             ` Ferruh Yigit
2023-11-20  9:21  0%       ` Deng, KaiwenX
2023-11-20 10:46  3%         ` Ferruh Yigit
2023-11-22  3:04  0%           ` Deng, KaiwenX
2023-09-29 15:42     [PATCH] lib/hash: new feature adding existing key David Marchand
2023-10-23  8:29     ` [PATCH v2] " Abdullah Ömer Yamaç
2024-02-16 12:43  3%   ` Thomas Monjalon
2023-11-15 13:36     [PATCH v1 0/2] dts: api docs generation Juraj Linkeš
2024-01-22 12:00     ` [PATCH v2 0/3] dts: API " Juraj Linkeš
2024-01-22 12:00  2%   ` [PATCH v2 3/3] dts: add API doc generation Juraj Linkeš
2024-01-22 16:35     ` [PATCH v3 0/3] dts: API docs generation Juraj Linkeš
2024-01-22 16:35  2%   ` [PATCH v3 3/3] dts: add API doc generation Juraj Linkeš
2024-01-29 17:09  0%     ` Jeremy Spewock
     [not found]         ` <CAJvnSUCNjo0p-yhROF1MNLKhjiAw2QTyTHO2hpOaVVUn0xnJ0A@mail.gmail.com>
2024-02-29 18:12  2%       ` Nicholas Pratte
2023-11-23  8:58  9% [PATCH 1/2] devtools: remove ABI exception for baseband FFT David Marchand
2023-11-23  8:58  9% ` [PATCH 2/2] devtools: remove ABI exception for crypto asym operations David Marchand
2023-11-24 19:39  4%   ` [EXT] " Akhil Goyal
2023-11-27  7:35  4%   ` David Marchand
2023-11-23  9:36  4% ` [PATCH 1/2] devtools: remove ABI exception for baseband FFT Maxime Coquelin
2023-11-25 16:03     [PATCH v2 1/3] net/octeon_ep: optimize Rx and Tx routines pbhagavatula
2023-12-06 12:12  3% ` Jerin Jacob
2023-12-06 17:24  3% ` [PATCH v3 " pbhagavatula
2023-12-07  6:49  3%   ` [PATCH v4 " pbhagavatula
2023-12-11 13:43  3%     ` [PATCH v5 " pbhagavatula
2023-11-28 16:15  4% DPDK 23.11 released David Marchand
2023-11-29 15:27  4% [PATCH] doc: add sunset clause for experimental tag Stephen Hemminger
2023-11-29 15:46  0% ` Bruce Richardson
2023-11-29 16:18 11% [PATCH] version: 24.03-rc0 David Marchand
2023-11-30  9:23  3% ` David Marchand
2023-11-30  9:30  0%   ` Ferruh Yigit
2023-11-30  9:32  0%     ` David Marchand
2023-11-30 18:33  0%   ` Patrick Robb
2023-12-06 11:29     [PATCH] cfgfile: increase value length Vipin Varghese
2023-12-06 13:21     ` Bruce Richardson
2023-12-06 13:34       ` Dumitrescu, Cristian
2023-12-06 15:22  3%     ` Varghese, Vipin
2023-12-06 15:50  3%       ` Bruce Richardson
2023-12-06 16:46  3%         ` Varghese, Vipin
2024-02-01 10:32  3% ` David Marchand
2024-02-01 12:01  0%   ` Varghese, Vipin
2023-12-08  6:18  2% [PATCH] bus/uacce: introduce UACCE bus Chengwen Feng
2024-01-15  8:14  0% ` lihuisong (C)
2024-01-15 11:43  0%   ` fengchengwen
2024-01-16  3:35  2% ` [PATCH v2] " Chengwen Feng
2023-12-11  7:39     [PATCH 0/2] bugfix and replace on use of stdatomic API Jie Hai
2023-12-11  7:39     ` [PATCH 1/2] eal: fix constraints on " Jie Hai
2023-12-11 18:53       ` Tyler Retzlaff
2023-12-15  2:47         ` Jie Hai
2023-12-15  7:17  3%       ` Tyler Retzlaff
2023-12-12 15:36     [PATCH v1] crypto/ipsec_mb: unified IPsec MB interface Brian Dooley
2024-03-05 17:42     ` [PATCH v5 1/4] crypto/ipsec_mb: bump minimum IPsec Multi-buffer version Brian Dooley
2024-03-05 19:11       ` [EXTERNAL] " Akhil Goyal
2024-03-06 11:12  4%     ` Power, Ciara
2023-12-13  1:42     [PATCH 00/26] Replace uses of RTE_LOGTYPE_PMD Stephen Hemminger
2024-02-03  4:10  3% ` [PATCH v7 00/19] Replace use of PMD logtype Stephen Hemminger
2024-02-12 14:45  0%   ` David Marchand
2024-02-03  4:11  3% ` [PATCH v7 00/19] Replace uses of RTE_LOGTYPE_PMD Stephen Hemminger
2023-12-14  1:56     [PATCH] ethdev: add dump regs for telemetry Jie Hai
2024-02-05 10:51     ` [PATCH v2 0/7] support dump reigser names and filter them Jie Hai
2024-02-05 10:51  8%   ` [PATCH v2 1/7] ethdev: support report register names and filter Jie Hai
2024-02-07 17:00  3%     ` Ferruh Yigit
2024-02-20  8:43  3%       ` Jie Hai
2024-02-20 10:58     ` [PATCH v3 0/7] support dump reigser names and filter them Jie Hai
2024-02-20 10:58  8%   ` [PATCH v3 1/7] ethdev: support report register names and filter Jie Hai
2024-02-26  3:07     ` [PATCH v4 0/7] support dump reigser names and filter them Jie Hai
2024-02-26  3:07  8%   ` [PATCH v4 1/7] ethdev: support report register names and filter Jie Hai
2024-02-26  8:01  0%     ` fengchengwen
2024-03-06  7:22  0%       ` Jie Hai
2024-02-29  9:52  3%     ` Thomas Monjalon
2024-03-05  7:45  5%       ` Jie Hai
2023-12-14  3:12     [PATCH 0/2] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Suanming Mou
2024-02-01  2:30  3% ` [PATCH v4 0/3] " Suanming Mou
2024-02-01  2:30  7%   ` [PATCH v4 1/3] ethdev: rename action modify field data structure Suanming Mou
2024-02-01 12:29  3% ` [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Suanming Mou
2024-02-01 12:29  7%   ` [PATCH v5 1/3] ethdev: rename action modify field data structure Suanming Mou
2024-02-01 18:57  0%     ` Ferruh Yigit
2024-02-01 18:56  0%   ` [PATCH v5 0/3] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Ferruh Yigit
2024-02-02  0:32  0%     ` Suanming Mou
2024-02-02  0:42  3% ` [PATCH v6 " Suanming Mou
2024-02-02  0:42  7%   ` [PATCH v6 1/3] ethdev: rename action modify field data structure Suanming Mou
2024-02-05 11:23  0%     ` Thomas Monjalon
2024-02-05 11:49  0%       ` Suanming Mou
2024-02-06  2:06  3% ` [PATCH v7 0/4] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Suanming Mou
2024-02-06  2:06  3%   ` [PATCH v7 1/4] ethdev: rename action modify field data structure Suanming Mou
2024-02-06 21:24  0%   ` [PATCH v7 0/4] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Ferruh Yigit
2023-12-15 16:31  1% [RFC] net/tap: remove kernel side RSS via BPF Stephen Hemminger
2023-12-19  1:33     [PATCH v2 0/3] [PATCH 0/2] ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE Suanming Mou
2024-01-15  9:13  3% ` [PATCH v3 0/3] " Suanming Mou
2024-01-15  9:13  8%   ` [PATCH v3 1/3] ethdev: rename action modify field data structure Suanming Mou
2023-12-19 17:29     [dpdk-dev] [RFC] ethdev: support Tx queue free descriptor query jerinj
2024-01-11 15:17     ` [dpdk-dev] [v1] ethdev: support Tx queue used count jerinj
2024-01-12  8:02  4%   ` David Marchand
2024-01-12  9:29  0%     ` Jerin Jacob
2024-01-12 11:34       ` Ferruh Yigit
2024-01-12 12:11  3%     ` David Marchand
2024-01-12 14:25  3%       ` Ferruh Yigit
2024-01-12 16:52  3%   ` Stephen Hemminger
2024-01-18  9:47  3%   ` [dpdk-dev] [v2] " jerinj
2024-01-22 13:00  0%     ` Konstantin Ananyev
2023-12-22 11:04     [v7 1/1] net/af_xdp: fix multi interface support for K8s Maryam Tahhan
2024-01-10 14:58     ` Maryam Tahhan
2024-01-10 15:21       ` Ferruh Yigit
2024-01-11  9:01         ` Maryam Tahhan
2024-01-11 11:35  3%       ` Ferruh Yigit
2024-01-11 12:21  0%         ` Maryam Tahhan
2024-01-11 13:28  0%           ` Kevin Traynor
2024-01-11 14:21  0%           ` Ferruh Yigit
2024-02-07 23:24  0%             ` Ferruh Yigit
2024-02-09 12:40  0%               ` Loftus, Ciara
2023-12-27 10:57     [RFC] ethdev: fast path async flow API Dariusz Sosnowski
2023-12-27 17:39  3% ` Stephen Hemminger
2023-12-27 17:41     ` Stephen Hemminger
2023-12-28 13:53  3%   ` Dariusz Sosnowski
2023-12-28 14:10  0%     ` Ivan Malov
2023-12-28 17:16     ` Stephen Hemminger
2024-01-03 19:14       ` Dariusz Sosnowski
2024-01-04  1:07         ` Stephen Hemminger
2024-01-23 11:37  3%       ` Dariusz Sosnowski
2024-01-29 13:38  0%         ` Dariusz Sosnowski
2024-01-29 17:36  0%           ` Ferruh Yigit
2024-01-30 12:06  0%             ` Dariusz Sosnowski
2024-01-30 12:17  0%               ` Ferruh Yigit
2024-01-30 16:08  0%                 ` Dariusz Sosnowski
2024-01-08  1:59  3% Issues around packet capture when secondary process is doing rx/tx Stephen Hemminger
2024-01-08 10:41  0% ` Morten Brørup
2024-01-08 15:13  0% ` Konstantin Ananyev
2024-01-08 17:02  0%   ` Stephen Hemminger
2024-01-09  1:30  0% ` Honnappa Nagarahalli
2024-01-08  8:27     [PATCH] app/dma-perf: support bi-directional transfer Amit Prakash Shukla
2024-02-27 19:26     ` [PATCH v2] " Amit Prakash Shukla
2024-02-28  7:03       ` fengchengwen
2024-02-28  9:38         ` [EXT] " Amit Prakash Shukla
2024-02-29 14:03  3%       ` Amit Prakash Shukla
2024-03-01  1:46  0%         ` fengchengwen
2024-03-01  8:31  0%           ` [EXTERNAL] " Amit Prakash Shukla
2024-03-01  9:30  0%             ` fengchengwen
2024-03-01 10:59  0%               ` Amit Prakash Shukla
2024-01-08 17:14  3% rte_eth_dev_data reorganization needed Stephen Hemminger
2024-01-09 16:58  3% ` Ferruh Yigit
2024-01-10 15:01     [PATCH] build: fix linker warnings about undefined symbols Bruce Richardson
2024-01-10 16:58     ` Tyler Retzlaff
2024-01-11  9:38       ` Morten Brørup
2024-01-11  9:48  4%     ` Bruce Richardson
2024-01-12 20:11  0%       ` Tyler Retzlaff
2024-01-12 20:49  0%         ` Morten Brørup
2024-01-10 16:57     [PATCH] doc: update minimum Linux kernel version Stephen Hemminger
2024-01-11  9:18     ` Morten Brørup
2024-01-11 19:02       ` Patrick Robb
2024-01-11 19:26         ` Morten Brørup
2024-01-11 19:54  3%       ` Stephen Hemminger
2024-01-11 22:38  0%         ` Morten Brørup
2024-02-16  3:05  0%           ` Stephen Hemminger
2024-02-16  8:29  0%             ` Morten Brørup
2024-02-16 17:22  0%               ` Stephen Hemminger
2024-01-12 13:48  1% [PATCH] net/tap: Modified TAP BPF program as per the Kernel-version upgrade requirements madhuker.mythri
2024-01-12 17:53  1% ` [RFC v3] tap: rework the BPF header parsing Stephen Hemminger
2024-01-18 11:18     [Bug 1368] inconsistency in eventdev dev_info and config structs makes some valid configs impossible bugzilla
2024-01-18 11:26  3% ` Bruce Richardson
2024-01-18 13:21  0%   ` Bruce Richardson
2024-01-18 13:45     [PATCH v1 0/7] improve eventdev API specification/documentation Bruce Richardson
2024-01-19 17:43     ` [PATCH v2 00/11] " Bruce Richardson
2024-01-19 17:43       ` [PATCH v2 11/11] eventdev: RFC clarify docs on event object fields Bruce Richardson
2024-01-24 11:34  3%     ` Mattias Rönnblom
2024-02-01 16:59  0%       ` Bruce Richardson
2024-02-02  9:38  0%         ` Mattias Rönnblom
2024-02-02 12:39       ` [PATCH v3 00/11] improve eventdev API specification/documentation Bruce Richardson
2024-02-02 12:39         ` [PATCH v3 10/11] eventdev: clarify docs on event object fields and op types Bruce Richardson
2024-02-09  9:14           ` Jerin Jacob
2024-02-20 17:39  3%         ` Bruce Richardson
2024-02-21  9:31  0%           ` Jerin Jacob
2024-01-24 22:17     [PATCH 0/2] more replacement of zero length array Tyler Retzlaff
2024-02-12 22:36     ` [PATCH v2 0/4] " Tyler Retzlaff
2024-02-13 13:14  3%   ` David Marchand
2024-02-13 19:20  3%     ` Tyler Retzlaff
2024-02-14  7:36  4%       ` David Marchand
2024-02-16 10:14  0%         ` David Marchand
2024-02-16 20:46  0%           ` Tyler Retzlaff
2024-02-27 23:56     ` [PATCH v3 0/6] " Tyler Retzlaff
2024-02-27 23:56  4%   ` [PATCH v3 4/6] pipeline: replace zero length array with flex array Tyler Retzlaff
2024-02-29 22:58     ` [PATCH v4 0/6] more replacement of zero length array Tyler Retzlaff
2024-02-29 22:58  4%   ` [PATCH v4 4/6] pipeline: replace zero length array with flex array Tyler Retzlaff
2024-01-28  9:39     [PATCH 0/4] introduce encap hash calculation Ori Kam
2024-02-08  9:09     ` [PATCH v2 1/4] ethdev: " Ori Kam
2024-02-08 17:13       ` Ferruh Yigit
2024-02-11  7:29         ` Ori Kam
2024-02-12 17:05           ` Ferruh Yigit
2024-02-12 18:44             ` Ori Kam
2024-02-12 20:09  3%           ` Ferruh Yigit
2024-02-13  7:05  0%             ` Ori Kam
2024-01-29 18:59     [PATCH 1/3] cryptodev: add ec points to sm2 op Arkadiusz Kusztal
2024-02-01  8:07  3% ` [EXT] " Akhil Goyal
2024-02-01 13:25  0%   ` Kusztal, ArkadiuszX
2024-01-30  3:46     [RFC 0/2] net/tap RSS BPF rewrite Stephen Hemminger
2024-01-30  3:46  1% ` [RFC 2/2] tap: rework BPF handling Stephen Hemminger
2024-02-07 22:11     ` [PATCH v2 0/7] net/tap: RSS using BPF overhaul Stephen Hemminger
2024-02-07 22:11  2%   ` [PATCH v2 4/7] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-02-08 17:41     ` [PATCH v3 0/7] net/tap: RSS using BPF overhaul Stephen Hemminger
2024-02-08 17:41  2%   ` [PATCH v3 4/7] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-02-08 19:05     ` [PATCH v4 0/7] net/tap: queue flow action RSS using BPF redo Stephen Hemminger
2024-02-08 19:05  2%   ` [PATCH v4 4/7] net/tap: rewrite the RSS BPF program Stephen Hemminger
     [not found]     <20220825024425.10534-1-lihuisong@huawei.com>
2023-08-02  3:15     ` [PATCH RESEND v6 0/5] app/testpmd: support multiple process attach and detach port Huisong Li
2023-10-09 10:34       ` lihuisong (C)
2023-10-30 12:17         ` lihuisong (C)
2023-12-08  2:25  0%       ` lihuisong (C)
2024-01-30  6:36  3% ` [PATCH v7 " Huisong Li
2024-01-30  6:36  2%   ` [PATCH v7 2/5] ethdev: fix skip valid port in probing callback Huisong Li
2024-01-30 18:17  1% [PATCH] ethdev: fast path async flow API Dariusz Sosnowski
2024-01-31  9:35  1% ` [PATCH v2] " Dariusz Sosnowski
2024-02-06 17:36  1%   ` [PATCH v3] " Dariusz Sosnowski
2024-01-30 23:26  3% [PATCH] replace GCC marker extension with C11 anonymous unions Tyler Retzlaff
2024-01-30 23:26     ` [PATCH] mbuf: " Tyler Retzlaff
2024-01-31  9:18       ` Morten Brørup
2024-01-31 21:09  3%     ` Tyler Retzlaff
2024-01-31 22:39  3%       ` Morten Brørup
2024-01-31 13:49  3%   ` Bruce Richardson
2024-01-31 20:45  0%     ` Tyler Retzlaff
2024-01-31 22:55  4%       ` Morten Brørup
2024-02-13  6:45  3%   ` [PATCH v2] RFC: " Tyler Retzlaff
2024-02-13  8:57  0%     ` Bruce Richardson
2024-02-13 17:09  0%     ` Morten Brørup
2024-02-15  6:21     ` [PATCH v4 00/18] stop using zero sized marker fields Tyler Retzlaff
2024-02-15  6:21  3%   ` [PATCH v4 01/18] mbuf: deprecate GCC marker in rte mbuf struct Tyler Retzlaff
2024-02-18 12:39  0%     ` Thomas Monjalon
2024-02-18 13:07  0%       ` Morten Brørup
2024-02-20 17:20  0%       ` Tyler Retzlaff
2024-02-27  5:41     ` [PATCH v6 00/23] stop and remove RTE_MARKER typedefs Tyler Retzlaff
2024-02-27  5:41       ` [PATCH v6 20/23] mbuf: remove and stop using rte marker fields Tyler Retzlaff
2024-02-27 15:18  4%     ` David Marchand
2024-02-27 16:04  3%       ` Morten Brørup
2024-02-27 17:23  4%       ` Tyler Retzlaff
2024-02-28 10:42  3%         ` David Marchand
2024-02-28 14:03  3%       ` Dodji Seketeli
2024-02-28 14:18         ` David Marchand
2024-02-28 15:01  4%       ` Morten Brørup
2024-02-28 15:33  3%         ` David Marchand
2024-01-31 17:44  4% [PATCH 1/2] ci: bump tested distributions in GHA David Marchand
2024-01-31 17:44  6% ` [PATCH 2/2] ci: update versions of actions " David Marchand
     [not found]     <0230331200824.195294-1-stephen@networkplumber.org>
2024-02-05 17:43     ` [PATCH v9 00/23] Use inclusive naming in DPDK Stephen Hemminger
2024-02-05 17:43  2%   ` [PATCH v9 05/23] mbuf: replace term sanity check Stephen Hemminger
2024-02-10 10:42     [PATCH 0/4] add support of partial offload Chaoyong He
2024-02-23  2:42     ` [PATCH v2 0/4] add support of MARK and RSS flow action Chaoyong He
2024-02-23  2:42  2%   ` [PATCH v2 1/4] ethdev: add function to check representor port Chaoyong He
2024-02-14  1:26     [PATCH 00/14] use C11 alignas and normalize type alignment Tyler Retzlaff
2024-02-14  7:05     ` [PATCH v3 00/39] " Tyler Retzlaff
2024-02-14  7:06  4%   ` [PATCH v3 27/39] mempool: use C11 alignas Tyler Retzlaff
2024-02-14 16:35     ` [PATCH v4 00/39] use C11 alignas and normalize type alignment Tyler Retzlaff
2024-02-14 16:35  4%   ` [PATCH v4 27/39] mempool: use C11 alignas Tyler Retzlaff
2024-02-23 19:03     ` [PATCH v5 00/39] " Tyler Retzlaff
2024-02-23 19:04  3%   ` [PATCH v5 27/39] mempool: " Tyler Retzlaff
2024-02-26 18:25     ` [PATCH v6 00/39] " Tyler Retzlaff
2024-02-26 18:25  3%   ` [PATCH v6 27/39] mempool: " Tyler Retzlaff
2024-02-27  9:42  0%     ` Konstantin Ananyev
2024-03-04 17:52     ` [PATCH v7 00/39] " Tyler Retzlaff
2024-03-04 17:52  3%   ` [PATCH v7 27/39] mempool: " Tyler Retzlaff
2024-02-15 12:48  3% [PATCH 0/7] add Nitrox compress device support Nagadheeraj Rottela
2024-02-29 17:22  0% ` Akhil Goyal
2024-02-19  9:40     [RFC v2 1/5] eal: add static per-lcore memory allocation facility Mattias Rönnblom
2024-02-20  8:49     ` [RFC v3 0/6] Lcore variables Mattias Rönnblom
2024-02-20  8:49       ` [RFC v3 1/6] eal: add static per-lcore memory allocation facility Mattias Rönnblom
2024-02-20  9:11         ` Bruce Richardson
2024-02-20 10:47  3%       ` Mattias Rönnblom
2024-02-20 11:39  0%         ` Bruce Richardson
2024-02-20 13:37  0%           ` Morten Brørup
2024-02-20 16:26  0%           ` Mattias Rönnblom
2024-02-20  3:29     [DPDK/ethdev Bug 1381] TAP device can not support 17 queues bugzilla
2024-02-20 19:23  3% ` Stephen Hemminger
2024-02-20 15:33     [RFC PATCH 0/2] power: refactor power management library Sivaprasad Tummala
2024-02-20 15:33     ` [RFC PATCH 1/2] power: refactor core " Sivaprasad Tummala
2024-03-01  2:56  3%   ` lihuisong (C)
2024-03-01 10:39  0%     ` Hunt, David
2024-03-05  4:35  3%     ` Tummala, Sivaprasad
2024-02-22  7:35     release candidate 24.03-rc1 Thomas Monjalon
2024-02-29  9:18  4% ` Xu, HailinX
2024-02-28  3:18  9% [DPDK/ethdev Bug 1386] [dpdk-24.03] [ABI][meson test] driver-tests/link_bonding_autotest test failed: Segmentation fault when do ABI testing bugzilla
2024-02-29 17:56  3% [PATCH] net/tap: allow more that 4 queues Stephen Hemminger
2024-03-06 16:14  0% ` Ferruh Yigit
2024-03-01 16:25  3% [PATCH 0/7] add Nitrox compress device support Nagadheeraj Rottela
2024-03-02  9:38  3% Nagadheeraj Rottela
2024-03-04  7:14  0% ` Akhil Goyal
2024-03-02 13:53  2% [RFC 0/7] Improve EAL bit operations API Mattias Rönnblom
2024-03-04 18:45     [PATCH] hash: make gfni stubs inline Stephen Hemminger
2024-03-05 10:14     ` David Marchand
2024-03-05 17:53  3%   ` Tyler Retzlaff
2024-03-05 18:44  0%     ` Stephen Hemminger
2024-03-05  2:29     [PATCH 0/5] add new meta data module Chaoyong He
2024-03-05  2:29  4% ` [PATCH 1/5] net/nfp: create " Chaoyong He
2024-03-05  2:29  3% ` [PATCH 3/5] net/nfp: uniform function name format Chaoyong He
2024-03-05 13:49  4% [PATCH] devtools: require version for experimental symbols David Marchand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).